257 lines
9.2 KiB
Dart
257 lines
9.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
import '../../models/pet_model.dart';
|
|
import '../../theme/app_colors.dart';
|
|
|
|
class PetSelectionHeader extends StatelessWidget {
|
|
final List<Pet> pets;
|
|
final Pet? selectedPet;
|
|
final ValueChanged<Pet> onPetSelected;
|
|
final VoidCallback onAddPetPressed;
|
|
|
|
const PetSelectionHeader({
|
|
super.key,
|
|
required this.pets,
|
|
required this.selectedPet,
|
|
required this.onPetSelected,
|
|
required this.onAddPetPressed,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
// If no pet selected (and list is empty), show Add Pet UI or minimal hint
|
|
if (pets.isEmpty) {
|
|
// Returning null or minimal UI might be better, but user asked for "Consistent Header"
|
|
// The HomeScreen shows a "Register Pet + " button if empty.
|
|
// Let's implement that logic here for consistency if pets are empty.
|
|
return Material(
|
|
color: Colors.transparent,
|
|
child: InkWell(
|
|
borderRadius: BorderRadius.circular(8.r),
|
|
onTap: onAddPetPressed,
|
|
child: Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 4.h, horizontal: 12.w),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Image.asset(
|
|
'assets/img/profile.png',
|
|
width: 40.w,
|
|
height: 40.h,
|
|
),
|
|
SizedBox(width: 6.w),
|
|
Text(
|
|
'반려동물 등록 +',
|
|
style: TextStyle(
|
|
fontFamily: 'SCDream',
|
|
fontWeight: FontWeight.w500,
|
|
fontSize: 15.sp,
|
|
letterSpacing: 0.45.sp,
|
|
color: const Color(0xFF1f1f1f),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
// Default display pet
|
|
final displayPet = selectedPet ?? pets.first;
|
|
|
|
return Material(
|
|
color: Colors.transparent,
|
|
child: InkWell(
|
|
borderRadius: BorderRadius.circular(8.r),
|
|
onTap: () {
|
|
final RenderBox button = context.findRenderObject() as RenderBox;
|
|
final RenderBox overlay =
|
|
Navigator.of(context).overlay!.context.findRenderObject()
|
|
as RenderBox;
|
|
final RelativeRect position = RelativeRect.fromRect(
|
|
Rect.fromPoints(
|
|
button.localToGlobal(Offset(0, 50.h), ancestor: overlay),
|
|
button.localToGlobal(
|
|
button.size.bottomRight(Offset.zero),
|
|
ancestor: overlay,
|
|
),
|
|
),
|
|
Offset.zero & overlay.size,
|
|
);
|
|
|
|
showMenu<dynamic>(
|
|
context: context,
|
|
position: position,
|
|
elevation: 3,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(12.r),
|
|
),
|
|
color: Colors.white,
|
|
surfaceTintColor: Colors.white,
|
|
items: [
|
|
...pets.map(
|
|
(pet) => PopupMenuItem<Pet>(
|
|
value: pet,
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
width: 32.w,
|
|
height: 32.w,
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
color: Colors.grey[200],
|
|
),
|
|
clipBehavior: Clip.hardEdge,
|
|
child: pet.profileImageUrl != null
|
|
? Image.network(
|
|
pet.profileImageUrl!,
|
|
fit: BoxFit.cover,
|
|
errorBuilder: (context, error, stackTrace) {
|
|
return Center(
|
|
child: SvgPicture.asset(
|
|
'assets/icons/profile_icon.svg',
|
|
width: 16.w,
|
|
colorFilter: ColorFilter.mode(
|
|
Colors.grey[400]!,
|
|
BlendMode.srcIn,
|
|
),
|
|
),
|
|
);
|
|
},
|
|
)
|
|
: Center(
|
|
child: SvgPicture.asset(
|
|
'assets/icons/profile_icon.svg',
|
|
width: 16.w,
|
|
colorFilter: ColorFilter.mode(
|
|
Colors.grey[400]!,
|
|
BlendMode.srcIn,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(width: 10.w),
|
|
Text(
|
|
pet.name,
|
|
style: TextStyle(
|
|
fontFamily: 'SCDream',
|
|
fontSize: 14.sp,
|
|
fontWeight: pet.id == displayPet.id
|
|
? FontWeight.bold
|
|
: FontWeight.normal,
|
|
color: pet.id == displayPet.id
|
|
? AppColors.highlight
|
|
: Colors.black,
|
|
),
|
|
),
|
|
if (pet.id == displayPet.id) ...[
|
|
const Spacer(),
|
|
const Icon(
|
|
Icons.check,
|
|
color: AppColors.highlight,
|
|
size: 16,
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
),
|
|
const PopupMenuDivider(),
|
|
PopupMenuItem<String>(
|
|
value: 'add_pet',
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: EdgeInsets.all(4.w),
|
|
decoration: BoxDecoration(
|
|
color: Colors.grey[100],
|
|
shape: BoxShape.circle,
|
|
),
|
|
child: Icon(Icons.add, size: 16.w, color: Colors.black54),
|
|
),
|
|
SizedBox(width: 10.w),
|
|
Text(
|
|
'반려동물 추가하기',
|
|
style: TextStyle(
|
|
fontFamily: 'SCDream',
|
|
fontSize: 14.sp,
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
).then((value) {
|
|
if (value != null) {
|
|
if (value is Pet) {
|
|
onPetSelected(value);
|
|
} else if (value == 'add_pet') {
|
|
onAddPetPressed();
|
|
}
|
|
}
|
|
});
|
|
},
|
|
child: Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 4.h, horizontal: 12.w),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Container(
|
|
width: 40.w,
|
|
height: 40.w,
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
color: Colors.grey[200],
|
|
),
|
|
clipBehavior: Clip.hardEdge,
|
|
child: displayPet.profileImageUrl != null
|
|
? Image.network(
|
|
displayPet.profileImageUrl!,
|
|
fit: BoxFit.cover,
|
|
errorBuilder: (context, error, stackTrace) {
|
|
return Center(
|
|
child: SvgPicture.asset(
|
|
'assets/icons/profile_icon.svg',
|
|
width: 20.w,
|
|
colorFilter: ColorFilter.mode(
|
|
Colors.grey[400]!,
|
|
BlendMode.srcIn,
|
|
),
|
|
),
|
|
);
|
|
},
|
|
)
|
|
: Center(
|
|
child: SvgPicture.asset(
|
|
'assets/icons/profile_icon.svg',
|
|
width: 20.w,
|
|
colorFilter: ColorFilter.mode(
|
|
Colors.grey[400]!,
|
|
BlendMode.srcIn,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(width: 10.w),
|
|
Text(
|
|
displayPet.name,
|
|
style: TextStyle(
|
|
fontFamily: 'SCDream',
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 18.sp,
|
|
color: Colors.black,
|
|
),
|
|
),
|
|
SizedBox(width: 4.w),
|
|
Icon(Icons.keyboard_arrow_down, size: 24.w, color: Colors.black),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|