diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index e0ccd055..bdf7e045 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1597,5 +1597,6 @@ "tests": "تحليل", "calendarPermissionAlert": "يرجى منح إذن الوصول إلى التقويم من إعدادات التطبيق لضبط تذكير تناول الدواء.", "sortByLocation": "الترتيب حسب الموقع", - "sortByNearestLocation": "فرز حسب الأقرب إلى موقعك" + "sortByNearestLocation": "فرز حسب الأقرب إلى موقعك", + "giveLocationPermissionForNearestList": "يرجى منح إذن الوصول إلى الموقع من إعدادات التطبيق لعرض أقرب المواقع." } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 661434c4..5e051cc8 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1591,5 +1591,6 @@ "tests": "tests", "calendarPermissionAlert": "Please grant calendar access permission from app settings to set medication reminder.", "sortByLocation": "Sort by location", - "sortByNearestLocation": "Sort by nearest to your location" + "sortByNearestLocation": "Sort by nearest to your location", + "giveLocationPermissionForNearestList": "Please grant location permission from app settings to see the nearest locations." } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 886e910b..e1a6e379 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1592,5 +1592,6 @@ abstract class LocaleKeys { static const calendarPermissionAlert = 'calendarPermissionAlert'; static const sortByLocation = 'sortByLocation'; static const sortByNearestLocation = 'sortByNearestLocation'; + static const giveLocationPermissionForNearestList = 'giveLocationPermissionForNearestList'; } diff --git a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart index f3301f0c..56a04636 100644 --- a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart +++ b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart @@ -1,20 +1,19 @@ import 'package:easy_localization/easy_localization.dart' show StringTranslateExtension; import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/debouncer.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; -import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart' show Utils; import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart'; import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; -import 'package:provider/provider.dart'; -import '../../../../features/my_appointments/models/resp_models/hospital_model.dart' show HospitalsModel; import '../../../emergency_services/call_ambulance/widgets/type_selection_widget.dart' show TypeSelectionWidget; // class HospitalBottomSheetBody extends StatelessWidget { @@ -125,8 +124,10 @@ class HospitalBottomSheetBody extends StatelessWidget { final Function(FacilitySelection) onFacilityClicked; final Function(PatientDoctorAppointmentList) onHospitalClicked; final Function(String) onHospitalSearch; + final bool sortByLocation; + final Function(bool)? onSortByLocationToggle; - HospitalBottomSheetBody({super.key, required this.hmcCount, required this.hmgCount, this.displayList, required this.selectedFacility, required this.onFacilityClicked, required this.onHospitalClicked, required this.onHospitalSearch, required this.searchText}); + HospitalBottomSheetBody({super.key, required this.hmcCount, required this.hmgCount, this.displayList, required this.selectedFacility, required this.onFacilityClicked, required this.onHospitalClicked, required this.onHospitalSearch, required this.searchText, this.sortByLocation = false, this.onSortByLocationToggle}); @override Widget build(BuildContext context) { @@ -156,7 +157,37 @@ class HospitalBottomSheetBody extends StatelessWidget { horizontal: ResponsiveExtension(15).h, ), ), - SizedBox(height: 24.h), + SizedBox(height: 16.h), + if (onSortByLocationToggle != null) + Padding( + padding: EdgeInsets.symmetric(horizontal: 4.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.location, iconColor: AppColors.greyTextColor, width: 18.h, height: 18.h), + SizedBox(width: 8.w), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.sortByLocation.tr(context: context).toText14(isBold: true), + // SizedBox(height: 4.h), + LocaleKeys.sortByNearestLocation.tr(context: context).toText11(color: AppColors.textColorLight, weight: FontWeight.w500), + ], + ), + ], + ), + Switch( + value: sortByLocation, + onChanged: onSortByLocationToggle, + activeThumbColor: AppColors.successColor, + activeTrackColor: AppColors.successColor.withValues(alpha: 0.15), + ), + ], + ), + ), + if (onSortByLocationToggle != null) SizedBox(height: 8.h), TypeSelectionWidget( selectedFacility:selectedFacility , hmcCount: hmcCount.toString(), @@ -174,7 +205,7 @@ class HospitalBottomSheetBody extends StatelessWidget { var hospital = displayList?[index]; return HospitalListItem( hospitalData: hospital, - isLocationEnabled: true, + isLocationEnabled: sortByLocation, ).onPress(() { onHospitalClicked(hospital!); });}, diff --git a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart index b0a717b7..abe1641a 100644 --- a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart +++ b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart @@ -97,14 +97,14 @@ class HospitalListItem extends StatelessWidget { // ) ], )), - Visibility( - visible: !isLocationEnabled, - child: AppCustomChipWidget( - labelText: "Location turned off", - deleteIcon: AppAssets.location_unavailable, - deleteIconSize: Size(9.w, 12.h), - textColor: AppColors.blackColor, - )), + // Visibility( + // visible: !isLocationEnabled, + // child: AppCustomChipWidget( + // labelText: "Location turned off", + // deleteIcon: AppAssets.location_unavailable, + // deleteIconSize: Size(9.w, 12.h), + // textColor: AppColors.blackColor, + // )), ], ); } diff --git a/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart b/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart index 76089b74..5676806e 100644 --- a/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart +++ b/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart @@ -195,7 +195,7 @@ class _RegionBottomSheetBodyState extends State { title: LocaleKeys.notice.tr(context: context), context, child: Utils.getWarningWidget( - loadingText: "Please grant location permission from app settings to see better results", + loadingText: LocaleKeys.giveLocationPermissionForNearestList.tr(context: context), isShowActionButtons: true, onCancelTap: () { Navigator.of(context).pop(); @@ -215,7 +215,7 @@ class _RegionBottomSheetBodyState extends State { title: LocaleKeys.notice.tr(context: context), context, child: Utils.getWarningWidget( - loadingText: "Please grant location permission from app settings to see better results", + loadingText: LocaleKeys.giveLocationPermissionForNearestList.tr(context: context), isShowActionButtons: true, onCancelTap: () { Navigator.of(context).pop(); diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart index 382516d7..c6859736 100644 --- a/lib/presentation/book_appointment/book_appointment_page.dart +++ b/lib/presentation/book_appointment/book_appointment_page.dart @@ -7,6 +7,7 @@ import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/location_util.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/route_extensions.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -32,6 +33,7 @@ import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart' show showC import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import '../appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart'; @@ -510,6 +512,8 @@ class _BookAppointmentPageState extends State { selectedFacility: data.selectedFacility, hmcCount: data.hmcCount, hmgCount: data.hmgCount, + sortByLocation: data.sortByLocation, + onSortByLocationToggle: (value) => _handleSortByLocationToggle(value, data), ); } if (data.bottomSheetState == AppointmentViaRegionState.CLINIC_SELECTION) { @@ -523,6 +527,78 @@ class _BookAppointmentPageState extends State { return SizedBox.shrink(); } + void _handleSortByLocationToggle(bool value, AppointmentViaRegionViewmodel regionVM) { + if (value) { + final locationUtils = getIt.get(); + locationUtils.getLocation( + isShowConfirmDialog: true, + onSuccess: (latLng) { + regionVM.setSortByLocation(true); + _refreshHospitalListAfterApi(regionVM); + }, + onFailure: () { + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.notice.tr(context: context), + context, + child: Utils.getWarningWidget( + loadingText: LocaleKeys.giveLocationPermissionForNearestList.tr(context: context), + isShowActionButtons: true, + onCancelTap: () { + Navigator.of(context).pop(); + }, + onConfirmTap: () async { + Navigator.of(context).pop(); + openAppSettings(); + }), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + regionVM.setSortByLocation(false); + }, + onLocationDeniedForever: () { + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.notice.tr(context: context), + context, + child: Utils.getWarningWidget( + loadingText: LocaleKeys.giveLocationPermissionForNearestList.tr(context: context), + isShowActionButtons: true, + onCancelTap: () { + Navigator.of(context).pop(); + }, + onConfirmTap: () async { + Navigator.of(context).pop(); + openAppSettings(); + }), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + regionVM.setSortByLocation(false); + }, + ); + } else { + final appState = getIt.get(); + appState.resetLocation(); + regionVM.setSortByLocation(false); + _refreshHospitalListAfterApi(regionVM); + } + } + + void _refreshHospitalListAfterApi(AppointmentViaRegionViewmodel regionVM) { + void listener() { + if (!bookAppointmentsViewModel.isRegionListLoading) { + bookAppointmentsViewModel.removeListener(listener); + final selectedRegion = regionVM.selectedRegionId; + if (selectedRegion != null && bookAppointmentsViewModel.hospitalList?.registeredDoctorMap?[selectedRegion] != null) { + regionVM.setDisplayListAndRegionHospitalList(bookAppointmentsViewModel.hospitalList!.registeredDoctorMap![selectedRegion]); + } + } + } + bookAppointmentsViewModel.addListener(listener); + bookAppointmentsViewModel.getRegionMappedProjectList(); + } + getTitle(AppointmentViaRegionViewmodel data) { if (data.selectedRegionId == null) { return LocaleKeys.selectRegion.tr(context: context).toText20(weight: FontWeight.w600); diff --git a/lib/presentation/book_appointment/doctor_profile_page.dart b/lib/presentation/book_appointment/doctor_profile_page.dart index fdd1af0f..fd43048d 100644 --- a/lib/presentation/book_appointment/doctor_profile_page.dart +++ b/lib/presentation/book_appointment/doctor_profile_page.dart @@ -85,10 +85,12 @@ class DoctorProfilePage extends StatelessWidget { runSpacing: 4.h, children: [ AppCustomChipWidget( + backgroundColor: AppColors.whiteColor, iconColor: AppColors.ratingColorYellow, labelText: "${bookAppointmentsViewModel.doctorsProfileResponseModel.projectName}", ), AppCustomChipWidget( + backgroundColor: AppColors.whiteColor, iconColor: AppColors.ratingColorYellow, labelText: "${bookAppointmentsViewModel.doctorsProfileResponseModel.clinicDescription}", ), diff --git a/lib/presentation/book_appointment/search_doctor_by_name.dart b/lib/presentation/book_appointment/search_doctor_by_name.dart index fa871f50..533229a0 100644 --- a/lib/presentation/book_appointment/search_doctor_by_name.dart +++ b/lib/presentation/book_appointment/search_doctor_by_name.dart @@ -52,7 +52,7 @@ class _SearchDoctorByNameState extends State { 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 { 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 { 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(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(index), - padding: EdgeInsets.only(top: 12.h), - child: Column( - children: groupedDoctors[index].asMap().entries.map((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((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(index), + // // padding: EdgeInsets.only(top: 12.h), + // // child: Column( + // // children: groupedDoctors[index].asMap().entries.map((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), ) diff --git a/lib/presentation/book_appointment/select_clinic_page.dart b/lib/presentation/book_appointment/select_clinic_page.dart index aebb90fd..ca3381b5 100644 --- a/lib/presentation/book_appointment/select_clinic_page.dart +++ b/lib/presentation/book_appointment/select_clinic_page.dart @@ -7,6 +7,7 @@ import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; +import 'package:hmg_patient_app_new/core/location_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -1118,6 +1119,8 @@ class _SelectClinicPageState extends State { selectedFacility: data.selectedFacility, hmcCount: data.hmcCount, hmgCount: data.hmgCount, + sortByLocation: data.sortByLocation, + onSortByLocationToggle: (value) => _handleSortByLocationToggle(value, data), ); } if (data.bottomSheetState == AppointmentViaRegionState.DOCTOR_SELECTION) { @@ -1301,4 +1304,42 @@ class _SelectClinicPageState extends State { initDentalAppointmentBookingFlow(int.parse(bookAppointmentsViewModel.currentlySelectedHospitalFromRegionFlow ?? "0")); return; } + + void _handleSortByLocationToggle(bool value, AppointmentViaRegionViewmodel regionVM) { + if (value) { + final locationUtils = getIt.get(); + locationUtils.getLocation( + isShowConfirmDialog: true, + onSuccess: (latLng) { + regionVM.setSortByLocation(true); + _refreshHospitalListAfterApi(regionVM); + }, + onFailure: () { + regionVM.setSortByLocation(false); + }, + onLocationDeniedForever: () { + regionVM.setSortByLocation(false); + }, + ); + } else { + final appState = getIt.get(); + appState.resetLocation(); + regionVM.setSortByLocation(false); + _refreshHospitalListAfterApi(regionVM); + } + } + + void _refreshHospitalListAfterApi(AppointmentViaRegionViewmodel regionVM) { + void listener() { + if (!bookAppointmentsViewModel.isRegionListLoading) { + bookAppointmentsViewModel.removeListener(listener); + final selectedRegion = regionVM.selectedRegionId; + if (selectedRegion != null && bookAppointmentsViewModel.hospitalList?.registeredDoctorMap?[selectedRegion] != null) { + regionVM.setDisplayListAndRegionHospitalList(bookAppointmentsViewModel.hospitalList!.registeredDoctorMap![selectedRegion]); + } + } + } + bookAppointmentsViewModel.addListener(listener); + bookAppointmentsViewModel.getRegionMappedProjectList(); + } } diff --git a/lib/presentation/symptoms_checker/possible_conditions_screen.dart b/lib/presentation/symptoms_checker/possible_conditions_screen.dart index 323a13c2..81980c66 100644 --- a/lib/presentation/symptoms_checker/possible_conditions_screen.dart +++ b/lib/presentation/symptoms_checker/possible_conditions_screen.dart @@ -2,8 +2,10 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; +import 'package:hmg_patient_app_new/core/location_util.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/route_extensions.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -337,6 +339,8 @@ class PossibleConditionsPage extends StatelessWidget { selectedFacility: data.selectedFacility, hmcCount: data.hmcCount, hmgCount: data.hmgCount, + sortByLocation: data.sortByLocation, + onSortByLocationToggle: (value) => _handleSortByLocationToggle(value, data), ); } if (data.bottomSheetState == AppointmentViaRegionState.DOCTOR_SELECTION) { @@ -354,4 +358,42 @@ class PossibleConditionsPage extends StatelessWidget { } return SizedBox.shrink(); } + + void _handleSortByLocationToggle(bool value, AppointmentViaRegionViewmodel regionVM) { + if (value) { + final locationUtils = getIt.get(); + locationUtils.getLocation( + isShowConfirmDialog: true, + onSuccess: (latLng) { + regionVM.setSortByLocation(true); + _refreshHospitalListAfterApi(regionVM); + }, + onFailure: () { + regionVM.setSortByLocation(false); + }, + onLocationDeniedForever: () { + regionVM.setSortByLocation(false); + }, + ); + } else { + final appState = getIt.get(); + appState.resetLocation(); + regionVM.setSortByLocation(false); + _refreshHospitalListAfterApi(regionVM); + } + } + + void _refreshHospitalListAfterApi(AppointmentViaRegionViewmodel regionVM) { + void listener() { + if (!bookAppointmentsViewModel.isRegionListLoading) { + bookAppointmentsViewModel.removeListener(listener); + final selectedRegion = regionVM.selectedRegionId; + if (selectedRegion != null && bookAppointmentsViewModel.hospitalList?.registeredDoctorMap?[selectedRegion] != null) { + regionVM.setDisplayListAndRegionHospitalList(bookAppointmentsViewModel.hospitalList!.registeredDoctorMap![selectedRegion]); + } + } + } + bookAppointmentsViewModel.addListener(listener); + bookAppointmentsViewModel.getRegionMappedProjectList(); + } }