From 87fd9a42b7c2c48f0046398dbb173a2a3b8db7bb Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 17 Dec 2025 11:09:35 +0300 Subject: [PATCH 1/6] Nearest Appointment selected --- lib/core/api_consts.dart | 2 +- .../book_appointments_view_model.dart | 15 ++++++++++ .../location/location_view_model.dart | 4 ++- .../book_appointment/select_doctor_page.dart | 28 ++++++++++++++++++- .../book_appointment/widgets/doctor_card.dart | 4 ++- 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index 9bab873..1f92ad5 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -700,7 +700,7 @@ var GET_PRESCRIPTION_INSTRUCTIONS_PDF = 'Services/ChatBot_Service.svc/REST/Chatb class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart index d96cb4f..fd3f8c7 100644 --- a/lib/features/book_appointments/book_appointments_view_model.dart +++ b/lib/features/book_appointments/book_appointments_view_model.dart @@ -49,6 +49,8 @@ class BookAppointmentsViewModel extends ChangeNotifier { int initialSlotDuration = 0; + bool isNearestAppointmentSelected = false; + LocationUtils locationUtils; List clinicsList = []; @@ -187,6 +189,18 @@ class BookAppointmentsViewModel extends ChangeNotifier { notifyListeners(); } + setIsNearestAppointmentSelected(bool isNearestAppointmentSelected) { + this.isNearestAppointmentSelected = isNearestAppointmentSelected; + + if (isNearestAppointmentSelected) { + doctorsList.sort((a, b) => DateUtil.convertStringToDate(a.nearestFreeSlot!).compareTo(DateUtil.convertStringToDate(b.nearestFreeSlot!))); + } else { + doctorsList.sort((a, b) => b.decimalDoctorRate!.compareTo(a.decimalDoctorRate!)); + } + + notifyListeners(); + } + setIsWaitingAppointmentSelected(bool isWaitingAppointmentSelected) { this.isWaitingAppointmentSelected = isWaitingAppointmentSelected; notifyListeners(); @@ -391,6 +405,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { doctorsList = apiResponse.data!; filteredDoctorList = doctorsList; isDoctorsListLoading = false; + doctorsList.sort((a, b) => b.decimalDoctorRate!.compareTo(a.decimalDoctorRate!)); initializeFilteredList(); clearSearchFilters(); getFiltersFromDoctorList(); diff --git a/lib/features/location/location_view_model.dart b/lib/features/location/location_view_model.dart index 76d7c2c..5b0eef6 100644 --- a/lib/features/location/location_view_model.dart +++ b/lib/features/location/location_view_model.dart @@ -37,7 +37,9 @@ class LocationViewModel extends ChangeNotifier { } GMSMapServices.CameraPosition getGMSLocation() { - return GMSMapServices.CameraPosition(target: GMSMapServices.LatLng(getIt().userLat, getIt().userLong), zoom: 18); + return GMSMapServices.CameraPosition( + target: GMSMapServices.LatLng(getIt().userLat != 0.0 ? getIt().userLat : 24.7248316, getIt().userLong != 0.0 ? getIt().userLong : 46.4928828), + zoom: 18); } void placeValueInController() async { diff --git a/lib/presentation/book_appointment/select_doctor_page.dart b/lib/presentation/book_appointment/select_doctor_page.dart index 46c3774..e450746 100644 --- a/lib/presentation/book_appointment/select_doctor_page.dart +++ b/lib/presentation/book_appointment/select_doctor_page.dart @@ -41,6 +41,7 @@ class _SelectDoctorPageState extends State { @override void initState() { scheduleMicrotask(() { + bookAppointmentsViewModel.setIsNearestAppointmentSelected(false); if (bookAppointmentsViewModel.isLiveCareSchedule) { bookAppointmentsViewModel.getLiveCareDoctorsList(); } else { @@ -105,8 +106,33 @@ class _SelectDoctorPageState extends State { ), ], ), + SizedBox(height: 16.h), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + // Utils.buildSvgWithAssets(icon: AppAssets.prescription_reminder_icon, width: 35.h, height: 35.h), + // SizedBox(width: 8.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.nearestAppo.tr(context: context).toText13(isBold: true), + "View nearest available appointments".needTranslation.toText11(color: AppColors.textColorLight, weight: FontWeight.w500), + ], + ), + const Spacer(), + Switch( + activeThumbColor: AppColors.successColor, + activeTrackColor: AppColors.successColor.withValues(alpha: .15), + value: bookAppointmentsVM.isNearestAppointmentSelected, + onChanged: (newValue) async { + bookAppointmentsVM.setIsNearestAppointmentSelected(newValue); + + }, + ), + ], + ), ListView.separated( - padding: EdgeInsets.only(top: 24.h), + padding: EdgeInsets.only(top: 16.h), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: bookAppointmentsVM.isDoctorsListLoading diff --git a/lib/presentation/book_appointment/widgets/doctor_card.dart b/lib/presentation/book_appointment/widgets/doctor_card.dart index 7257dbf..63450b3 100644 --- a/lib/presentation/book_appointment/widgets/doctor_card.dart +++ b/lib/presentation/book_appointment/widgets/doctor_card.dart @@ -115,12 +115,14 @@ class DoctorCard extends StatelessWidget { iconColor: AppColors.ratingColorYellow, labelText: "Rating: ${isLoading ? 4.78 : doctorsListResponseModel.decimalDoctorRate}".needTranslation, ).toShimmer2(isShow: isLoading), - doctorsListResponseModel.nearestFreeSlot != null + bookAppointmentsViewModel.isNearestAppointmentSelected + ? doctorsListResponseModel.nearestFreeSlot != null ? AppCustomChipWidget( labelText: (isLoading ? "Cardiologist" : DateUtil.getDateStringForNearestSlot(doctorsListResponseModel.nearestFreeSlot)).needTranslation, backgroundColor: AppColors.successColor, textColor: AppColors.whiteColor, ).toShimmer2(isShow: isLoading) + : SizedBox.shrink() : SizedBox.shrink(), ], ), From 15f5eaf8e55de7d48572b95162ba29bb067f92e6 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 17 Dec 2025 11:13:50 +0300 Subject: [PATCH 2/6] updates --- lib/presentation/book_appointment/select_doctor_page.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/presentation/book_appointment/select_doctor_page.dart b/lib/presentation/book_appointment/select_doctor_page.dart index e450746..72786f3 100644 --- a/lib/presentation/book_appointment/select_doctor_page.dart +++ b/lib/presentation/book_appointment/select_doctor_page.dart @@ -110,12 +110,11 @@ class _SelectDoctorPageState extends State { Row( mainAxisSize: MainAxisSize.max, children: [ - // Utils.buildSvgWithAssets(icon: AppAssets.prescription_reminder_icon, width: 35.h, height: 35.h), - // SizedBox(width: 8.h), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.nearestAppo.tr(context: context).toText13(isBold: true), + SizedBox(height: 4.h), "View nearest available appointments".needTranslation.toText11(color: AppColors.textColorLight, weight: FontWeight.w500), ], ), From 5581346a2d4d7532fc46e98de190dc638a720b82 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 17 Dec 2025 16:30:06 +0300 Subject: [PATCH 3/6] updates --- lib/widgets/appbar/collapsing_list_view.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index ca40c32..68dbb32 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -209,8 +209,8 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget } class _ScrollAnimatedTitleState extends State { - static const double _maxFont = 24; - static const double _minFont = 14; + static const double _maxFont = 26; + static const double _minFont = 18; static const double _maxHeight = 80; static const double _minHeight = 56; From f886357bcdafce17d95ea0b6aab7aa995171608d Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 24 Dec 2025 11:30:34 +0300 Subject: [PATCH 4/6] updates --- lib/core/api_consts.dart | 2 +- lib/features/payfort/payfort_view_model.dart | 4 ++-- .../appointment_checkin_bottom_sheet.dart | 10 ++++---- .../immediate_livecare_payment_details.dart | 24 +++++++++++++++---- lib/presentation/home/landing_page.dart | 19 +++++++-------- 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index 1f92ad5..9bab873 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -700,7 +700,7 @@ var GET_PRESCRIPTION_INSTRUCTIONS_PDF = 'Services/ChatBot_Service.svc/REST/Chatb class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT diff --git a/lib/features/payfort/payfort_view_model.dart b/lib/features/payfort/payfort_view_model.dart index db8209a..dda8f51 100644 --- a/lib/features/payfort/payfort_view_model.dart +++ b/lib/features/payfort/payfort_view_model.dart @@ -110,7 +110,7 @@ class PayfortViewModel extends ChangeNotifier { onError!(failure.message); }, (apiResponse) { - log(apiResponse.data); + log(apiResponse.data.toString()); if (onSuccess != null) { onSuccess(apiResponse); } @@ -134,7 +134,7 @@ class PayfortViewModel extends ChangeNotifier { onError!(failure.message); }, (apiResponse) { - log(apiResponse.data); + log(apiResponse.data.toString()); if (onSuccess != null) { onSuccess(apiResponse); } diff --git a/lib/presentation/appointments/widgets/appointment_checkin_bottom_sheet.dart b/lib/presentation/appointments/widgets/appointment_checkin_bottom_sheet.dart index 5b1d1cd..9113ba3 100644 --- a/lib/presentation/appointments/widgets/appointment_checkin_bottom_sheet.dart +++ b/lib/presentation/appointments/widgets/appointment_checkin_bottom_sheet.dart @@ -60,7 +60,7 @@ class AppointmentCheckinBottomSheet extends StatelessWidget { double dist = Utils.distance(value.latitude, value.longitude, double.parse(projectDetailListModel.latitude!), double.parse(projectDetailListModel.longitude!)).ceilToDouble() * 1000; print(dist); if (dist <= projectDetailListModel.geofenceRadius!) { - sendCheckInRequest(projectDetailListModel.checkInQrCode!, context); + sendCheckInRequest(projectDetailListModel.checkInQrCode!, 3, context); } else { showCommonBottomSheetWithoutHeight(context, title: "Error".needTranslation, @@ -79,7 +79,7 @@ class AppointmentCheckinBottomSheet extends StatelessWidget { Future.delayed(const Duration(milliseconds: 500), () { showNfcReader(context, onNcfScan: (String nfcId) { Future.delayed(const Duration(milliseconds: 100), () { - sendCheckInRequest(nfcId, context); + sendCheckInRequest(nfcId, 1, context); }); }, onCancel: () {}); }); @@ -92,7 +92,7 @@ class AppointmentCheckinBottomSheet extends StatelessWidget { ).onPress(() async { String onlineCheckInQRCode = (await BarcodeScanner.scan().then((value) => value.rawContent)); if (onlineCheckInQRCode != "") { - sendCheckInRequest(onlineCheckInQRCode, context); + sendCheckInRequest(onlineCheckInQRCode, 2, context); } else {} }), ], @@ -140,12 +140,12 @@ class AppointmentCheckinBottomSheet extends StatelessWidget { ); } - void sendCheckInRequest(String scannedCode, BuildContext context) async { + void sendCheckInRequest(String scannedCode, int checkInType, BuildContext context) async { LoaderBottomSheet.showLoader(loadingText: "Processing Check-In...".needTranslation); await myAppointmentsViewModel.sendCheckInNfcRequest( patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, scannedCode: scannedCode, - checkInType: 2, + checkInType: checkInType, onSuccess: (apiResponse) { LoaderBottomSheet.hideLoader(); showCommonBottomSheetWithoutHeight(context, title: "Success".needTranslation, child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr()), callBackFunc: () async { diff --git a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart index 2877b27..d54042e 100644 --- a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart +++ b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart @@ -322,15 +322,29 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget { } Future askVideoCallPermission() async { - Map statuses = await [Permission.camera, Permission.microphone, Permission.notification].request(); + bool hasPermission = false; + if (Platform.isIOS) { + Map statuses = await [Permission.camera, Permission.microphone].request(); - if (statuses[Permission.camera] == PermissionStatus.granted && statuses[Permission.microphone] == PermissionStatus.granted && statuses[Permission.notification] == PermissionStatus.granted) { - // Camera permission granted - return true; + if (statuses[Permission.camera] == PermissionStatus.granted && statuses[Permission.microphone] == PermissionStatus.granted) { + // Camera permission granted + hasPermission = true; + } else { + hasPermission = false; + } } else { - return false; + Map statuses = await [Permission.camera, Permission.microphone, Permission.notification].request(); + + if (statuses[Permission.camera] == PermissionStatus.granted && statuses[Permission.microphone] == PermissionStatus.granted && statuses[Permission.notification] == PermissionStatus.granted) { + // Camera permission granted + hasPermission = true; + } else { + hasPermission = false; + } } + return hasPermission; + // if (!(await Permission.camera.request().isGranted) || !(await Permission.microphone.request().isGranted)) { // return false; // } diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index fc50d02..64884e5 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -405,15 +405,15 @@ class _LandingPageState extends State { SizedBox(height: 10.h), "Hala ${appState.getAuthenticatedUser()!.firstName}!!!".needTranslation.toText16(isBold: true), SizedBox(height: 8.h), - "Your turn is after ${immediateLiveCareVM.patientLiveCareHistoryList[0].patCount} patients.".toText14(isBold: true), - SizedBox(height: 8.h), - Column( + "Your turn is after ${immediateLiveCareVM.patientLiveCareHistoryList[0].patCount} patients.".needTranslation.toText14(isBold: true), + SizedBox(height: 8.h), + Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Expected waiting time: ".toText12(isBold: true), - SizedBox(height: 8.h), - ValueListenableBuilder( - valueListenable: immediateLiveCareVM.durationNotifier, + "Expected waiting time: ".needTranslation.toText12(isBold: true), + SizedBox(height: 7.h), + ValueListenableBuilder( + valueListenable: immediateLiveCareVM.durationNotifier, builder: (context, duration, child) { return Column( mainAxisAlignment: MainAxisAlignment.center, @@ -423,9 +423,8 @@ class _LandingPageState extends State { ); }, ), - SizedBox(height: 12.h), - ], - ), + ], + ), // CustomButton( // text: "View Details".needTranslation, // onPressed: () async { From 3cc2610d30fd8a031d34f298735763da94f15764 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 28 Dec 2025 10:39:53 +0300 Subject: [PATCH 5/6] updates --- lib/features/blood_donation/blood_donation_repo.dart | 1 + lib/presentation/hmg_services/services_page.dart | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/features/blood_donation/blood_donation_repo.dart b/lib/features/blood_donation/blood_donation_repo.dart index 84997b2..dce0975 100644 --- a/lib/features/blood_donation/blood_donation_repo.dart +++ b/lib/features/blood_donation/blood_donation_repo.dart @@ -66,6 +66,7 @@ class BloodDonationRepoImp implements BloodDonationRepo { await apiClient.post( GET_BLOOD_REQUEST, body: mapDevice, + isAllowAny: true, onFailure: (error, statusCode, {messageStatus, failureType}) { failure = failureType; }, diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index 8b10ab0..ae78973 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -86,14 +86,16 @@ class ServicesPage extends StatelessWidget { route: null, onTap: () async { LoaderBottomSheet.showLoader(loadingText: "Fetching Data..."); await bloodDonationViewModel.getRegionSelectedClinics(onSuccess: (val) async { - await bloodDonationViewModel.getPatientBloodGroupDetails(onSuccess: (val) { + // await bloodDonationViewModel.getPatientBloodGroupDetails(onSuccess: (val) { LoaderBottomSheet.hideLoader(); Navigator.of(GetIt.instance().navigatorKey.currentContext!).push( CustomPageRoute( page: BloodDonationPage(), ), ); - }); + // }, onError: (err) { + // LoaderBottomSheet.hideLoader(); + // }); }, onError: (err) { LoaderBottomSheet.hideLoader(); }); From dcdd17f0e9ae0cd244b41f73ab1060f9aa76e02f Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 28 Dec 2025 16:13:53 +0300 Subject: [PATCH 6/6] sickleave fix --- lib/presentation/medical_file/patient_sickleaves_list_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/presentation/medical_file/patient_sickleaves_list_page.dart b/lib/presentation/medical_file/patient_sickleaves_list_page.dart index cbd7b56..ef5aaeb 100644 --- a/lib/presentation/medical_file/patient_sickleaves_list_page.dart +++ b/lib/presentation/medical_file/patient_sickleaves_list_page.dart @@ -108,7 +108,7 @@ class _PatientSickleavesListPageState extends State { ? PatientSickLeaveCard( patientSickLeavesResponseModel: PatientSickLeavesResponseModel(), isLoading: true, - ).paddingSymmetrical(24.h, 0.0) + ).paddingSymmetrical(0.h, 12.h) : model.patientSickLeaveList.isNotEmpty ? AnimationConfiguration.staggeredList( position: index,