|
|
|
|
@ -52,7 +52,7 @@ class _SearchDoctorByNameState extends State<SearchDoctorByName> {
|
|
|
|
|
children: [
|
|
|
|
|
Expanded(
|
|
|
|
|
child: CollapsingListView(
|
|
|
|
|
title: LocaleKeys.chooseDoctor.tr(),
|
|
|
|
|
title: LocaleKeys.chooseDoctor.tr(context: context),
|
|
|
|
|
child: SingleChildScrollView(
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: EdgeInsets.symmetric(horizontal: 24.h),
|
|
|
|
|
@ -142,49 +142,49 @@ class _SearchDoctorByNameState extends State<SearchDoctorByName> {
|
|
|
|
|
return Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
if (bookAppointmentsVM.isDoctorSearchByNameStarted)
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
CustomButton(
|
|
|
|
|
text: LocaleKeys.byClinic.tr(context: context),
|
|
|
|
|
onPressed: () {
|
|
|
|
|
bookAppointmentsVM.sortFilteredDoctorList(true);
|
|
|
|
|
},
|
|
|
|
|
backgroundColor: bookAppointmentsVM.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor,
|
|
|
|
|
borderColor: bookAppointmentsVM.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
|
|
|
|
|
textColor: bookAppointmentsVM.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor,
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
fontWeight: FontWeight.w500,
|
|
|
|
|
borderRadius: 10,
|
|
|
|
|
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
|
|
|
|
|
height: 40.h,
|
|
|
|
|
),
|
|
|
|
|
SizedBox(width: 8.h),
|
|
|
|
|
CustomButton(
|
|
|
|
|
text: LocaleKeys.byHospital.tr(context: context),
|
|
|
|
|
onPressed: () {
|
|
|
|
|
bookAppointmentsVM.sortFilteredDoctorList(false);
|
|
|
|
|
},
|
|
|
|
|
backgroundColor: bookAppointmentsVM.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor,
|
|
|
|
|
borderColor: bookAppointmentsVM.isSortByClinic ? AppColors.textColor.withOpacity(0.2) : AppColors.primaryRedColor,
|
|
|
|
|
textColor: bookAppointmentsVM.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor,
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
fontWeight: FontWeight.w500,
|
|
|
|
|
borderRadius: 10,
|
|
|
|
|
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
|
|
|
|
|
height: 40.h,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
).paddingSymmetrical(0.h, 0.h),
|
|
|
|
|
// if (bookAppointmentsVM.isDoctorSearchByNameStarted)
|
|
|
|
|
// Row(
|
|
|
|
|
// children: [
|
|
|
|
|
// CustomButton(
|
|
|
|
|
// text: LocaleKeys.byClinic.tr(context: context),
|
|
|
|
|
// onPressed: () {
|
|
|
|
|
// bookAppointmentsVM.sortFilteredDoctorList(true);
|
|
|
|
|
// },
|
|
|
|
|
// backgroundColor: bookAppointmentsVM.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor,
|
|
|
|
|
// borderColor: bookAppointmentsVM.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
|
|
|
|
|
// textColor: bookAppointmentsVM.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor,
|
|
|
|
|
// fontSize: 12,
|
|
|
|
|
// fontWeight: FontWeight.w500,
|
|
|
|
|
// borderRadius: 10,
|
|
|
|
|
// padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
|
|
|
|
|
// height: 40.h,
|
|
|
|
|
// ),
|
|
|
|
|
// SizedBox(width: 8.h),
|
|
|
|
|
// CustomButton(
|
|
|
|
|
// text: LocaleKeys.byHospital.tr(context: context),
|
|
|
|
|
// onPressed: () {
|
|
|
|
|
// bookAppointmentsVM.sortFilteredDoctorList(false);
|
|
|
|
|
// },
|
|
|
|
|
// backgroundColor: bookAppointmentsVM.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor,
|
|
|
|
|
// borderColor: bookAppointmentsVM.isSortByClinic ? AppColors.textColor.withOpacity(0.2) : AppColors.primaryRedColor,
|
|
|
|
|
// textColor: bookAppointmentsVM.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor,
|
|
|
|
|
// fontSize: 12,
|
|
|
|
|
// fontWeight: FontWeight.w500,
|
|
|
|
|
// borderRadius: 10,
|
|
|
|
|
// padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
|
|
|
|
|
// height: 40.h,
|
|
|
|
|
// ),
|
|
|
|
|
// ],
|
|
|
|
|
// ).paddingSymmetrical(0.h, 0.h),
|
|
|
|
|
bookAppointmentsVM.isDoctorSearchByNameStarted
|
|
|
|
|
? ListView.separated(
|
|
|
|
|
padding: EdgeInsets.only(top: 20.h),
|
|
|
|
|
shrinkWrap: true,
|
|
|
|
|
physics: NeverScrollableScrollPhysics(),
|
|
|
|
|
itemCount: bookAppointmentsVM.isDoctorsListLoading ? 5 : bookAppointmentsVM.getGroupedFilteredDoctorsList().length,
|
|
|
|
|
itemCount: bookAppointmentsVM.isDoctorsListLoading ? 5 : bookAppointmentsVM.filteredDoctorList.length,
|
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
|
final isExpanded = bookAppointmentsVM.expandedGroupIndex == index;
|
|
|
|
|
final groupedDoctors = bookAppointmentsVM.getGroupedFilteredDoctorsList();
|
|
|
|
|
// final isExpanded = bookAppointmentsVM.expandedGroupIndex == index;
|
|
|
|
|
// final groupedDoctors = bookAppointmentsVM.getGroupedFilteredDoctorsList();
|
|
|
|
|
|
|
|
|
|
return bookAppointmentsVM.isDoctorsListLoading
|
|
|
|
|
? DoctorCard(
|
|
|
|
|
@ -203,112 +203,184 @@ class _SearchDoctorByNameState extends State<SearchDoctorByName> {
|
|
|
|
|
duration: Duration(milliseconds: 300),
|
|
|
|
|
curve: Curves.easeInOut,
|
|
|
|
|
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
|
|
|
|
|
child: InkWell(
|
|
|
|
|
onTap: () {
|
|
|
|
|
bookAppointmentsVM.toggleGroupExpansion(index);
|
|
|
|
|
// After rebuild, ensure the expanded item is visible
|
|
|
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
|
|
|
final key = _itemKeys[index];
|
|
|
|
|
if (key != null && key.currentContext != null && bookAppointmentsVM.expandedGroupIndex == index) {
|
|
|
|
|
Scrollable.ensureVisible(
|
|
|
|
|
key.currentContext!,
|
|
|
|
|
duration: Duration(milliseconds: 350),
|
|
|
|
|
curve: Curves.easeInOut,
|
|
|
|
|
alignment: 0.1,
|
|
|
|
|
child: Container(
|
|
|
|
|
key: ValueKey<int>(index),
|
|
|
|
|
padding: EdgeInsets.only(top: 12.h),
|
|
|
|
|
child: DoctorCard(
|
|
|
|
|
doctorsListResponseModel: bookAppointmentsVM.filteredDoctorList[index],
|
|
|
|
|
isLoading: false,
|
|
|
|
|
bookAppointmentsViewModel: bookAppointmentsViewModel,
|
|
|
|
|
).paddingSymmetrical(16.h, 0.h).onPress(() async {
|
|
|
|
|
bookAppointmentsVM.setSelectedDoctor(bookAppointmentsVM.filteredDoctorList[index]);
|
|
|
|
|
LoaderBottomSheet.showLoader();
|
|
|
|
|
await bookAppointmentsVM.getDoctorProfile(
|
|
|
|
|
onSuccess: (dynamic respData) {
|
|
|
|
|
LoaderBottomSheet.hideLoader();
|
|
|
|
|
Navigator.of(context).push(
|
|
|
|
|
CustomPageRoute(
|
|
|
|
|
page: DoctorProfilePage(),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
onError: (err) {
|
|
|
|
|
LoaderBottomSheet.hideLoader();
|
|
|
|
|
showCommonBottomSheetWithoutHeight(
|
|
|
|
|
context,
|
|
|
|
|
child: Utils.getErrorWidget(loadingText: err),
|
|
|
|
|
callBackFunc: () {},
|
|
|
|
|
isFullScreen: false,
|
|
|
|
|
isCloseButtonVisible: true,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: EdgeInsets.all(16.h),
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
children: [
|
|
|
|
|
CustomButton(
|
|
|
|
|
text: "${groupedDoctors[index].length} ${'doctors'}",
|
|
|
|
|
onPressed: () {},
|
|
|
|
|
backgroundColor: AppColors.greyColor,
|
|
|
|
|
borderColor: AppColors.greyColor,
|
|
|
|
|
textColor: AppColors.blackColor,
|
|
|
|
|
fontSize: 10,
|
|
|
|
|
fontWeight: FontWeight.w500,
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
|
|
|
|
|
height: 30.h),
|
|
|
|
|
Icon(isExpanded ? Icons.expand_less : Icons.expand_more),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
SizedBox(height: 8.h),
|
|
|
|
|
// Clinic/Hospital name as group title
|
|
|
|
|
Text(
|
|
|
|
|
bookAppointmentsVM.isSortByClinic
|
|
|
|
|
? (groupedDoctors[index].first.clinicName ?? 'Unknown')
|
|
|
|
|
: (groupedDoctors[index].first.projectName ?? 'Unknown'),
|
|
|
|
|
style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600),
|
|
|
|
|
overflow: TextOverflow.ellipsis,
|
|
|
|
|
),
|
|
|
|
|
// Expanded content - list of doctors in this group
|
|
|
|
|
AnimatedSwitcher(
|
|
|
|
|
duration: Duration(milliseconds: 400),
|
|
|
|
|
child: isExpanded
|
|
|
|
|
? Container(
|
|
|
|
|
key: ValueKey<int>(index),
|
|
|
|
|
padding: EdgeInsets.only(top: 12.h),
|
|
|
|
|
child: Column(
|
|
|
|
|
children: groupedDoctors[index].asMap().entries.map<Widget>((entry) {
|
|
|
|
|
final doctorIndex = entry.key;
|
|
|
|
|
final doctor = entry.value;
|
|
|
|
|
final isLastDoctor = doctorIndex == groupedDoctors[index].length - 1;
|
|
|
|
|
return Column(
|
|
|
|
|
children: [
|
|
|
|
|
DoctorCard(
|
|
|
|
|
doctorsListResponseModel: doctor,
|
|
|
|
|
isLoading: false,
|
|
|
|
|
bookAppointmentsViewModel: bookAppointmentsViewModel,
|
|
|
|
|
).onPress(() async {
|
|
|
|
|
bookAppointmentsVM.setSelectedDoctor(doctor);
|
|
|
|
|
LoaderBottomSheet.showLoader();
|
|
|
|
|
await bookAppointmentsVM.getDoctorProfile(
|
|
|
|
|
onSuccess: (dynamic respData) {
|
|
|
|
|
LoaderBottomSheet.hideLoader();
|
|
|
|
|
Navigator.of(context).push(
|
|
|
|
|
CustomPageRoute(
|
|
|
|
|
page: DoctorProfilePage(),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
onError: (err) {
|
|
|
|
|
LoaderBottomSheet.hideLoader();
|
|
|
|
|
showCommonBottomSheetWithoutHeight(
|
|
|
|
|
context,
|
|
|
|
|
child: Utils.getErrorWidget(loadingText: err),
|
|
|
|
|
callBackFunc: () {},
|
|
|
|
|
isFullScreen: false,
|
|
|
|
|
isCloseButtonVisible: true,
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}),
|
|
|
|
|
if (!isLastDoctor)
|
|
|
|
|
Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}).toList(),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
: SizedBox.shrink(),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
// Column(
|
|
|
|
|
// children: bookAppointmentsVM.doctorsList[index].map<Widget>((entry) {
|
|
|
|
|
// final doctorIndex = entry.key;
|
|
|
|
|
// final doctor = entry.value;
|
|
|
|
|
// final isLastDoctor = doctorIndex == groupedDoctors[index].length - 1;
|
|
|
|
|
// return Column(
|
|
|
|
|
// children: [
|
|
|
|
|
// DoctorCard(
|
|
|
|
|
// doctorsListResponseModel: doctor,
|
|
|
|
|
// isLoading: false,
|
|
|
|
|
// bookAppointmentsViewModel: bookAppointmentsViewModel,
|
|
|
|
|
// ).onPress(() async {
|
|
|
|
|
// bookAppointmentsVM.setSelectedDoctor(doctor);
|
|
|
|
|
// LoaderBottomSheet.showLoader();
|
|
|
|
|
// await bookAppointmentsVM.getDoctorProfile(
|
|
|
|
|
// onSuccess: (dynamic respData) {
|
|
|
|
|
// LoaderBottomSheet.hideLoader();
|
|
|
|
|
// Navigator.of(context).push(
|
|
|
|
|
// CustomPageRoute(
|
|
|
|
|
// page: DoctorProfilePage(),
|
|
|
|
|
// ),
|
|
|
|
|
// );
|
|
|
|
|
// },
|
|
|
|
|
// onError: (err) {
|
|
|
|
|
// LoaderBottomSheet.hideLoader();
|
|
|
|
|
// showCommonBottomSheetWithoutHeight(
|
|
|
|
|
// context,
|
|
|
|
|
// child: Utils.getErrorWidget(loadingText: err),
|
|
|
|
|
// callBackFunc: () {},
|
|
|
|
|
// isFullScreen: false,
|
|
|
|
|
// isCloseButtonVisible: true,
|
|
|
|
|
// );
|
|
|
|
|
// },
|
|
|
|
|
// );
|
|
|
|
|
// }),
|
|
|
|
|
// if (!isLastDoctor)
|
|
|
|
|
// Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h),
|
|
|
|
|
// ],
|
|
|
|
|
// );
|
|
|
|
|
// }).toList(),
|
|
|
|
|
// ),
|
|
|
|
|
}),
|
|
|
|
|
// InkWell(
|
|
|
|
|
// onTap: () {
|
|
|
|
|
// bookAppointmentsVM.toggleGroupExpansion(index);
|
|
|
|
|
// // After rebuild, ensure the expanded item is visible
|
|
|
|
|
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
|
|
|
// final key = _itemKeys[index];
|
|
|
|
|
// if (key != null && key.currentContext != null && bookAppointmentsVM.expandedGroupIndex == index) {
|
|
|
|
|
// Scrollable.ensureVisible(
|
|
|
|
|
// key.currentContext!,
|
|
|
|
|
// duration: Duration(milliseconds: 350),
|
|
|
|
|
// curve: Curves.easeInOut,
|
|
|
|
|
// alignment: 0.1,
|
|
|
|
|
// );
|
|
|
|
|
// }
|
|
|
|
|
// });
|
|
|
|
|
// },
|
|
|
|
|
// child: Padding(
|
|
|
|
|
// padding: EdgeInsets.all(16.h),
|
|
|
|
|
// child: Column(
|
|
|
|
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
// children: [
|
|
|
|
|
// Row(
|
|
|
|
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
// children: [
|
|
|
|
|
// CustomButton(
|
|
|
|
|
// text: "${groupedDoctors[index].length} ${'doctors'}",
|
|
|
|
|
// onPressed: () {},
|
|
|
|
|
// backgroundColor: AppColors.greyColor,
|
|
|
|
|
// borderColor: AppColors.greyColor,
|
|
|
|
|
// textColor: AppColors.blackColor,
|
|
|
|
|
// fontSize: 10,
|
|
|
|
|
// fontWeight: FontWeight.w500,
|
|
|
|
|
// borderRadius: 8,
|
|
|
|
|
// padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
|
|
|
|
|
// height: 30.h),
|
|
|
|
|
// Icon(isExpanded ? Icons.expand_less : Icons.expand_more),
|
|
|
|
|
// ],
|
|
|
|
|
// ),
|
|
|
|
|
// SizedBox(height: 8.h),
|
|
|
|
|
// // Clinic/Hospital name as group title
|
|
|
|
|
// Text(
|
|
|
|
|
// bookAppointmentsVM.isSortByClinic
|
|
|
|
|
// ? (groupedDoctors[index].first.clinicName ?? 'Unknown')
|
|
|
|
|
// : (groupedDoctors[index].first.projectName ?? 'Unknown'),
|
|
|
|
|
// style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600),
|
|
|
|
|
// overflow: TextOverflow.ellipsis,
|
|
|
|
|
// ),
|
|
|
|
|
// // Expanded content - list of doctors in this group
|
|
|
|
|
// // AnimatedSwitcher(
|
|
|
|
|
// // duration: Duration(milliseconds: 400),
|
|
|
|
|
// // child: isExpanded
|
|
|
|
|
// // ? Container(
|
|
|
|
|
// // key: ValueKey<int>(index),
|
|
|
|
|
// // padding: EdgeInsets.only(top: 12.h),
|
|
|
|
|
// // child: Column(
|
|
|
|
|
// // children: groupedDoctors[index].asMap().entries.map<Widget>((entry) {
|
|
|
|
|
// // final doctorIndex = entry.key;
|
|
|
|
|
// // final doctor = entry.value;
|
|
|
|
|
// // final isLastDoctor = doctorIndex == groupedDoctors[index].length - 1;
|
|
|
|
|
// // return Column(
|
|
|
|
|
// // children: [
|
|
|
|
|
// // DoctorCard(
|
|
|
|
|
// // doctorsListResponseModel: doctor,
|
|
|
|
|
// // isLoading: false,
|
|
|
|
|
// // bookAppointmentsViewModel: bookAppointmentsViewModel,
|
|
|
|
|
// // ).onPress(() async {
|
|
|
|
|
// // bookAppointmentsVM.setSelectedDoctor(doctor);
|
|
|
|
|
// // LoaderBottomSheet.showLoader();
|
|
|
|
|
// // await bookAppointmentsVM.getDoctorProfile(
|
|
|
|
|
// // onSuccess: (dynamic respData) {
|
|
|
|
|
// // LoaderBottomSheet.hideLoader();
|
|
|
|
|
// // Navigator.of(context).push(
|
|
|
|
|
// // CustomPageRoute(
|
|
|
|
|
// // page: DoctorProfilePage(),
|
|
|
|
|
// // ),
|
|
|
|
|
// // );
|
|
|
|
|
// // },
|
|
|
|
|
// // onError: (err) {
|
|
|
|
|
// // LoaderBottomSheet.hideLoader();
|
|
|
|
|
// // showCommonBottomSheetWithoutHeight(
|
|
|
|
|
// // context,
|
|
|
|
|
// // child: Utils.getErrorWidget(loadingText: err),
|
|
|
|
|
// // callBackFunc: () {},
|
|
|
|
|
// // isFullScreen: false,
|
|
|
|
|
// // isCloseButtonVisible: true,
|
|
|
|
|
// // );
|
|
|
|
|
// // },
|
|
|
|
|
// // );
|
|
|
|
|
// // }),
|
|
|
|
|
// // if (!isLastDoctor)
|
|
|
|
|
// // Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h),
|
|
|
|
|
// // ],
|
|
|
|
|
// // );
|
|
|
|
|
// // }).toList(),
|
|
|
|
|
// // ),
|
|
|
|
|
// // )
|
|
|
|
|
// // : SizedBox.shrink(),
|
|
|
|
|
// // ),
|
|
|
|
|
// ],
|
|
|
|
|
// ),
|
|
|
|
|
// ),
|
|
|
|
|
// ),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
));
|
|
|
|
|
},
|
|
|
|
|
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
|
|
|
|
|
)
|
|
|
|
|
|