diff --git a/assets/images/png/blood_donation_image.png b/assets/images/png/blood_donation_image.png new file mode 100644 index 00000000..c7e82c7f Binary files /dev/null and b/assets/images/png/blood_donation_image.png differ diff --git a/assets/images/png/cmc_services_image.png b/assets/images/png/cmc_services_image.png new file mode 100644 index 00000000..baad76de Binary files /dev/null and b/assets/images/png/cmc_services_image.png differ diff --git a/assets/images/png/emergency_services_image.png b/assets/images/png/emergency_services_image.png new file mode 100644 index 00000000..f9924a52 Binary files /dev/null and b/assets/images/png/emergency_services_image.png differ diff --git a/assets/images/png/ereferral_services_image.png b/assets/images/png/ereferral_services_image.png new file mode 100644 index 00000000..15194b59 Binary files /dev/null and b/assets/images/png/ereferral_services_image.png differ diff --git a/assets/images/png/water_consumption_image.png b/assets/images/png/water_consumption_image.png new file mode 100644 index 00000000..604fa8a2 Binary files /dev/null and b/assets/images/png/water_consumption_image.png differ diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 979b12bf..46633cbf 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -187,7 +187,7 @@ "lastName": "اسم العائلة", "female": "أنثى", "male": "ذكر", - "preferredLanguage": "اللغة المفضلة *", + "preferredLanguage": "اللغة المفضلة", "locationsRegister": "أين ترغب في إنشاء هذا الملف؟", "ksa": "السعودية", "dubai": "دبي", @@ -1612,7 +1612,10 @@ "verifyInsurance": "التحقق من التأمين", "tests": "تحليل", "calendarPermissionAlert": "يرجى منح إذن الوصول إلى التقويم من إعدادات التطبيق لضبط تذكير تناول الدواء.", + "sortByNearestLocation": "فرز حسب الأقرب إلى موقعك", + "giveLocationPermissionForNearestList": "يرجى منح إذن الوصول إلى الموقع من إعدادات التطبيق لعرض أقرب المواقع.", "sortByLocation": "الترتيب حسب الموقع", "timeForFirstReminder": "وقت التذكير الأول", - "reminderRemovalNote": "يمكنك إزالتها من التقويم الخاص بك لاحقاً عن طريق إيقاف تشغيل التذكير" + "reminderRemovalNote": "يمكنك إزالتها من التقويم الخاص بك لاحقاً عن طريق إيقاف تشغيل التذكير", + "communicationLanguage": "لغة التواصل" } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 727b2ee0..61453b29 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -187,7 +187,7 @@ "lastName": "Last Name", "female": "Female", "male": "Male", - "preferredLanguage": "Preferred Language *", + "preferredLanguage": "Preferred Language", "locationsRegister": "Where do you want to create this file?", "ksa": "KSA", "dubai": "Dubai", @@ -1605,7 +1605,10 @@ "verifyInsurance": "Verify Insurance", "tests": "tests", "calendarPermissionAlert": "Please grant calendar access permission from app settings to set medication reminder.", - "sortByLocation": "Sort by location", "timeForFirstReminder": "Time for 1st reminder", - "reminderRemovalNote": "You can remove it from your calendar later by switching off the reminder" + "reminderRemovalNote": "You can remove it from your calendar later by switching off the reminder", + "sortByLocation": "Sort by location", + "sortByNearestLocation": "Sort by nearest to your location", + "giveLocationPermissionForNearestList": "Please grant location permission from app settings to see the nearest locations.", + "communicationLanguage": "Communication Language" } diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index 5fae22b1..898d5661 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -233,7 +233,7 @@ class ApiConsts { static String getAiOverViewLabOrder = "Services/Patients.svc/REST/HMGAI_Lab_Analyzer_API"; // ************ static values for Api **************** - static final double appVersionID = 20.5; + static final double appVersionID = 20.9; // static final double appVersionID = 50.7; static final int appChannelId = 3; diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index 96d196ae..3ef55b46 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -359,6 +359,11 @@ class AppAssets { static const String homeHealthCareService = '$pngBasePath/home_health_care.png'; static const String pharmacyService = '$pngBasePath/pharmacy_service.png'; + static const String bloodDonationService = '$pngBasePath/blood_donation_image.png'; + static const String waterConsumptionService = '$pngBasePath/water_consumption_image.png'; + static const String emergencyService = '$pngBasePath/emergency_services_image.png'; + static const String cmcService = '$pngBasePath/cmc_services_image.png'; + static const String eReferralService = '$pngBasePath/ereferral_services_image.png'; static const String maleImg = '$pngBasePath/male_img.png'; static const String femaleImg = '$pngBasePath/female_img.png'; diff --git a/lib/core/app_state.dart b/lib/core/app_state.dart index b95b883f..7d3ab1a4 100644 --- a/lib/core/app_state.dart +++ b/lib/core/app_state.dart @@ -169,7 +169,7 @@ class AppState { ///this will be called if there is any problem in getting the user location void resetLocation() { userLong = 0.0; - userLong = 0.0; + userLat = 0.0; } setRatedVisible(bool value) { diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index ac8c152a..f63b160b 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -382,7 +382,7 @@ class Utils { children: [ Lottie.asset(AppAnimations.checkmark, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), SizedBox(height: 8.h), - (loadingText ?? LocaleKeys.loadingText.tr()).toText16(color: AppColors.blackColor), + (loadingText ?? LocaleKeys.loadingText.tr()).toText16(color: AppColors.blackColor).paddingSymmetrical(24.h, 0.h), SizedBox(height: 8.h), ], ).center; @@ -396,7 +396,7 @@ class Utils { Lottie.asset(AppAnimations.errorAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), SizedBox(height: 8.h), - (loadingText ?? LocaleKeys.loadingText.tr()).toText16(color: AppColors.blackColor), + (loadingText ?? LocaleKeys.loadingText.tr()).toText16(color: AppColors.blackColor).paddingSymmetrical(24.h, 0.h), SizedBox(height: 8.h), ], ).center; @@ -769,20 +769,20 @@ class Utils { mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Image.asset(AppAssets.mada, width: 25.h, height: 25.h), + Image.asset(AppAssets.mada, width: 35.h, height: 35.h), Image.asset( AppAssets.tamaraEng, - width: 25.h, - height: 25.h, + width: 35.h, + height: 35.h, fit: BoxFit.contain, errorBuilder: (context, error, stackTrace) { debugPrint('Failed to load Tamara PNG in payment methods: $error'); - return Utils.buildSvgWithAssets(icon: AppAssets.tamara, width: 25.h, height: 25.h, fit: BoxFit.contain); + return Utils.buildSvgWithAssets(icon: AppAssets.tamara, width: 35.h, height: 35.h, fit: BoxFit.contain); }, ), - Image.asset(AppAssets.visa, width: 25.h, height: 25.h), - Image.asset(AppAssets.mastercard, width: 25.h, height: 25.h), - Image.asset(AppAssets.applePay, width: 25.h, height: 25.h), + Image.asset(AppAssets.visa, width: 35.h, height: 35.h), + Image.asset(AppAssets.mastercard, width: 35.h, height: 25.h), + Image.asset(AppAssets.applePay, width: 35.h, height: 35.h), ], ); } diff --git a/lib/features/hmg_services/models/ui_models/vital_sign_ui_model.dart b/lib/features/hmg_services/models/ui_models/vital_sign_ui_model.dart index 328ffc93..66f5d77b 100644 --- a/lib/features/hmg_services/models/ui_models/vital_sign_ui_model.dart +++ b/lib/features/hmg_services/models/ui_models/vital_sign_ui_model.dart @@ -48,13 +48,14 @@ class VitalSignUiModel { ); } - if (s.contains('low')) { - final Color yellowBg = AppColors.warningColor.withValues(alpha: 0.12); + // Warning for both low and overweight/underweight BMI, since they can indicate potential health issues. + if (s.contains('low') || s.contains('underweight') || s.contains('overweight')) { + final Color yellowBg = AppColors.highAndLow.withValues(alpha: 0.12); return VitalSignUiModel( iconBg: yellowBg, - iconFg: AppColors.warningColor, + iconFg: AppColors.highAndLow, chipBg: yellowBg, - chipFg: AppColors.warningColor, + chipFg: AppColors.highAndLow, ); } @@ -91,12 +92,27 @@ class VitalSignUiModel { } static String bmiStatus(dynamic bmi) { - if (bmi == null) return 'N/A'; - final double bmiValue = double.tryParse(bmi.toString()) ?? 0; - if (bmiValue < 18.5) return 'Underweight'; - if (bmiValue < 25) return 'Normal'; - if (bmiValue < 30) return 'Overweight'; - return 'High'; + String bmiStatus = 'Normal'; + final double bmiResult = double.tryParse(bmi.toString()) ?? 0; + + if (bmiResult >= 30) { + bmiStatus = "High"; + } else if (bmiResult < 30 && bmiResult >= 25) { + bmiStatus = "Overweight"; + } else if (bmiResult < 25 && bmiResult >= 18.5) { + bmiStatus = "Normal"; + } else if (bmiResult < 18.5) { + bmiStatus = "Underweight"; + } + + // if (bmi == null) return 'N/A'; + // final double bmiValue = double.tryParse(bmi.toString()) ?? 0; + // if (bmiValue < 18.5) return 'Underweight'; + // if (bmiValue < 25) return 'Normal'; + // if (bmiValue < 30) return 'Overweight'; + // return 'High'; + + return bmiStatus; } } diff --git a/lib/features/my_appointments/appointment_via_region_viewmodel.dart b/lib/features/my_appointments/appointment_via_region_viewmodel.dart index c5dcaf62..10da4e3d 100644 --- a/lib/features/my_appointments/appointment_via_region_viewmodel.dart +++ b/lib/features/my_appointments/appointment_via_region_viewmodel.dart @@ -43,9 +43,20 @@ class AppointmentViaRegionViewmodel extends ChangeNotifier { int hmgCount = 0; int hmcCount = 0; RegionBottomSheetType regionBottomSheetType = RegionBottomSheetType.FOR_REGION; + bool sortByLocation = false; AppointmentViaRegionViewmodel({required this.navigationService,required this.appState}); + void initSortByLocation() { + sortByLocation = (appState.userLat != 0.0) && (appState.userLong != 0.0); + notifyListeners(); + } + + void setSortByLocation(bool value) { + sortByLocation = value; + notifyListeners(); + } + void setSelectedRegionId(String? regionId) { selectedRegionId = regionId; notifyListeners(); @@ -122,6 +133,7 @@ class AppointmentViaRegionViewmodel extends ChangeNotifier { setFacility(null); setBottomSheetType(RegionBottomSheetType.FOR_REGION); setBottomSheetState(AppointmentViaRegionState.REGION_SELECTION); + sortByLocation = false; } void setHospitalModel(PatientDoctorAppointmentList? hospital) { diff --git a/lib/features/profile_settings/models/get_patient_info_response_model.dart b/lib/features/profile_settings/models/get_patient_info_response_model.dart new file mode 100644 index 00000000..ea89c9f9 --- /dev/null +++ b/lib/features/profile_settings/models/get_patient_info_response_model.dart @@ -0,0 +1,136 @@ +class GetPatientInfoForUpdate { + int? projectID; + int? patientType; + int? patientID; + String? emailAddress; + bool? isEmailAlertRequired; + bool? isSMSAlertRequired; + String? preferredLanguage; + String? emergencyContactName; + String? emergencyContactNo; + int? editedBy; + String? editedOn; + String? patientIdentificationNo; + int? patientIdentificationType; + String? firstName; + String? middleName; + String? lastName; + int? gender; + String? dateofBirth; + String? dateofBirthN; + String? firstNameN; + String? middleNameN; + String? lastNameN; + int? projectID1; + int? patientType1; + int? patientID1; + bool? isIVRStopped; + String? aGE; + String? genderString; + bool? isNeedUpdateIdintificationNo; + String? nationality; + String? type; + + GetPatientInfoForUpdate( + {this.projectID, + this.patientType, + this.patientID, + this.emailAddress, + this.isEmailAlertRequired, + this.isSMSAlertRequired, + this.preferredLanguage, + this.emergencyContactName, + this.emergencyContactNo, + this.editedBy, + this.editedOn, + this.patientIdentificationNo, + this.patientIdentificationType, + this.firstName, + this.middleName, + this.lastName, + this.gender, + this.dateofBirth, + this.dateofBirthN, + this.firstNameN, + this.middleNameN, + this.lastNameN, + this.projectID1, + this.patientType1, + this.patientID1, + this.isIVRStopped, + this.aGE, + this.genderString, + this.isNeedUpdateIdintificationNo, + this.nationality, + this.type}); + + GetPatientInfoForUpdate.fromJson(Map json) { + projectID = json['ProjectID']; + patientType = json['PatientType']; + patientID = json['PatientID']; + emailAddress = json['EmailAddress']; + isEmailAlertRequired = json['IsEmailAlertRequired']; + isSMSAlertRequired = json['IsSMSAlertRequired']; + preferredLanguage = json['PreferredLanguage']; + emergencyContactName = json['EmergencyContactName']; + emergencyContactNo = json['EmergencyContactNo']; + editedBy = json['EditedBy']; + editedOn = json['EditedOn']; + patientIdentificationNo = json['PatientIdentificationNo']; + patientIdentificationType = json['PatientIdentificationType']; + firstName = json['FirstName']; + middleName = json['MiddleName']; + lastName = json['LastName']; + gender = json['Gender']; + dateofBirth = json['DateofBirth']; + dateofBirthN = json['DateofBirthN']; + firstNameN = json['FirstNameN']; + middleNameN = json['MiddleNameN']; + lastNameN = json['LastNameN']; + projectID1 = json['ProjectID1']; + patientType1 = json['PatientType1']; + patientID1 = json['PatientID1']; + isIVRStopped = json['IsIVRStopped']; + aGE = json['AGE']; + genderString = json['GenderString']; + isNeedUpdateIdintificationNo = json['IsNeedUpdateIdintificationNo']; + nationality = json['Nationality']; + type = json['Type']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['PatientType'] = this.patientType; + data['PatientID'] = this.patientID; + data['EmailAddress'] = this.emailAddress; + data['IsEmailAlertRequired'] = this.isEmailAlertRequired; + data['IsSMSAlertRequired'] = this.isSMSAlertRequired; + data['PreferredLanguage'] = this.preferredLanguage; + data['EmergencyContactName'] = this.emergencyContactName; + data['EmergencyContactNo'] = this.emergencyContactNo; + data['EditedBy'] = this.editedBy; + data['EditedOn'] = this.editedOn; + data['PatientIdentificationNo'] = this.patientIdentificationNo; + data['PatientIdentificationType'] = this.patientIdentificationType; + data['FirstName'] = this.firstName; + data['MiddleName'] = this.middleName; + data['LastName'] = this.lastName; + data['Gender'] = this.gender; + data['DateofBirth'] = this.dateofBirth; + data['DateofBirthN'] = this.dateofBirthN; + data['FirstNameN'] = this.firstNameN; + data['MiddleNameN'] = this.middleNameN; + data['LastNameN'] = this.lastNameN; + data['ProjectID1'] = this.projectID1; + data['PatientType1'] = this.patientType1; + data['PatientID1'] = this.patientID1; + data['IsIVRStopped'] = this.isIVRStopped; + data['AGE'] = this.aGE; + data['GenderString'] = this.genderString; + data['IsNeedUpdateIdintificationNo'] = this.isNeedUpdateIdintificationNo; + data['Nationality'] = this.nationality; + data['Type'] = this.type; + return data; + } +} diff --git a/lib/features/profile_settings/profile_settings_repo.dart b/lib/features/profile_settings/profile_settings_repo.dart index 253bf505..9d4c1221 100644 --- a/lib/features/profile_settings/profile_settings_repo.dart +++ b/lib/features/profile_settings/profile_settings_repo.dart @@ -3,6 +3,7 @@ import 'package:hmg_patient_app_new/core/api/api_client.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; +import 'package:hmg_patient_app_new/features/profile_settings/models/get_patient_info_response_model.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; abstract class ProfileSettingsRepo { @@ -13,6 +14,8 @@ abstract class ProfileSettingsRepo { /// Deactivates (deletes) the patient's account. Future>> deactivateAccount(); + + Future>> getProfileSettings(); } class ProfileSettingsRepoImp implements ProfileSettingsRepo { @@ -96,5 +99,43 @@ class ProfileSettingsRepoImp implements ProfileSettingsRepo { return Left(UnknownFailure(e.toString())); } } + + @override + Future> getProfileSettings() async { + final Map body = {}; + + try { + GenericApiModel? apiResponse; + Failure? failure; + + await apiClient.post( + PROFILE_SETTING, + body: body, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + final patientProfileInfo = GetPatientInfoForUpdate.fromJson(response['PateintInfoForUpdateList'][0]); + + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: errorMessage, + data: patientProfileInfo, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } } diff --git a/lib/features/profile_settings/profile_settings_view_model.dart b/lib/features/profile_settings/profile_settings_view_model.dart index 92f11528..28f28af6 100644 --- a/lib/features/profile_settings/profile_settings_view_model.dart +++ b/lib/features/profile_settings/profile_settings_view_model.dart @@ -1,8 +1,16 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; +import 'package:get_it/get_it.dart'; +import 'package:hmg_patient_app_new/features/profile_settings/models/get_patient_info_response_model.dart'; import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_repo.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/profile_settings/widgets/preferred_language_widget.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; class ProfileSettingsViewModel extends ChangeNotifier { static const String _darkModeKey = 'is_dark_mode'; @@ -30,6 +38,9 @@ class ProfileSettingsViewModel extends ChangeNotifier { bool isDeactivateAccountSuccess = false; String? deactivateAccountError; + late GetPatientInfoForUpdate getPatientInfoForUpdate; + bool isPatientProfileLoading = false; + ProfileSettingsViewModel({ required CacheService cacheService, required this.profileSettingsRepo, @@ -88,6 +99,34 @@ class ProfileSettingsViewModel extends ChangeNotifier { ); } + Future getProfileSettings({ + Function(dynamic)? onSuccess, + Function(String)? onError, + }) async { + isPatientProfileLoading = true; + notifyListeners(); + + final result = await profileSettingsRepo.getProfileSettings(); + + result.fold( + (failure) { + isPatientProfileLoading = false; + notifyListeners(); + if (onError != null) { + onError(failure.message); + } else { + errorHandlerService.handleError(failure: failure); + } + }, + (response) { + getPatientInfoForUpdate = response.data; + isPatientProfileLoading = false; + notifyListeners(); + onSuccess?.call(response.data); + }, + ); + } + // ── Deactivate account ─────────────────────────────────────────────── Future deactivateAccount({ @@ -123,7 +162,14 @@ class ProfileSettingsViewModel extends ChangeNotifier { // ── Helpers ────────────────────────────────────────────────────────── - void notify() { - notifyListeners(); + openPreferredLanguageBottomSheet() { + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.preferredLanguage.tr(), + GetIt.instance().navigatorKey.currentContext!, + child: PreferredLanguageWidget(), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); } } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 2f2ba30d..34a0c222 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1604,9 +1604,12 @@ abstract class LocaleKeys { static const verifyInsurance = 'verifyInsurance'; static const tests = 'tests'; static const calendarPermissionAlert = 'calendarPermissionAlert'; + static const sortByNearestLocation = 'sortByNearestLocation'; + static const giveLocationPermissionForNearestList = 'giveLocationPermissionForNearestList'; static const sortByLocation = 'sortByLocation'; static const timeForFirstReminder = 'timeForFirstReminder'; static const reminderRemovalNote = 'reminderRemovalNote'; + static const communicationLanguage = 'communicationLanguage'; static const featureComingSoonDescription = 'featureComingSoonDescription'; } diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index 072cb04a..176b3771 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -286,7 +286,7 @@ class _AppointmentDetailsPageState extends State { Positioned( bottom: 0, child: SizedBox( - width: MediaQuery.of(context).size.width * 0.785, + width: MediaQuery.of(context).size.width - 85.w, child: CustomButton( onPressed: () async { if (widget.patientAppointmentHistoryResponseModel.projectID == 130 || widget.patientAppointmentHistoryResponseModel.projectID == 120) { @@ -394,7 +394,6 @@ class _AppointmentDetailsPageState extends State { }, isMultiAllowed: true, onMultiDateSuccess: (int selectedIndex) async { - isEventAddedOrRemoved = await calender.createOrUpdateEvent( title: "Appointment Reminder with ${widget.patientAppointmentHistoryResponseModel.doctorNameObj} on ${DateUtil.convertStringToDate(widget.patientAppointmentHistoryResponseModel.appointmentDate)}, Appointment #${widget.patientAppointmentHistoryResponseModel.appointmentNo}", @@ -822,8 +821,7 @@ class _AppointmentDetailsPageState extends State { child: LocaleKeys.upcomingPaymentNow .tr(context: context) .toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor)), - "VAT 15%(${widget.patientAppointmentHistoryResponseModel.patientTaxAmount})" - .toText14(isBold: true, color: AppColors.greyTextColor, letterSpacing: -2), + "VAT 15%(${widget.patientAppointmentHistoryResponseModel.patientTaxAmount})".toText14(isBold: true, color: AppColors.greyTextColor, letterSpacing: -0.64), ], ), SizedBox(height: 18.h), @@ -831,7 +829,7 @@ class _AppointmentDetailsPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox( - width: 150.h, + width: 200.h, child: Utils.getPaymentMethods(), ), Row( 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..8904e585 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,11 +1,13 @@ 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/core/utils/utils.dart' show Utils; 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/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'; @@ -14,7 +16,6 @@ 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,66 +126,111 @@ 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) { - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TextInputWidget( - labelText: LocaleKeys.search.tr(context: context), - hintText: LocaleKeys.searchHospital.tr(context: context), - controller: searchText, - onChange: (value) { - debouncer.run((){ - onHospitalSearch(value??""); - }); - }, - isEnable: true, - prefix: null, - - autoFocus: false, - isBorderAllowed: false, - keyboardType: TextInputType.text, - isAllowLeadingIcon: true, - selectionType: SelectionTypeEnum.search, - padding: EdgeInsets.symmetric( - vertical: ResponsiveExtension(10).h, - horizontal: ResponsiveExtension(15).h, + return Consumer(builder: (context, myAppointmentsVM, child) { + if (myAppointmentsVM.isRegionListLoading) { + return Container( + height: MediaQuery.of(context).size.height * 0.3, + decoration: BoxDecoration( + color: AppColors.whiteColor, + borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), - ), - SizedBox(height: 24.h), - TypeSelectionWidget( - selectedFacility:selectedFacility , - hmcCount: hmcCount.toString(), - hmgCount: hmgCount.toString(), - onitemClicked: (selectedValue){ - onFacilityClicked(selectedValue); - }, - ), - SizedBox(height: 21.h), - SizedBox( - height: MediaQuery.sizeOf(context).height * .4, - child: ListView.separated( - itemBuilder: (_, index) - { - var hospital = displayList?[index]; - return HospitalListItem( - hospitalData: hospital, - isLocationEnabled: true, - ).onPress(() { - onHospitalClicked(hospital!); - });}, - separatorBuilder: (_, __) => SizedBox( - height: 16.h, + child: Center( + child: Utils.getLoadingWidget(), + ), + ); + } else { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextInputWidget( + labelText: LocaleKeys.search.tr(context: context), + hintText: LocaleKeys.searchHospital.tr(context: context), + controller: searchText, + onChange: (value) { + debouncer.run(() { + onHospitalSearch(value ?? ""); + }); + }, + isEnable: true, + prefix: null, + autoFocus: false, + isBorderAllowed: false, + keyboardType: TextInputType.text, + isAllowLeadingIcon: true, + selectionType: SelectionTypeEnum.search, + padding: EdgeInsets.symmetric( + vertical: ResponsiveExtension(10).h, + horizontal: ResponsiveExtension(15).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), + ), + ], + ), ), - itemCount: displayList?.length ?? 0, - )) - ], - ); + if (onSortByLocationToggle != null) SizedBox(height: 8.h), + TypeSelectionWidget( + selectedFacility: selectedFacility, + hmcCount: hmcCount.toString(), + hmgCount: hmgCount.toString(), + onitemClicked: (selectedValue) { + onFacilityClicked(selectedValue); + }, + ), + SizedBox(height: 21.h), + SizedBox( + height: MediaQuery.sizeOf(context).height * .4, + child: ListView.separated( + itemBuilder: (_, index) { + var hospital = displayList?[index]; + return HospitalListItem( + hospitalData: hospital, + isLocationEnabled: sortByLocation, + ).onPress(() { + onHospitalClicked(hospital!); + }); + }, + separatorBuilder: (_, __) => SizedBox( + height: 16.h, + ), + itemCount: displayList?.length ?? 0, + )) + ], + ); + } + }); } } 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 489ee8b7..2b3a6ffc 100644 --- a/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart +++ b/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart @@ -3,6 +3,9 @@ import 'dart:async'; 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_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/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart' show Utils; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -14,6 +17,7 @@ import 'package:hmg_patient_app_new/presentation/appointments/widgets/region_bot import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:lottie/lottie.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -33,6 +37,7 @@ class _RegionBottomSheetBodyState extends State { @override void initState() { scheduleMicrotask(() { + regionalViewModel.initSortByLocation(); if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_REGION || regionalViewModel.regionBottomSheetType == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER ) { myAppointmentsViewModel.getRegionMappedProjectList(); } else if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_CLINIIC) { @@ -110,30 +115,136 @@ class _RegionBottomSheetBodyState extends State { } else { return SizedBox( height: MediaQuery.of(context).size.height * 0.5, - child: ListView.separated( - itemCount: myAppointmentsVM.hospitalList?.registeredDoctorMap?.length ?? 0, - separatorBuilder: (_, __) { - return SizedBox( - height: 16.h, - ); - }, - itemBuilder: (_, index) { - String key = myAppointmentsVM.hospitalList?.registeredDoctorMap?.keys.toList()[index] ?? ''; - return RegionListItem( - title: key, - subTitle: "", - hmcCount: "${myAppointmentsVM.hospitalList?.registeredDoctorMap?[key]?.hmcSize ?? 0}", - hmgCount: "${myAppointmentsVM.hospitalList?.registeredDoctorMap?[key]?.hmgSize ?? 0}", - ).onPress(() { - regionalViewModel.setSelectedRegionId(key); - regionalViewModel.setDisplayListAndRegionHospitalList(myAppointmentsVM.hospitalList?.registeredDoctorMap![key]); - regionalViewModel.setBottomSheetState(AppointmentViaRegionState.HOSPITAL_SELECTION); - }); - }, + child: Column( + children: [ + Consumer( + builder: (context, regionVM, _) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 4.w, vertical: 8.h), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.location, iconColor: AppColors.greyTextColor, width: 24.h, height: 24.h), + SizedBox(width: 12.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: regionVM.sortByLocation, + onChanged: (value) => _handleSortByLocationToggle(value), + activeThumbColor: AppColors.successColor, + activeTrackColor: AppColors.successColor.withValues(alpha: 0.15), + ), + ], + ), + ); + }, + ), + Expanded( + child: ListView.separated( + itemCount: myAppointmentsVM.hospitalList?.registeredDoctorMap?.length ?? 0, + separatorBuilder: (_, __) { + return SizedBox( + height: 16.h, + ); + }, + itemBuilder: (_, index) { + String key = myAppointmentsVM.hospitalList?.registeredDoctorMap?.keys.toList()[index] ?? ''; + return RegionListItem( + title: key, + subTitle: "", + hmcCount: "${myAppointmentsVM.hospitalList?.registeredDoctorMap?[key]?.hmcSize ?? 0}", + hmgCount: "${myAppointmentsVM.hospitalList?.registeredDoctorMap?[key]?.hmgSize ?? 0}", + ).onPress(() { + regionalViewModel.setSelectedRegionId(key); + regionalViewModel.setDisplayListAndRegionHospitalList(myAppointmentsVM.hospitalList?.registeredDoctorMap![key]); + regionalViewModel.setBottomSheetState(AppointmentViaRegionState.HOSPITAL_SELECTION); + }); + }, + ), + ), + ], ), ); } }, ); } + + void _handleSortByLocationToggle(bool value) { + if (value) { + // User wants to sort by location — check permission & get location + final locationUtils = getIt.get(); + locationUtils.getLocation( + isShowConfirmDialog: true, + onSuccess: (latLng) { + regionalViewModel.setSortByLocation(true); + if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_REGION || regionalViewModel.regionBottomSheetType == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER) { + myAppointmentsViewModel.getRegionMappedProjectList(); + } else if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_CLINIIC) { + myAppointmentsViewModel.getMappedDoctors(); + } + }, + 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, + ); + regionalViewModel.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, + ); + regionalViewModel.setSortByLocation(false); + }, + ); + } else { + // User turned off sort by location — reset location & re-fetch + final appState = getIt.get(); + appState.resetLocation(); + regionalViewModel.setSortByLocation(false); + if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_REGION || regionalViewModel.regionBottomSheetType == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER) { + myAppointmentsViewModel.getRegionMappedProjectList(); + } else if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_CLINIIC) { + myAppointmentsViewModel.getMappedDoctors(); + } + } + } } diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart index 4a8ada6a..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'; @@ -57,7 +59,7 @@ class _BookAppointmentPageState extends State { scheduleMicrotask(() { // bookAppointmentsViewModel.selectedTabIndex = 0; bookAppointmentsViewModel.initBookAppointmentViewModel(); - bookAppointmentsViewModel.getLocation(); + // bookAppointmentsViewModel.getLocation(); immediateLiveCareViewModel.initImmediateLiveCare(); if (appState.isAuthenticated) { getIt.get().getPatientMyDoctors(); @@ -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/livecare/immediate_livecare_payment_details.dart b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart index 7c2784de..c885b595 100644 --- a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart +++ b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart @@ -7,6 +7,7 @@ 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/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/int_extensions.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'; @@ -82,9 +83,7 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget { runSpacing: 4.h, children: [ AppCustomChipWidget(labelText: "${appState.getAuthenticatedUser()!.age} ${LocaleKeys.yearsOld.tr(context: context)}"), - AppCustomChipWidget( - labelText: - "${LocaleKeys.clinic.tr()}: ${(appState.isArabic() ? immediateLiveCareVM.immediateLiveCareSelectedClinic.serviceNameN : immediateLiveCareVM.immediateLiveCareSelectedClinic.serviceName) ?? ""}"), + AppCustomChipWidget(labelText: "${LocaleKeys.gender.tr(context: context)}: ${appState.getAuthenticatedUser()?.gender == 1 ? LocaleKeys.malE.tr(context: context) : LocaleKeys.femaleGender.tr(context: context)}"), ], ), ], @@ -105,17 +104,28 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget { ), child: Padding( padding: EdgeInsets.all(16.h), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ + AppCustomChipWidget( + labelText: + "${LocaleKeys.clinic.tr()}: ${(appState.isArabic() ? immediateLiveCareVM.immediateLiveCareSelectedClinic.serviceNameN : immediateLiveCareVM.immediateLiveCareSelectedClinic.serviceName) ?? ""}"), + SizedBox(height: 16.h), + 1.divider, + SizedBox(height: 16.h), Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Utils.buildSvgWithAssets(icon: getLiveCareTypeIcon(immediateLiveCareVM.liveCareSelectedCallType), width: 32.h, height: 32.h, fit: BoxFit.contain, applyThemeColor: false), - SizedBox(width: 8.h), - getLiveCareType(context, immediateLiveCareVM.liveCareSelectedCallType).toText16(isBold: true), + Row( + children: [ + Utils.buildSvgWithAssets(icon: getLiveCareTypeIcon(immediateLiveCareVM.liveCareSelectedCallType), width: 32.h, height: 32.h, fit: BoxFit.contain, applyThemeColor: false), + SizedBox(width: 8.h), + getLiveCareType(context, immediateLiveCareVM.liveCareSelectedCallType).toText16(isBold: true), + ], + ), + Utils.buildSvgWithAssets(icon: AppAssets.edit_icon, width: 24.h, height: 24.h, fit: BoxFit.contain), ], ), - Utils.buildSvgWithAssets(icon: AppAssets.edit_icon, width: 24.h, height: 24.h, fit: BoxFit.contain), ], ), ), @@ -202,7 +212,7 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - SizedBox(width: 150.h, child: Utils.getPaymentMethods()), + SizedBox(width: 200.h, child: Utils.getPaymentMethods()), Utils.getPaymentAmountWithSymbol(immediateLiveCareVM.liveCareImmediateAppointmentFeesList.total!.toText24(isBold: true), AppColors.blackColor, 17, isSaudiCurrency: (immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "sar" || immediateLiveCareVM.liveCareImmediateAppointmentFeesList.currency!.toLowerCase() == "ريال")), diff --git a/lib/presentation/book_appointment/review_appointment_page.dart b/lib/presentation/book_appointment/review_appointment_page.dart index 794b821b..9069138f 100644 --- a/lib/presentation/book_appointment/review_appointment_page.dart +++ b/lib/presentation/book_appointment/review_appointment_page.dart @@ -109,8 +109,8 @@ class _ReviewAppointmentPageState extends State { SizedBox(height: 12.h), Wrap( direction: Axis.horizontal, - spacing: 8.h, - runSpacing: 8.h, + spacing: 4.h, + runSpacing: 4.h, children: [ AppCustomChipWidget( labelText: "${LocaleKeys.clinic.tr(context: context)}: ${bookAppointmentsViewModel.selectedDoctor.clinicName}", @@ -156,7 +156,15 @@ class _ReviewAppointmentPageState extends State { children: [ "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText16(isBold: true), SizedBox(height: 8.h), - AppCustomChipWidget(labelText: "${appState.getAuthenticatedUser()!.age} Years Old"), + Wrap( + direction: Axis.horizontal, + spacing: 4.h, + runSpacing: 4.h, + children: [ + AppCustomChipWidget(labelText: "${appState.getAuthenticatedUser()!.age} Years Old"), + AppCustomChipWidget(labelText: "${LocaleKeys.gender.tr(context: context)}: ${appState.getAuthenticatedUser()?.gender == 1 ? LocaleKeys.malE.tr(context: context) : LocaleKeys.femaleGender.tr(context: context)}"), + ], + ), ], ), ], 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..aaa52217 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,49 @@ 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); + + if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_REGION || regionalViewModel.regionBottomSheetType == RegionBottomSheetType.REGION_FOR_DENTAL_AND_LASER) { + bookAppointmentsViewModel.getRegionMappedProjectList(); + } else if (regionalViewModel.regionBottomSheetType == RegionBottomSheetType.FOR_CLINIIC) { + bookAppointmentsViewModel.getMappedDoctors(); + } + + // bookAppointmentsViewModel.getRegionMappedProjectList(); + } } diff --git a/lib/presentation/book_appointment/widgets/appointment_calendar.dart b/lib/presentation/book_appointment/widgets/appointment_calendar.dart index 57a045cc..56bffc38 100644 --- a/lib/presentation/book_appointment/widgets/appointment_calendar.dart +++ b/lib/presentation/book_appointment/widgets/appointment_calendar.dart @@ -99,12 +99,12 @@ class _AppointmentCalendarState extends State { showNavigationArrow: true, headerHeight: 60.h, headerStyle: CalendarHeaderStyle( - backgroundColor: AppColors.scaffoldBgColor, + backgroundColor: AppColors.transparent, textAlign: TextAlign.start, textStyle: TextStyle(fontSize: 18.f, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: AppColors.primaryRedColor, fontFamily: "Poppins"), ), viewHeaderStyle: ViewHeaderStyle( - backgroundColor: AppColors.scaffoldBgColor, + // backgroundColor: AppColors.scaffoldBgColor, dayTextStyle: TextStyle(fontSize: 14.f, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: AppColors.textColor, fontFamily: "Poppins"), ), view: CalendarView.month, diff --git a/lib/presentation/book_appointment/widgets/doctor_card.dart b/lib/presentation/book_appointment/widgets/doctor_card.dart index 02b2e55d..25856829 100644 --- a/lib/presentation/book_appointment/widgets/doctor_card.dart +++ b/lib/presentation/book_appointment/widgets/doctor_card.dart @@ -127,23 +127,23 @@ class DoctorCard extends StatelessWidget { spacing: 3.h, runSpacing: 4.h, children: [ - AppCustomChipWidget( - labelText: "${isLoading ? "Cardiologist" : doctorsListResponseModel.clinicName}", - ).toShimmer2(isShow: isLoading), - AppCustomChipWidget( - labelText: "${isLoading ? "Olaya Hospital" : doctorsListResponseModel.projectName}", - ).toShimmer2(isShow: isLoading), bookAppointmentsViewModel.isNearestAppointmentSelected ? doctorsListResponseModel.nearestFreeSlot != null ? AppCustomChipWidget( - // labelText: (isLoading ? "Cardiologist" : DateUtil.getDateStringForNearestSlot(doctorsListResponseModel.nearestFreeSlot)), - richText: (isLoading ? "Cardiologist" : DateUtil.getDateStringForNearestSlot(doctorsListResponseModel.nearestFreeSlot)) - .toText10(isEnglishOnly: true, color: AppColors.whiteColor), - backgroundColor: AppColors.successColor, - textColor: AppColors.whiteColor, + labelText: (isLoading ? "Cardiologist" : DateUtil.getDateStringForNearestSlot(doctorsListResponseModel.nearestFreeSlot)), + // richText: (isLoading ? "Cardiologist" : DateUtil.getDateStringForNearestSlot(doctorsListResponseModel.nearestFreeSlot)) + // .toText10(isEnglishOnly: true, color: AppColors.textColor), + // backgroundColor: AppColors.successColor, + textColor: AppColors.textColor, ).toShimmer2(isShow: isLoading) : SizedBox.shrink() : SizedBox.shrink(), + AppCustomChipWidget( + labelText: "${isLoading ? "Cardiologist" : doctorsListResponseModel.clinicName}", + ).toShimmer2(isShow: isLoading), + AppCustomChipWidget( + labelText: "${isLoading ? "Olaya Hospital" : doctorsListResponseModel.projectName}", + ).toShimmer2(isShow: isLoading), ], ), ], @@ -155,7 +155,7 @@ class DoctorCard extends StatelessWidget { ), ], ), - SizedBox(height: 12.h), + SizedBox(height: 16.h), CustomButton( text: LocaleKeys.bookAppo.tr(context: context), onPressed: () async { diff --git a/lib/presentation/contact_us/contact_us.dart b/lib/presentation/contact_us/contact_us.dart index 70ef6e3f..602fc3b2 100644 --- a/lib/presentation/contact_us/contact_us.dart +++ b/lib/presentation/contact_us/contact_us.dart @@ -14,6 +14,8 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/contact_us/feedback_page.dart'; import 'package:hmg_patient_app_new/presentation/contact_us/find_us_page.dart'; import 'package:hmg_patient_app_new/presentation/contact_us/live_chat_page.dart'; +import 'package:hmg_patient_app_new/presentation/home/service_info_page.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; @@ -80,15 +82,23 @@ class ContactUs extends StatelessWidget { LocaleKeys.liveChat.tr(), LocaleKeys.liveChatWithHMG.tr(), ).onPress(() { - locationUtils.getCurrentLocation(onSuccess: (value) { - contactUsViewModel.getLiveChatProjectsList(); - Navigator.pop(context); + if (getIt.get().isAuthenticated) { Navigator.of(context).push( CustomPageRoute( page: LiveChatPage(), ), ); - }); + } else { + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: ServiceInfoPage( + serviceName: LocaleKeys.liveChat.tr(), + serviceHeader: "HMG Hospital E-Referral: Streamlined patient referrals".needTranslation, + serviceDescription: "Facilitate seamless patient transfers to HMG with our secure e-referral system. Ensure continuity of care for every patient.".needTranslation, + serviceImage: AppAssets.eReferralService), + ), + ); + } }), ], ); diff --git a/lib/presentation/contact_us/find_us_page.dart b/lib/presentation/contact_us/find_us_page.dart index 9091f74d..0cabbf2b 100644 --- a/lib/presentation/contact_us/find_us_page.dart +++ b/lib/presentation/contact_us/find_us_page.dart @@ -59,7 +59,7 @@ class FindUsPage extends StatelessWidget { children: [ LocaleKeys.sortByLocation.tr(context: context).toText14(isBold: true), SizedBox(height: 4.h), - "Sort the locations by nearest to your location".toText11(color: AppColors.textColorLight, weight: FontWeight.w500), + LocaleKeys.sortByNearestLocation.tr(context: context).toText11(color: AppColors.textColorLight, weight: FontWeight.w500), ], ), const Spacer(), diff --git a/lib/presentation/emergency_services/emergency_services_page.dart b/lib/presentation/emergency_services/emergency_services_page.dart index 7970d819..801f6ca2 100644 --- a/lib/presentation/emergency_services/emergency_services_page.dart +++ b/lib/presentation/emergency_services/emergency_services_page.dart @@ -1,6 +1,8 @@ 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_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.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'; @@ -12,7 +14,9 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/emergency_services/RRT/rrt_request_type_select.dart'; import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/ambulance_option_selection_bottomsheet.dart'; import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/pickup_location.dart'; +import 'package:hmg_patient_app_new/presentation/emergency_services/er_online_checkin/er_online_checkin_home.dart'; import 'package:hmg_patient_app_new/presentation/emergency_services/history/er_history_listing.dart'; +import 'package:hmg_patient_app_new/presentation/home/service_info_page.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; @@ -22,23 +26,46 @@ import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:lottie/lottie.dart'; import 'package:provider/provider.dart'; -class EmergencyServicesPage extends StatelessWidget { +class EmergencyServicesPage extends StatefulWidget { EmergencyServicesPage({super.key}); + @override + State createState() => _EmergencyServicesPageState(); +} + +class _EmergencyServicesPageState extends State { late EmergencyServicesViewModel emergencyServicesViewModel; - _handleConfirmationBottomSheet() {} + late AppState appState; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (appState.isAuthenticated) { + emergencyServicesViewModel.flushData(); + emergencyServicesViewModel.getTransportationOrders( + showLoader: false, + ); + emergencyServicesViewModel.getRRTOrders( + showLoader: false, + ); + } + }); + } @override Widget build(BuildContext context) { emergencyServicesViewModel = Provider.of(context, listen: false); - + appState = getIt.get(); return CollapsingListView( title: LocaleKeys.emergencyServices.tr(), - history: () { - emergencyServicesViewModel.changeOrderDisplayItems(OrderDislpay.ALL); - Navigator.of(context).push(CustomPageRoute(page: ErHistoryListing(), direction: AxisDirection.up)); - }, + history: appState.isAuthenticated + ? () { + emergencyServicesViewModel.changeOrderDisplayItems(OrderDislpay.ALL); + Navigator.of(context).push(CustomPageRoute(page: ErHistoryListing(), direction: AxisDirection.up)); + } + : null, child: Padding( padding: EdgeInsets.all(24.h), child: Column( @@ -60,8 +87,7 @@ class EmergencyServicesPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.callAmbulance.tr().toText16(isBold: true, color: AppColors.blackColor), - LocaleKeys.requestAmbulanceInEmergency.tr() - .toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), + LocaleKeys.requestAmbulanceInEmergency.tr().toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), ], ), ), @@ -69,65 +95,75 @@ class EmergencyServicesPage extends StatelessWidget { Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, width: 13.h, height: 13.h), ], ).onPress(() { - showCommonBottomSheetWithoutHeight( - context, - child: Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.primaryRedColor, - borderRadius: 24.h, - ), - child: Padding( - padding: EdgeInsets.all(24.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - "".toText14(), - Utils.buildSvgWithAssets( - icon: AppAssets.cancel_circle_icon, - iconColor: Colors.white, - width: 24.h, - height: 24.h, - fit: BoxFit.contain, - ).onPress(() { + if(appState.isAuthenticated) { + showCommonBottomSheetWithoutHeight( + context, + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.primaryRedColor, + borderRadius: 24.h, + ), + child: Padding( + padding: EdgeInsets.all(24.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "".toText14(), + Utils.buildSvgWithAssets( + icon: AppAssets.cancel_circle_icon, + iconColor: Colors.white, + width: 24.h, + height: 24.h, + fit: BoxFit.contain, + ).onPress(() { + Navigator.of(context).pop(); + }), + ], + ), + Lottie.asset(AppAnimations.ambulanceAlert, repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain), + SizedBox(height: 8.h), + LocaleKeys.confirmation.tr().toText28(color: Colors.white, isBold: true), + SizedBox(height: 8.h), + LocaleKeys.areYouSureYouWantToCallAmbulance.tr().toText14(color: Colors.white, weight: FontWeight.w500), + SizedBox(height: 24.h), + CustomButton( + text: LocaleKeys.confirm.tr(context: context), + onPressed: () async { Navigator.of(context).pop(); - }), - ], - ), - Lottie.asset(AppAnimations.ambulanceAlert, - repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain), - SizedBox(height: 8.h), - LocaleKeys.confirmation.tr().toText28(color: Colors.white, isBold: true), - SizedBox(height: 8.h), - LocaleKeys.areYouSureYouWantToCallAmbulance.tr() - .toText14(color: Colors.white, weight: FontWeight.w500), - SizedBox(height: 24.h), - CustomButton( - text: LocaleKeys.confirm.tr(context: context), - onPressed: () async { - Navigator.of(context).pop(); - await emergencyServicesViewModel.getTransportationOption(); - openTranportationSelectionBottomSheet(context); - }, - backgroundColor: Colors.white, - borderColor: Colors.white, - textColor: AppColors.primaryRedColor, - icon: AppAssets.checkmark_icon, - iconColor: AppColors.primaryRedColor, - ), - SizedBox(height: 8.h), - ], + await emergencyServicesViewModel.getTransportationOption(); + openTranportationSelectionBottomSheet(context); + }, + backgroundColor: Colors.white, + borderColor: Colors.white, + textColor: AppColors.primaryRedColor, + icon: AppAssets.checkmark_icon, + iconColor: AppColors.primaryRedColor, + ), + SizedBox(height: 8.h), + ], + ), ), ), - ), - isFullScreen: false, - isCloseButtonVisible: false, - hasBottomPadding: false, - backgroundColor: AppColors.primaryRedColor, - callBackFunc: () {}, - ); + isFullScreen: false, + isCloseButtonVisible: false, + hasBottomPadding: false, + backgroundColor: AppColors.primaryRedColor, + callBackFunc: () {}, + ); + } else { + Navigator.of(context).push( + CustomPageRoute( + page: ServiceInfoPage( + serviceName: LocaleKeys.emergencyServices.tr(), + serviceHeader: "ER Check-in, Faster Than Ever. Call ambulance / Rapid Response Team instantly".needTranslation, + serviceDescription: "In a medical emergency? Our ambulances and rapid response teams are on standby 24/7. Plus, quick ER check-in for faster care.".needTranslation, + serviceImage: AppAssets.emergencyService), + ), + ); + } }), ), SizedBox(height: 16.h), @@ -147,8 +183,7 @@ class EmergencyServicesPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.nearester.tr(context: context).toText16(isBold: true, color: AppColors.blackColor), - LocaleKeys.getDetailsOfNearestBranch.tr() - .toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), + LocaleKeys.getDetailsOfNearestBranch.tr().toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), ], ), ), @@ -176,8 +211,7 @@ class EmergencyServicesPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.rapidResponseTeam.tr(context: context).toText16(isBold: true, color: AppColors.blackColor), - "Comprehensive medical service for all sorts of urgent and stable cases" - .toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), + "Comprehensive medical service for all sorts of urgent and stable cases".toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), ], ), ), @@ -185,77 +219,101 @@ class EmergencyServicesPage extends StatelessWidget { Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, width: 13.h, height: 13.h), ], ).onPress(() { - showCommonBottomSheetWithoutHeight( - context, - child: Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.primaryRedColor, - borderRadius: 24.h, - ), - child: Padding( - padding: EdgeInsets.all(24.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Lottie.asset(AppAnimations.ambulanceAlert, repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain), - SizedBox(height: 8.h), - LocaleKeys.confirm.tr().toText28(color: Colors.white, isBold: true), - SizedBox(height: 8.h), - LocaleKeys.areYouSureYouWantToCallRRT.tr() - .toText14(color: Colors.white, weight: FontWeight.w500), - SizedBox(height: 24.h), - CustomButton( - text: LocaleKeys.confirm.tr(context: context), - onPressed: () async { - Navigator.of(context).pop(); - - LoaderBottomSheet.showLoader(); - emergencyServicesViewModel.clearRRTData(); - await emergencyServicesViewModel.getRRTProcedures(onSuccess: (val) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - padding: EdgeInsets.only(top: 24.h), - titleWidget: Transform.flip( - flipX: emergencyServicesViewModel.isArabic, - child: Utils.buildSvgWithAssets( - icon: AppAssets.arrow_back, - iconColor: Color(0xff2B353E), - fit: BoxFit.contain, - ), - ).onPress(() { - - Navigator.pop(context); - }), - // title: "Rapid Response Team (RRT)".needTranslation, - context, - child: RrtRequestTypeSelect(), - isFullScreen: false, - isCloseButtonVisible: true, - hasBottomPadding: false, - backgroundColor: AppColors.bottomSheetBgColor, - callBackFunc: () {}, - ); - }); - }, - backgroundColor: Colors.white, - borderColor: Colors.white, - textColor: AppColors.primaryRedColor, - icon: AppAssets.checkmark_icon, - iconColor: AppColors.primaryRedColor, - ), - SizedBox(height: 8.h), - ], + if(appState.isAuthenticated) { + showCommonBottomSheetWithoutHeight( + context, + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.primaryRedColor, + borderRadius: 24.h, + ), + child: Padding( + padding: EdgeInsets.all(24.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "".toText14(), + Utils.buildSvgWithAssets( + icon: AppAssets.cancel_circle_icon, + iconColor: Colors.white, + width: 24.h, + height: 24.h, + fit: BoxFit.contain, + ).onPress(() { + Navigator.of(context).pop(); + }), + ], + ), + Lottie.asset(AppAnimations.ambulanceAlert, repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain), + SizedBox(height: 8.h), + LocaleKeys.confirm.tr().toText28(color: Colors.white, isBold: true), + SizedBox(height: 8.h), + LocaleKeys.areYouSureYouWantToCallRRT.tr().toText14(color: Colors.white, weight: FontWeight.w500), + SizedBox(height: 24.h), + CustomButton( + text: LocaleKeys.confirm.tr(context: context), + onPressed: () async { + Navigator.of(context).pop(); + LoaderBottomSheet.showLoader(); + emergencyServicesViewModel.clearRRTData(); + await emergencyServicesViewModel.getRRTProcedures(onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + padding: EdgeInsets.only(top: 24.h), + titleWidget: Transform.flip( + flipX: emergencyServicesViewModel.isArabic, + child: Utils.buildSvgWithAssets( + icon: AppAssets.arrow_back, + iconColor: Color(0xff2B353E), + fit: BoxFit.contain, + ), + ).onPress(() { + Navigator.pop(context); + }), + // title: "Rapid Response Team (RRT)".needTranslation, + context, + child: RrtRequestTypeSelect(), + isFullScreen: false, + isCloseButtonVisible: true, + hasBottomPadding: false, + backgroundColor: AppColors.bottomSheetBgColor, + callBackFunc: () {}, + ); + }); + }, + backgroundColor: Colors.white, + borderColor: Colors.white, + textColor: AppColors.primaryRedColor, + icon: AppAssets.checkmark_icon, + iconColor: AppColors.primaryRedColor, + ), + SizedBox(height: 8.h), + ], + ), ), ), - ), - isFullScreen: false, - isCloseButtonVisible: false, - hasBottomPadding: false, - backgroundColor: AppColors.primaryRedColor, - callBackFunc: () { - context.read().setTermsAndConditions(false); - }, - ); + isFullScreen: false, + isCloseButtonVisible: false, + hasBottomPadding: false, + backgroundColor: AppColors.primaryRedColor, + callBackFunc: () { + context.read().setTermsAndConditions(false); + }, + ); + } else { + Navigator.of(context).push( + CustomPageRoute( + page: ServiceInfoPage( + serviceName: LocaleKeys.emergencyServices.tr(), + serviceHeader: "ER Check-in, Faster Than Ever. Call ambulance / Rapid Response Team instantly".needTranslation, + serviceDescription: "In a medical emergency? Our ambulances and rapid response teams are on standby 24/7. Plus, quick ER check-in for faster care.".needTranslation, + serviceImage: AppAssets.emergencyService), + ), + ); + } }), ), SizedBox(height: 16.h), @@ -275,8 +333,7 @@ class EmergencyServicesPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.emergencyCheckIn.tr(context: context).toText16(isBold: true, color: AppColors.blackColor), - LocaleKeys.priorERCheckInToSkipLine.tr() - .toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), + LocaleKeys.priorERCheckInToSkipLine.tr().toText12(color: AppColors.greyTextColor, fontWeight: FontWeight.w500), ], ), ), @@ -284,64 +341,79 @@ class EmergencyServicesPage extends StatelessWidget { Utils.buildSvgWithAssets(icon: AppAssets.forward_chevron_icon, width: 13.h, height: 13.h), ], ).onPress(() { - showCommonBottomSheetWithoutHeight( - context, - child: Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.primaryRedColor, borderRadius: 24.h), - child: Padding( - padding: EdgeInsets.all(24.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + if(appState.isAuthenticated) { + if (emergencyServicesViewModel.patientHasAdvanceERBalance) { + Navigator.of(context).push(CustomPageRoute(page: ErOnlineCheckinHome())); + } else { + showCommonBottomSheetWithoutHeight( + context, + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.primaryRedColor, borderRadius: 24.h), + child: Padding( + padding: EdgeInsets.all(24.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - "".toText14(), - Utils.buildSvgWithAssets( - icon: AppAssets.cancel_circle_icon, - iconColor: AppColors.whiteColor, - width: 24.h, - height: 24.h, - fit: BoxFit.contain, - ).onPress(() { - Navigator.of(context).pop(); - }), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "".toText14(), + Utils.buildSvgWithAssets( + icon: AppAssets.cancel_circle_icon, + iconColor: AppColors.whiteColor, + width: 24.h, + height: 24.h, + fit: BoxFit.contain, + ).onPress(() { + Navigator.of(context).pop(); + }), + ], + ), + Lottie.asset(AppAnimations.ambulanceAlert, repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain), + SizedBox(height: 8.h), + LocaleKeys.confirm.tr().toText28(color: Colors.white, isBold: true), + SizedBox(height: 8.h), + LocaleKeys.areYouSureYouWantToMakeERCheckIn.tr().toText14(color: Colors.white, weight: FontWeight.w500), + SizedBox(height: 24.h), + CustomButton( + text: LocaleKeys.confirm.tr(context: context), + onPressed: () async { + Navigator.of(context).pop(); + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingYourERAppointmentStatus.tr()); + await context.read().checkPatientERAdvanceBalance(onSuccess: (dynamic response) { + LoaderBottomSheet.hideLoader(); + context.read().navigateToEROnlineCheckIn(); + }); + }, + backgroundColor: Colors.white, + borderColor: Colors.white, + textColor: AppColors.primaryRedColor, + icon: AppAssets.checkmark_icon, + iconColor: AppColors.primaryRedColor, + ), + SizedBox(height: 8.h), ], ), - Lottie.asset(AppAnimations.ambulanceAlert, - repeat: false, reverse: false, frameRate: FrameRate(60), width: 120.h, height: 120.h, fit: BoxFit.contain), - SizedBox(height: 8.h), - LocaleKeys.confirm.tr().toText28(color: Colors.white, isBold: true), - SizedBox(height: 8.h), - LocaleKeys.areYouSureYouWantToMakeERCheckIn.tr().toText14(color: Colors.white, weight: FontWeight.w500), - SizedBox(height: 24.h), - CustomButton( - text: LocaleKeys.confirm.tr(context: context), - onPressed: () async { - Navigator.of(context).pop(); - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingYourERAppointmentStatus.tr()); - await context.read().checkPatientERAdvanceBalance(onSuccess: (dynamic response) { - LoaderBottomSheet.hideLoader(); - context.read().navigateToEROnlineCheckIn(); - }); - }, - backgroundColor: Colors.white, - borderColor: Colors.white, - textColor: AppColors.primaryRedColor, - icon: AppAssets.checkmark_icon, - iconColor: AppColors.primaryRedColor, - ), - SizedBox(height: 8.h), - ], + ), ), + isFullScreen: false, + isCloseButtonVisible: false, + hasBottomPadding: false, + backgroundColor: AppColors.primaryRedColor, + callBackFunc: () {}, + ); + } + } else { + Navigator.of(context).push( + CustomPageRoute( + page: ServiceInfoPage( + serviceName: LocaleKeys.emergencyServices.tr(), + serviceHeader: "ER Check-in, Faster Than Ever. Call ambulance / Rapid Response Team instantly".needTranslation, + serviceDescription: "In a medical emergency? Our ambulances and rapid response teams are on standby 24/7. Plus, quick ER check-in for faster care.".needTranslation, + serviceImage: AppAssets.emergencyService), ), - ), - isFullScreen: false, - isCloseButtonVisible: false, - hasBottomPadding: false, - backgroundColor: AppColors.primaryRedColor, - callBackFunc: () {}, - ); + ); + } }), ), ], @@ -355,7 +427,7 @@ class EmergencyServicesPage extends StatelessWidget { onCloseClicked: () { context.read().flushPickupInformation(); }, - titleWidget: Transform.flip( + titleWidget: Transform.flip( flipX: emergencyServicesViewModel.isArabic, child: Utils.buildSvgWithAssets( icon: AppAssets.arrow_back, diff --git a/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_details_page.dart b/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_details_page.dart index 463121d9..eee31da7 100644 --- a/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_details_page.dart +++ b/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_details_page.dart @@ -128,7 +128,7 @@ class ErOnlineCheckinPaymentDetailsPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox( - width: 150.h, + width: 200.h, child: Utils.getPaymentMethods(), ), Row( diff --git a/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_page.dart b/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_page.dart index 8b9633c1..bc0e7344 100644 --- a/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_page.dart +++ b/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_page.dart @@ -468,12 +468,12 @@ class _ErOnlineCheckinPaymentPageState extends State context, child: Utils.getErrorWidget(loadingText: LocaleKeys.paymentFailedPleaseTryAgain.tr(context: context)), callBackFunc: () { - Navigator.pushAndRemoveUntil( - context, - CustomPageRoute( - page: LandingNavigation(), - ), - (r) => false); + // Navigator.pushAndRemoveUntil( + // context, + // CustomPageRoute( + // page: LandingNavigation(), + // ), + // (r) => false); }, isFullScreen: false, isCloseButtonVisible: true, diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index de3235aa..8310e6db 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -26,6 +26,7 @@ import 'package:hmg_patient_app_new/presentation/habib_wallet/habib_wallet_page. import 'package:hmg_patient_app_new/presentation/habib_wallet/recharge_wallet_page.dart'; import 'package:hmg_patient_app_new/presentation/hmg_services/services_view.dart'; import 'package:hmg_patient_app_new/presentation/home/data/landing_page_data.dart'; +import 'package:hmg_patient_app_new/presentation/home/service_info_page.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; import 'package:hmg_patient_app_new/presentation/parking/paking_page.dart'; @@ -54,23 +55,23 @@ class ServicesPage extends StatelessWidget { late final List hmgServices = [ HmgServicesComponentModel(11, LocaleKeys.emergencyServices.tr(), "", AppAssets.emergency_services_icon, bgColor: AppColors.primaryRedColor, true, route: null, onTap: () async { - if (getIt.get().isAuthenticated) { - getIt.get().flushData(); - getIt.get().getTransportationOrders( - showLoader: false, - ); - getIt.get().getRRTOrders( - showLoader: false, - ); + // if (getIt.get().isAuthenticated) { + // getIt.get().flushData(); + // getIt.get().getTransportationOrders( + // showLoader: false, + // ); + // getIt.get().getRRTOrders( + // showLoader: false, + // ); Navigator.of(getIt.get().navigatorKey.currentContext!).push( CustomPageRoute( page: EmergencyServicesPage(), settings: const RouteSettings(name: '/EmergencyServicesPage'), ), ); - } else { - await getIt.get().onLoginPressed(); - } + // } else { + // await getIt.get().onLoginPressed(); + // } }), HmgServicesComponentModel( 11, @@ -85,7 +86,15 @@ class ServicesPage extends StatelessWidget { if (getIt.get().isAuthenticated) { getIt.get().pushPageRoute(AppRoutes.comprehensiveCheckupPage); } else { - await getIt.get().onLoginPressed(); + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: ServiceInfoPage( + serviceName: LocaleKeys.comprehensiveMedicalCheckup.tr(), + serviceHeader: "Complete Health Checkup: Advanced diagnostics, Detailed Health insights".needTranslation, + serviceDescription: "Get detailed insights into your health with our advanced diagnostics. Understand your body better for a healthier future.".needTranslation, + serviceImage: AppAssets.cmcService), + ), + ); } }), HmgServicesComponentModel( @@ -137,7 +146,15 @@ class ServicesPage extends StatelessWidget { if (getIt.get().isAuthenticated) { getIt.get().pushPageRoute(AppRoutes.eReferralPage); } else { - await getIt.get().onLoginPressed(); + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: ServiceInfoPage( + serviceName: LocaleKeys.eReferralServices.tr(), + serviceHeader: "HMG Hospital E-Referral: Streamlined patient referrals".needTranslation, + serviceDescription: "Facilitate seamless patient transfers to HMG with our secure e-referral system. Ensure continuity of care for every patient.".needTranslation, + serviceImage: AppAssets.eReferralService), + ), + ); } }), HmgServicesComponentModel( @@ -147,7 +164,26 @@ class ServicesPage extends StatelessWidget { AppAssets.blood_donation_icon, bgColor: AppColors.bloodDonationCardColor, true, - route: AppRoutes.bloodDonationPage, + route: null, + onTap: () { + if (getIt.get().isAuthenticated) { + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: BloodDonationPage(), + ), + ); + } else { + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: ServiceInfoPage( + serviceName: LocaleKeys.bloodDonation.tr(), + serviceHeader: "Give Blood, Save Lives. Your donation makes a difference.".needTranslation, + serviceDescription: "Donate blood, empower lives. Your contribution creates hope. Join our blood drive and be a lifeline for those in need. Every drop counts!".needTranslation, + serviceImage: AppAssets.bloodDonationService), + ), + ); + } + } ), HmgServicesComponentModel( 113, @@ -230,7 +266,15 @@ class ServicesPage extends StatelessWidget { if (getIt.get().isAuthenticated) { getIt.get().pushPageRoute(AppRoutes.healthTrackersPage); } else { - await getIt.get().onLoginPressed(); + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: ServiceInfoPage( + serviceName: LocaleKeys.healthTrackers.tr(), + serviceHeader: "HMG Hospital E-Referral: Streamlined patient referrals".needTranslation, + serviceDescription: "Facilitate seamless patient transfers to HMG with our secure e-referral system. Ensure continuity of care for every patient.".needTranslation, + serviceImage: AppAssets.eReferralService), + ), + ); } }, ), @@ -263,7 +307,15 @@ class ServicesPage extends StatelessWidget { }, ); } else { - await getIt.get().onLoginPressed(); + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: ServiceInfoPage( + serviceName: LocaleKeys.waterConsumption.tr(), + serviceHeader: "Stay Hydrated, Stay Healthy. Track your daily water intake with ease.".needTranslation, + serviceDescription: "Quench your thirst, track your health. Effortlessly monitor your daily water intake with our user-friendly app, ensuring optimal hydration and well-being.".needTranslation, + serviceImage: AppAssets.waterConsumptionService), + ), + ); } }, ), @@ -294,8 +346,21 @@ class ServicesPage extends StatelessWidget { true, route: null, onTap: () async { - // if (getIt.get().isAuthenticated) { + if (getIt.get().isAuthenticated) { getIt.get().pushPageRoute(AppRoutes.smartWatches); + } else { + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: ServiceInfoPage( + serviceName: LocaleKeys.smartWatches.tr(), + serviceHeader: "HMG Hospital E-Referral: Streamlined patient referrals".needTranslation, + serviceDescription: "Facilitate seamless patient transfers to HMG with our secure e-referral system. Ensure continuity of care for every patient.".needTranslation, + serviceImage: AppAssets.eReferralService), + ), + ); + } + // if (getIt.get().isAuthenticated) { + // getIt.get().pushPageRoute(AppRoutes.smartWatches); // } else { // await getIt.get().onLoginPressed(); // } @@ -368,168 +433,172 @@ class ServicesPage extends StatelessWidget { ), ), SizedBox(height: 24.h), - LocaleKeys.personalServices.tr().toText18(weight: FontWeight.w600).paddingSymmetrical(24.w, 0), - SizedBox(height: 16.h), - Row( + getIt.get().isAuthenticated ? Column( children: [ - Expanded( - child: Container( - height: 183.h, - width: 183.h, - padding: EdgeInsets.all(16.w), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.r, - hasShadow: false, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - spacing: 8.w, - crossAxisAlignment: CrossAxisAlignment.center, + LocaleKeys.personalServices.tr().toText18(weight: FontWeight.w600).paddingSymmetrical(24.w, 0), + SizedBox(height: 16.h), + Row( + children: [ + Expanded( + child: Container( + height: 183.h, + width: 183.h, + padding: EdgeInsets.all(16.w), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.r, + hasShadow: false, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.wallet, width: 40.w, height: 40.h, applyThemeColor: false), - LocaleKeys.habibWallet.tr().toText14(weight: FontWeight.w600, maxlines: 2).expanded, - Utils.buildSvgWithAssets(icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward), + Row( + spacing: 8.w, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.wallet, width: 40.w, height: 40.h, applyThemeColor: false), + LocaleKeys.habibWallet.tr().toText14(weight: FontWeight.w600, maxlines: 2).expanded, + Utils.buildSvgWithAssets(icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward), + ], + ), + Spacer(), + getIt.get().isAuthenticated + ? Consumer(builder: (context, habibWalletVM, child) { + return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, isExpanded: false) + .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.r, width: 80.w, height: 24.h); + }) + : LocaleKeys.loginToViewWalletBalance.tr().toText12(fontWeight: FontWeight.w500, maxLine: 2), + Spacer(), + getIt.get().isAuthenticated + ? CustomButton( + height: 40.h, + icon: AppAssets.recharge_icon, + iconSize: 24.w, + iconColor: AppColors.infoColor, + textColor: AppColors.infoColor, + text: LocaleKeys.recharge.tr(), + borderWidth: 0.w, + fontWeight: FontWeight.w500, + borderColor: Colors.transparent, + backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), + padding: EdgeInsets.all(8.w), + fontSize: 14.f, + onPressed: () { + Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); + }, + ) + : SizedBox.shrink(), ], - ), - Spacer(), - getIt.get().isAuthenticated - ? Consumer(builder: (context, habibWalletVM, child) { - return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, isExpanded: false) - .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.r, width: 80.w, height: 24.h); - }) - : LocaleKeys.loginToViewWalletBalance.tr().toText12(fontWeight: FontWeight.w500, maxLine: 2), - Spacer(), - getIt.get().isAuthenticated - ? CustomButton( - height: 40.h, - icon: AppAssets.recharge_icon, - iconSize: 24.w, - iconColor: AppColors.infoColor, - textColor: AppColors.infoColor, - text: LocaleKeys.recharge.tr(), - borderWidth: 0.w, - fontWeight: FontWeight.w500, - borderColor: Colors.transparent, - backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), - padding: EdgeInsets.all(8.w), - fontSize: 14.f, - onPressed: () { - Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); - }, - ) - : SizedBox.shrink(), - ], - ).onPress(() async { - if (getIt.get().isAuthenticated) { - Navigator.of(context).push(CustomPageRoute(page: HabibWalletPage())); - } else { - await getIt.get().onLoginPressed(); - } - }), - ), - ), - SizedBox(width: 16.w), - Expanded( - child: Container( - height: 183.h, - width: 183.h, - padding: EdgeInsets.all(16.w), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.r, - hasShadow: false, + ).onPress(() async { + if (getIt.get().isAuthenticated) { + Navigator.of(context).push(CustomPageRoute(page: HabibWalletPage())); + } else { + await getIt.get().onLoginPressed(); + } + }), + ), ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - spacing: 8.w, - crossAxisAlignment: CrossAxisAlignment.center, + SizedBox(width: 16.w), + Expanded( + child: Container( + height: 183.h, + width: 183.h, + padding: EdgeInsets.all(16.w), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.r, + hasShadow: false, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Utils.buildSvgWithAssets(icon: AppAssets.services_medical_file_icon, width: 40.w, height: 40.h, applyThemeColor: false), - LocaleKeys.medicalFile.tr().toText16(weight: FontWeight.w600, maxlines: 2).expanded, - Utils.buildSvgWithAssets(icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward), + Row( + spacing: 8.w, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.services_medical_file_icon, width: 40.w, height: 40.h, applyThemeColor: false), + LocaleKeys.medicalFile.tr().toText16(weight: FontWeight.w600, maxlines: 2).expanded, + Utils.buildSvgWithAssets(icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward), + ], + ), + Spacer(), + getIt.get().isAuthenticated + ? Wrap( + spacing: -12.h, + // runSpacing: 0.h, + children: [ + Utils.buildImgWithAssets( + icon: AppAssets.babyGirlImg, + height: 32.h, + width: 32.w, + border: 1, + fit: BoxFit.contain, + borderRadius: 50.r, + ), + Utils.buildImgWithAssets( + icon: AppAssets.femaleImg, + height: 32.h, + width: 32.w, + border: 1, + borderRadius: 50.r, + fit: BoxFit.contain, + ), + Utils.buildImgWithAssets( + icon: AppAssets.maleImg, + height: 32.h, + width: 32.w, + border: 1, + borderRadius: 50.r, + fit: BoxFit.contain, + ), + ], + ) + : LocaleKeys.loginToViewMedicalFile.tr().toText12(fontWeight: FontWeight.w500, maxLine: 2), + Spacer(), + getIt.get().isAuthenticated + ? CustomButton( + height: 40.h, + icon: AppAssets.add_icon, + iconSize: 24.h, + iconColor: AppColors.primaryRedColor, + textColor: AppColors.primaryRedColor, + text: LocaleKeys.addMember.tr(), + borderWidth: 0.w, + fontWeight: FontWeight.w500, + borderColor: Colors.transparent, + backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08), + padding: EdgeInsets.all(8.w), + fontSize: 14.f, + onPressed: () { + DialogService dialogService = getIt.get(); + medicalFileViewModel.clearAuthValues(); + dialogService.showAddFamilyFileSheet( + label: LocaleKeys.addFamilyMember.tr(), + message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(), + onVerificationPress: () { + medicalFileViewModel.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); + }); + }, + ) + : SizedBox.shrink(), ], - ), - Spacer(), - getIt.get().isAuthenticated - ? Wrap( - spacing: -12.h, - // runSpacing: 0.h, - children: [ - Utils.buildImgWithAssets( - icon: AppAssets.babyGirlImg, - height: 32.h, - width: 32.w, - border: 1, - fit: BoxFit.contain, - borderRadius: 50.r, - ), - Utils.buildImgWithAssets( - icon: AppAssets.femaleImg, - height: 32.h, - width: 32.w, - border: 1, - borderRadius: 50.r, - fit: BoxFit.contain, - ), - Utils.buildImgWithAssets( - icon: AppAssets.maleImg, - height: 32.h, - width: 32.w, - border: 1, - borderRadius: 50.r, - fit: BoxFit.contain, - ), - ], - ) - : LocaleKeys.loginToViewMedicalFile.tr().toText12(fontWeight: FontWeight.w500, maxLine: 2), - Spacer(), - getIt.get().isAuthenticated - ? CustomButton( - height: 40.h, - icon: AppAssets.add_icon, - iconSize: 24.h, - iconColor: AppColors.primaryRedColor, - textColor: AppColors.primaryRedColor, - text: LocaleKeys.addMember.tr(), - borderWidth: 0.w, - fontWeight: FontWeight.w500, - borderColor: Colors.transparent, - backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08), - padding: EdgeInsets.all(8.w), - fontSize: 14.f, - onPressed: () { - DialogService dialogService = getIt.get(); - medicalFileViewModel.clearAuthValues(); - dialogService.showAddFamilyFileSheet( - label: LocaleKeys.addFamilyMember.tr(), - message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(), - onVerificationPress: () { - medicalFileViewModel.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); - }); - }, - ) - : SizedBox.shrink(), - ], - ).onPress(() async { - if (getIt.get().isAuthenticated) { - Navigator.of(context).push( - CustomPageRoute( - page: MedicalFilePage(), - ), - ); - } else { - await getIt.get().onLoginPressed(); - } - }), - ), - ), + ).onPress(() async { + if (getIt.get().isAuthenticated) { + Navigator.of(context).push( + CustomPageRoute( + page: MedicalFilePage(), + ), + ); + } else { + await getIt.get().onLoginPressed(); + } + }), + ), + ), + ], + ).paddingSymmetrical(24.w, 0), ], - ).paddingSymmetrical(24.w, 0), + ) : SizedBox(), SizedBox(height: 24.h), LocaleKeys.healthTools.tr().toText18(weight: FontWeight.w600).paddingSymmetrical(24.w, 0), SizedBox(height: 16.h), diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 14684c0c..3109443f 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -349,7 +349,7 @@ class _LandingPageState extends State { ).paddingSymmetrical(24.w, 0.h) : SizedBox.shrink(), appState.isAuthenticated - ? Column( + ? Column( children: [ SizedBox(height: 12.h), Row( @@ -498,67 +498,67 @@ class _LandingPageState extends State { ), // Consumer for ER Online Check-In pending request - Consumer( - builder: (context, emergencyServicesVM, child) { - return emergencyServicesVM.patientHasAdvanceERBalance - ? Column( - children: [ - SizedBox(height: 16.h), - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.r, - hasShadow: false, - side: BorderSide(color: AppColors.primaryRedColor, width: 3.h), - ), - width: double.infinity, - child: Padding( - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // AppCustomChipWidget( - // labelText: LocaleKeys.erOnlineCheckInRequest.tr(context: context), - // backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.10), - // textColor: AppColors.primaryRedColor, - // ), - // Utils.buildSvgWithAssets(icon: AppAssets.appointment_checkin_icon, width: 24.h, height: 24.h, iconColor: AppColors.primaryRedColor), - // ], - // ), - SizedBox(height: 8.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.youHaveEROnlineCheckInRequest.tr(context: context).toText12(isBold: true), - Transform.flip( - flipX: getIt.get().isArabic(), - child: Utils.buildSvgWithAssets( - icon: AppAssets.forward_arrow_icon_small, - iconColor: AppColors.blackColor, - width: 20.h, - height: 15.h, - fit: BoxFit.contain, - ), - ), - ], - ), - ], - ), - ), - ).paddingSymmetrical(24.h, 0.h).onPress(() { - Navigator.of(context).push(CustomPageRoute(page: ErOnlineCheckinHome())); - // context.read().navigateToEROnlineCheckIn(); - }), - SizedBox(height: 12.h), - ], - ) - : SizedBox(height: 0.h); - }, - ), - SizedBox(height: 16.h), + // Consumer( + // builder: (context, emergencyServicesVM, child) { + // return emergencyServicesVM.patientHasAdvanceERBalance + // ? Column( + // children: [ + // SizedBox(height: 16.h), + // Container( + // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + // color: AppColors.whiteColor, + // borderRadius: 20.r, + // hasShadow: false, + // side: BorderSide(color: AppColors.primaryRedColor, width: 3.h), + // ), + // width: double.infinity, + // child: Padding( + // padding: EdgeInsets.all(16.h), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // // Row( + // // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // // children: [ + // // AppCustomChipWidget( + // // labelText: LocaleKeys.erOnlineCheckInRequest.tr(context: context), + // // backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.10), + // // textColor: AppColors.primaryRedColor, + // // ), + // // Utils.buildSvgWithAssets(icon: AppAssets.appointment_checkin_icon, width: 24.h, height: 24.h, iconColor: AppColors.primaryRedColor), + // // ], + // // ), + // SizedBox(height: 8.h), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // LocaleKeys.youHaveEROnlineCheckInRequest.tr(context: context).toText12(isBold: true), + // Transform.flip( + // flipX: getIt.get().isArabic(), + // child: Utils.buildSvgWithAssets( + // icon: AppAssets.forward_arrow_icon_small, + // iconColor: AppColors.blackColor, + // width: 20.h, + // height: 15.h, + // fit: BoxFit.contain, + // ), + // ), + // ], + // ), + // ], + // ), + // ), + // ).paddingSymmetrical(24.h, 0.h).onPress(() { + // Navigator.of(context).push(CustomPageRoute(page: ErOnlineCheckinHome())); + // // context.read().navigateToEROnlineCheckIn(); + // }), + // SizedBox(height: 12.h), + // ], + // ) + // : SizedBox(height: 0.h); + // }, + // ), + SizedBox(height: 16.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -575,66 +575,61 @@ class _LandingPageState extends State { Navigator.of(context).push(CustomPageRoute(page: MedicalFilePage())); }), SizedBox(height: 16.h), - Container( - // height: 121.h, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), - child: Column( - children: [ - SizedBox( - height: 92.h + 32.h - 4.h, - child: RawScrollbar( - controller: _horizontalScrollController, - thumbVisibility: true, - radius: Radius.circular(10.0), - thumbColor: AppColors.primaryRedColor, - trackVisibility: true, - trackColor: Color(0xffD9D9D9), - trackBorderColor: Colors.transparent, - trackRadius: Radius.circular(10.0), - padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery - .sizeOf(context) - .width / 2 - 35, right: MediaQuery - .sizeOf(context) - .width / 2 - 35), - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: LandingPageData.getLoggedInServiceCardsList.length, - shrinkWrap: true, - controller: _horizontalScrollController, - padding: EdgeInsets.only(left: 16.h, right: 16.h, top: 16.h, bottom: 12.h), - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: SmallServiceCard( - icon: LandingPageData.getLoggedInServiceCardsList[index].icon, - title: LandingPageData.getLoggedInServiceCardsList[index].title, - subtitle: LandingPageData.getLoggedInServiceCardsList[index].subtitle, - iconColor: LandingPageData.getLoggedInServiceCardsList[index].iconColor!, - textColor: LandingPageData.getLoggedInServiceCardsList[index].textColor, - backgroundColor: LandingPageData.getLoggedInServiceCardsList[index].backgroundColor, - isBold: LandingPageData.getLoggedInServiceCardsList[index].isBold, - serviceName: LandingPageData.getLoggedInServiceCardsList[index].serviceName, + Container( + // height: 121.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), + child: Column( + children: [ + SizedBox( + height: 92.h + 32.h - 4.h, + child: RawScrollbar( + controller: _horizontalScrollController, + thumbVisibility: true, + radius: Radius.circular(10.0), + thumbColor: AppColors.primaryRedColor, + trackVisibility: true, + trackColor: Color(0xffD9D9D9), + trackBorderColor: Colors.transparent, + trackRadius: Radius.circular(10.0), + padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery.sizeOf(context).width / 2.5 - 10, right: MediaQuery.sizeOf(context).width / 2.5 - 10), + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: LandingPageData.getLoggedInServiceCardsList.length, + shrinkWrap: true, + controller: _horizontalScrollController, + padding: EdgeInsets.only(left: 0.h, right: 0.h, top: 16.h, bottom: 12.h), + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: SmallServiceCard( + icon: LandingPageData.getLoggedInServiceCardsList[index].icon, + title: LandingPageData.getLoggedInServiceCardsList[index].title, + subtitle: LandingPageData.getLoggedInServiceCardsList[index].subtitle, + iconColor: LandingPageData.getLoggedInServiceCardsList[index].iconColor!, + textColor: LandingPageData.getLoggedInServiceCardsList[index].textColor, + backgroundColor: LandingPageData.getLoggedInServiceCardsList[index].backgroundColor, + isBold: LandingPageData.getLoggedInServiceCardsList[index].isBold, + serviceName: LandingPageData.getLoggedInServiceCardsList[index].serviceName, + ), + ), + ), + ); + }, + separatorBuilder: (BuildContext cxt, int index) => 10.width, + ).paddingSymmetrical(16.h, 0.h), ), ), - ), - ); - }, - separatorBuilder: (BuildContext cxt, int index) => 10.width, - ), - ), - ), - SizedBox(height: 16.h), - ], - ), - ).paddingSymmetrical(24.h, 0.h), - ], - ) - : Container( - // height: 141.h, + SizedBox(height: 16.h), + ], + ), + ).paddingSymmetrical(24.h, 0.h), + ], + ) + : Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), child: Column( children: [ @@ -649,14 +644,13 @@ class _LandingPageState extends State { trackColor: Color(0xffD9D9D9), trackBorderColor: Colors.transparent, trackRadius: Radius.circular(10.0), - padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery.sizeOf(context).width / 2 - 35, right: MediaQuery.sizeOf(context).width / 2 - 35), + padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery.sizeOf(context).width / 2.5 - 10, right: MediaQuery.sizeOf(context).width / 2.5 - 10), child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: LandingPageData.getNotLoggedInServiceCardsList.length, shrinkWrap: true, controller: _horizontalScrollController, - padding: EdgeInsets.only(left: 16.h, right: 16.h, top: 16.h, bottom: 12.h), - // padding: EdgeInsets.zero, + padding: EdgeInsets.only(left: 0.h, right: 0.h, top: 16.h, bottom: 12.h), itemBuilder: (context, index) { return AnimationConfiguration.staggeredList( position: index, @@ -679,7 +673,7 @@ class _LandingPageState extends State { ); }, separatorBuilder: (BuildContext cxt, int index) => 0.width, - ), + ).paddingSymmetrical(16.h, 0.h), ), ), SizedBox(height: 16.h), diff --git a/lib/presentation/home/service_info_page.dart b/lib/presentation/home/service_info_page.dart new file mode 100644 index 00000000..5d07593d --- /dev/null +++ b/lib/presentation/home/service_info_page.dart @@ -0,0 +1,74 @@ +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_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.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/authentication/authentication_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; + +class ServiceInfoPage extends StatelessWidget { + final String serviceName; + final String serviceHeader; + final String serviceDescription; + final String serviceImage; + + const ServiceInfoPage({required this.serviceName, required this.serviceHeader, required this.serviceDescription, required this.serviceImage, super.key}); + + @override + Widget build(BuildContext context) { + return CollapsingListView( + title: "", + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppCustomChipWidget( + richText: serviceName.toText14(color: AppColors.infoColor, weight: FontWeight.w500), + backgroundColor: AppColors.infoColor.withAlpha(50), + textColor: AppColors.infoColor, + ).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 24.h), + serviceHeader.toText28(isBold: true, height: 1.4).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 24.h), + serviceDescription.toText14(weight: FontWeight.w500, color: AppColors.greyTextColor).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 24.h), + CustomButton( + text: LocaleKeys.login.tr(context: context), + onPressed: () { + getIt().onLoginPressed(); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 16.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + padding: EdgeInsets.symmetric(horizontal: 10.w), + height: 40.h, + icon: AppAssets.login1, + iconColor: AppColors.primaryRedColor, + iconSize: 18.h, + ).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 36.h), + ClipRRect( + borderRadius: BorderRadius.circular(24.r), + child: Transform.flip( + flipX: getIt.get().isArabic(), + child: Image.asset( + serviceImage, + fit: BoxFit.fitHeight, + width: 520.w, + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/home/widgets/habib_wallet_card.dart b/lib/presentation/home/widgets/habib_wallet_card.dart index 0ac32443..19c03284 100644 --- a/lib/presentation/home/widgets/habib_wallet_card.dart +++ b/lib/presentation/home/widgets/habib_wallet_card.dart @@ -115,7 +115,7 @@ class HabibWalletCard extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox( - width: 150.h, + width: 200.h, child: Utils.getPaymentMethods(), ), CustomButton( diff --git a/lib/presentation/home/widgets/large_service_card.dart b/lib/presentation/home/widgets/large_service_card.dart index b89e58c5..f0145afa 100644 --- a/lib/presentation/home/widgets/large_service_card.dart +++ b/lib/presentation/home/widgets/large_service_card.dart @@ -1,6 +1,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; +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/utils/size_utils.dart'; @@ -10,6 +11,7 @@ import 'package:hmg_patient_app_new/features/book_appointments/book_appointments import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart'; import 'package:hmg_patient_app_new/presentation/home/data/service_card_data.dart'; +import 'package:hmg_patient_app_new/presentation/home/service_info_page.dart'; import 'package:hmg_patient_app_new/presentation/home_health_care/hhc_procedures_page.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; @@ -135,11 +137,23 @@ class LargeServiceCard extends StatelessWidget { } case "home_health_care": { - Navigator.of(getIt().navigatorKey.currentContext!).push( - CustomPageRoute( - page: HhcProceduresPage(), - ), - ); + if (getIt.get().isAuthenticated) { + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: HhcProceduresPage(), + ), + ); + } else { + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: ServiceInfoPage( + serviceName: LocaleKeys.homeHealthCare.tr(), + serviceHeader: "Your Health, Elevated. Premium care, delivered to your doorstep.", + serviceDescription: "We bring quality healthcare to your doorstep. Experienced nurses providing compassionate care in the comfort of your home.", + serviceImage: AppAssets.homeHealthCareService), + ), + ); + } } case "pharmacy": { @@ -270,11 +284,23 @@ class FadedLargeServiceCard extends StatelessWidget { } case "home_health_care": { - Navigator.of(getIt().navigatorKey.currentContext!).push( - CustomPageRoute( - page: HhcProceduresPage(), - ), - ); + if (getIt.get().isAuthenticated) { + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: HhcProceduresPage(), + ), + ); + } else { + Navigator.of(getIt().navigatorKey.currentContext!).push( + CustomPageRoute( + page: ServiceInfoPage( + serviceName: LocaleKeys.homeHealthCare.tr(), + serviceHeader: "Your Health, Elevated. Premium care, delivered to your doorstep.".needTranslation, + serviceDescription: "We bring quality healthcare to your doorstep. Experienced nurses providing compassionate care in the comfort of your home.".needTranslation, + serviceImage: AppAssets.homeHealthCareService), + ), + ); + } } case "pharmacy": { diff --git a/lib/presentation/home/widgets/welcome_widget.dart b/lib/presentation/home/widgets/welcome_widget.dart index 9b613e64..beff2ae4 100644 --- a/lib/presentation/home/widgets/welcome_widget.dart +++ b/lib/presentation/home/widgets/welcome_widget.dart @@ -7,6 +7,7 @@ import 'package:hmg_patient_app_new/core/utils/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/insurance/insurance_view_model.dart'; +import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart'; import 'package:hmg_patient_app_new/presentation/profile_settings/profile_settings.dart'; @@ -40,6 +41,7 @@ class WelcomeWidget extends StatelessWidget { spacing: 8.h, children: [ Icon(Icons.menu, color: AppColors.textColor).onPress(() { + getIt.get().getProfileSettings(); Navigator.of(context).push(springPageRoute(ProfileSettings())); }), Image.asset(imageUrl, width: 40, height: 40), diff --git a/lib/presentation/insurance/widgets/patient_insurance_card.dart b/lib/presentation/insurance/widgets/patient_insurance_card.dart index 1607a7c6..ab70eb6f 100644 --- a/lib/presentation/insurance/widgets/patient_insurance_card.dart +++ b/lib/presentation/insurance/widgets/patient_insurance_card.dart @@ -136,7 +136,7 @@ class PatientInsuranceCard extends StatelessWidget { insuranceCardDetailsModel.groupName!.toText12(isBold: true), Row( children: [ - insuranceCardDetailsModel.companyName!.toText12(isBold: true), + (insuranceCardDetailsModel.companyName!.length > 40 ? "${insuranceCardDetailsModel.companyName!.substring(0, 40)}..." : insuranceCardDetailsModel.companyName!).toText12(isBold: true), SizedBox( width: 6.h, ), @@ -146,7 +146,7 @@ class PatientInsuranceCard extends StatelessWidget { color: AppColors.infoColor, borderRadius: 50.r, ), - child: (insuranceCardDetailsModel.subCategoryDesc!.length > 5 ? insuranceCardDetailsModel.subCategoryDesc!.substring(0, 12) : insuranceCardDetailsModel.subCategoryDesc!) + child: ((insuranceCardDetailsModel.subCategoryDesc ?? "").length > 10 ? (insuranceCardDetailsModel.subCategoryDesc ?? "").substring(0, 10) : (insuranceCardDetailsModel.subCategoryDesc ?? "")) .toText8(isBold: true, color: AppColors.whiteColor), ), ], diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index cddc4757..3e440723 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -473,8 +473,7 @@ class _MedicalFilePageState extends State { ], ); }), - SizedBox(height: 16.h), - + SizedBox(height: 24.h), // TextInputWidget( // labelText: LocaleKeys.search.tr(context: context), // hintText: "Type any record".needTranslation, @@ -489,7 +488,7 @@ class _MedicalFilePageState extends State { // leadingIcon: AppAssets.search_icon, // hintColor: AppColors.textColor, // ).paddingSymmetrical(24.w, 0.0), - SizedBox(height: 16.h), + // SizedBox(height: 16.h), // Using CustomExpandableList CustomExpandableList( expansionMode: ExpansionMode.exactlyOne, @@ -1538,6 +1537,7 @@ class _MedicalFilePageState extends State { value: vitalSign.bodyMassIndex?.toString() ?? '--', unit: '', status: vitalSign.bodyMassIndex != null ? _getBMIStatus(vitalSign.bodyMassIndex) : null, + // status: "Overweight", onTap: onTap, ), ), diff --git a/lib/presentation/my_invoices/my_invoices_details_page.dart b/lib/presentation/my_invoices/my_invoices_details_page.dart index 79e1adc3..0410d311 100644 --- a/lib/presentation/my_invoices/my_invoices_details_page.dart +++ b/lib/presentation/my_invoices/my_invoices_details_page.dart @@ -6,6 +6,7 @@ import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/date_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/int_extensions.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/my_invoices/models/get_invoice_details_response_model.dart'; @@ -183,48 +184,6 @@ class _MyInvoicesDetailsPageState extends State { ), ), SizedBox(height: 16.h), - Row( - mainAxisSize: MainAxisSize.max, - children: [ - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.h, - hasShadow: true, - ), - child: Padding( - padding: EdgeInsets.all(14.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - widget.getInvoiceDetailsResponseModel.listConsultation!.first.procedureName!.toText16(isBold: true), - SizedBox(height: 16.h), - Wrap( - direction: Axis.horizontal, - spacing: 6.w, - runSpacing: 6.h, - children: [ - AppCustomChipWidget( - labelText: "${LocaleKeys.quantity.tr()}: ${widget.getInvoiceDetailsResponseModel.listConsultation!.first.quantity!}", - labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), - ), - AppCustomChipWidget( - labelText: "${LocaleKeys.price.tr()}: ${widget.getInvoiceDetailsResponseModel.listConsultation!.first.price!} ${LocaleKeys.sar.tr()}", - labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), - ), - AppCustomChipWidget( - labelText: "${LocaleKeys.total.tr()}: ${widget.getInvoiceDetailsResponseModel.listConsultation!.first.total!} ${LocaleKeys.sar.tr()}", - labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), - ), - ], - ), - ], - ), - ), - ), - ], - ), - SizedBox(height: 16.h), Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, @@ -257,6 +216,57 @@ class _MyInvoicesDetailsPageState extends State { ), ), ), + SizedBox(height: 16.h), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: true, + ), + child: Padding( + padding: EdgeInsets.all(14.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Header row + Row( + children: [ + Expanded(flex: 3, child: LocaleKeys.name.tr().toText12(color: AppColors.textColor, fontWeight: FontWeight.w600)), + Expanded(flex: 1, child: LocaleKeys.quantity.tr().toText12(color: AppColors.textColor, fontWeight: FontWeight.w600, isCenter: true)), + Expanded( + flex: 2, child: LocaleKeys.price.tr().toText12(color: AppColors.textColor, fontWeight: FontWeight.w600, isCenter: true)), + Expanded( + flex: 2, child: LocaleKeys.total.tr().toText12(color: AppColors.textColor, fontWeight: FontWeight.w600, isCenter: true)), + ], + ), + SizedBox(height: 16.h), + 2.divider, + SizedBox(height: 12.h), + // Data rows + ...widget.getInvoiceDetailsResponseModel.listConsultation!.map( + (consultation) => Padding( + padding: EdgeInsets.symmetric(vertical: 6.h), + child: Row( + children: [ + Expanded(flex: 3, child: (consultation.procedureName ?? '-').toText12(fontWeight: FontWeight.w500)), + Expanded(flex: 1, child: '${consultation.quantity ?? '-'}'.toText12(fontWeight: FontWeight.w500, isCenter: true)), + Expanded(flex: 2, child: '${consultation.price ?? '-'}'.toText12(fontWeight: FontWeight.w500, isCenter: true)), + Expanded(flex: 2, child: '${consultation.total ?? '-'}'.toText12(fontWeight: FontWeight.w500, isCenter: true)), + ], + ), + ), + ), + ], + ), + ), + ), + ), + ], + ), ], ), ), diff --git a/lib/presentation/prescriptions/prescription_item_view.dart b/lib/presentation/prescriptions/prescription_item_view.dart index 1c145115..13ddebf1 100644 --- a/lib/presentation/prescriptions/prescription_item_view.dart +++ b/lib/presentation/prescriptions/prescription_item_view.dart @@ -207,7 +207,7 @@ class PrescriptionItemView extends StatelessWidget { initialHour: DateTime.now().hour, initialMinute: DateTime.now().minute, use24HourFormat: true, - pickerHeight: 120.h, + pickerHeight: 200.h, itemExtent: 100.h, onTimeChanged: (time) { // Handle selected time diff --git a/lib/presentation/prescriptions/prescription_reminder_view.dart b/lib/presentation/prescriptions/prescription_reminder_view.dart index aab587d4..d1dcd07a 100644 --- a/lib/presentation/prescriptions/prescription_reminder_view.dart +++ b/lib/presentation/prescriptions/prescription_reminder_view.dart @@ -20,7 +20,7 @@ class PrescriptionReminderView extends StatefulWidget { } class _PrescriptionReminderViewState extends State { - final List _options = [15, 30, 60, 90]; + final List _options = [60, 360, 720, 1440]; int _selectedOption = 0; // Nullable to represent no selection initially @override @@ -54,7 +54,7 @@ class _PrescriptionReminderViewState extends State { ), child: RadioListTile( title: Text( - "${_options[index]} ${LocaleKeys.minute.tr(context: context)}", + "${(_options[index] / 60).toInt()} ${LocaleKeys.hours.tr(context: context)}", style: TextStyle( fontSize: 16.h, fontWeight: FontWeight.w500, diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart index 1a10e0de..fd88c049 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -28,6 +28,7 @@ import 'package:hmg_patient_app_new/presentation/habib_wallet/habib_wallet_page. import 'package:hmg_patient_app_new/presentation/habib_wallet/recharge_wallet_page.dart'; import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_update_details_card.dart'; import 'package:hmg_patient_app_new/presentation/profile_settings/widgets/update_email_widget.dart'; +import 'package:hmg_patient_app_new/presentation/profile_settings/widgets/update_emergency_contact_widget.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/app_language_change.dart'; @@ -39,6 +40,7 @@ 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 'package:url_launcher/url_launcher.dart'; +import 'package:in_app_review/in_app_review.dart'; class ProfileSettings extends StatefulWidget { const ProfileSettings({super.key}); @@ -48,6 +50,9 @@ class ProfileSettings extends StatefulWidget { } class ProfileSettingsState extends State { + + final InAppReview inAppReview = InAppReview.instance; + @override void initState() { scheduleMicrotask(() { @@ -242,49 +247,47 @@ class ProfileSettingsState extends State { ], ), ), - // Container( - // margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h), - // padding: EdgeInsets.only(top: 4.h, bottom: 4.h), - // decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), - // child: Column( - // children: [ - // actionItem(AppAssets.language_change, LocaleKeys.language.tr(context: context), () { - // showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.language.tr(context: context), child: AppLanguageChange(), callBackFunc: () {}, isFullScreen: false); - // }, trailingLabel: Utils.appState.isArabic() ? "العربية" : "English"), - // 1.divider, - // actionItem(AppAssets.bell, LocaleKeys.notificationsSettings.tr(context: context), () { - // openAppSettings(); - // }), - // // 1.divider, - // // actionItem(AppAssets.touch_face_id, LocaleKeys.touchIDFaceIDServices.tr(context: context), () {}, switchValue: true), - // ], - // ), - // ), - // LocaleKeys.personalInformation.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w), - // Container( - // margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h), - // padding: EdgeInsets.only(top: 4.h, bottom: 4.h), - // decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), - // child: Column( - // children: [ - // actionItem(AppAssets.email_transparent, LocaleKeys.updateEmailAddress.tr(context: context), () { - // showCommonBottomSheetWithoutHeight( - // context, - // title: LocaleKeys.updateEmailAddress.tr(context: context), - // child: UpdateEmailDialog(), - // callBackFunc: () {}, - // isFullScreen: false, - // ); - // }), - // // 1.divider, - // // actionItem(AppAssets.smart_phone_fill, "Phone Number".needTranslation, () {}), - // // 1.divider, - // // actionItem(AppAssets.my_address, "My Addresses".needTranslation, () {}), - // // 1.divider, - // // actionItem(AppAssets.emergency, "Emergency Contact".needTranslation, () {}), - // ], - // ), - // ), + LocaleKeys.personalInformation.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w), + Container( + margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h), + padding: EdgeInsets.only(top: 4.h, bottom: 4.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), + child: Column( + children: [ + actionItem(AppAssets.email_transparent, LocaleKeys.updateEmailAddress.tr(context: context), () { + showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.updateEmailAddress.tr(context: context), + child: UpdateEmailDialog(), + callBackFunc: () {}, + isFullScreen: false, + ); + }), + 1.divider, + actionItem(AppAssets.language, LocaleKeys.communicationLanguage.tr(context: context), () { + profileVm.openPreferredLanguageBottomSheet(); + }, + trailingLabel: profileVm.isPatientProfileLoading + ? "English" + : (profileVm.getPatientInfoForUpdate.preferredLanguage! == "1" ? LocaleKeys.arabic.tr(context: context) : LocaleKeys.english.tr(context: context)), + isShowLoading: profileVm.isPatientProfileLoading), + 1.divider, + actionItem(AppAssets.smart_phone_fill, LocaleKeys.emrgNo.tr(context: context), () { + showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.emrgNo.tr(context: context), + child: UpdateEmergencyContactDialog(), + callBackFunc: () {}, + isFullScreen: false, + ); + }), + // 1.divider, + // actionItem(AppAssets.my_address, "My Addresses".needTranslation, () {}), + // 1.divider, + // actionItem(AppAssets.emergency, "Emergency Contact".needTranslation, () {}), + ], + ), + ), LocaleKeys.helpAndSupport.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w), Container( margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h), @@ -314,17 +317,23 @@ class ProfileSettingsState extends State { 1.divider, // actionItem(AppAssets.permission, LocaleKeys.permissions.tr(context: context), () {}, trailingLabel: "Location, Camera"), // 1.divider, - actionItem(AppAssets.rate, LocaleKeys.rateApp.tr(context: context), () { - if (Platform.isAndroid) { - Utils.openWebView( - url: 'https://play.google.com/store/apps/details?id=com.ejada.hmg', - ); + actionItem(AppAssets.rate, LocaleKeys.rateApp.tr(context: context), () async { + if (await inAppReview.isAvailable()) { + inAppReview.requestReview(); } else { - Utils.openWebView( - url: 'https://itunes.apple.com/app/id733503978', - ); + inAppReview.openStoreListing(appStoreId: '6758851027'); } - }, isExternalLink: true), + // if (Platform.isAndroid) { + // Utils.openWebView( + // url: 'https://play.google.com/store/apps/details?id=com.ejada.hmg', + // ); + // } else { + // Utils.openWebView( + // url: 'https://itunes.apple.com/app/id733503978', + // ); + // } + // }, isExternalLink: true), + }), 1.divider, actionItem(AppAssets.privacy_terms, LocaleKeys.privacyPolicy.tr(context: context), () { Utils.openWebView( @@ -340,12 +349,12 @@ class ProfileSettingsState extends State { ], ), ), - CustomButton( - height: 56.h, - icon: AppAssets.minus, - text: LocaleKeys.deactivateAccount.tr(context: context), - onPressed: () {}, - ).paddingAll(24.w), + // CustomButton( + // height: 56.h, + // icon: AppAssets.minus, + // text: LocaleKeys.deactivateAccount.tr(context: context), + // onPressed: () {}, + // ).paddingAll(24.w), ], ); }, @@ -382,7 +391,8 @@ class ProfileSettingsState extends State { return _permissionsLabel; } - Widget actionItem(String icon, String label, VoidCallback onPress, {String trailingLabel = "", bool? switchValue, ValueChanged? onSwitchChanged, bool isExternalLink = false}) { + Widget actionItem(String icon, String label, VoidCallback onPress, + {String trailingLabel = "", bool? switchValue, ValueChanged? onSwitchChanged, bool isExternalLink = false, bool isShowLoading = false}) { return SizedBox( height: 56.h, child: Row( @@ -390,7 +400,11 @@ class ProfileSettingsState extends State { children: [ Utils.buildSvgWithAssets(icon: icon, iconColor: AppColors.greyTextColor), label.toText14(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1).expanded, - if (trailingLabel.isNotEmpty) trailingLabel.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1), + if (trailingLabel.isNotEmpty) + ConstrainedBox( + constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.35), + child: trailingLabel.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1).toShimmer2(isShow: isShowLoading), + ), switchValue != null ? Switch( value: switchValue, diff --git a/lib/presentation/profile_settings/widgets/preferred_language_widget.dart b/lib/presentation/profile_settings/widgets/preferred_language_widget.dart new file mode 100644 index 00000000..dcd30360 --- /dev/null +++ b/lib/presentation/profile_settings/widgets/preferred_language_widget.dart @@ -0,0 +1,116 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.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/int_extensions.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/profile_settings/profile_settings_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; +import 'package:provider/provider.dart'; + +class PreferredLanguageWidget extends StatefulWidget { + PreferredLanguageWidget({super.key}); + + @override + State createState() => _PreferredLanguageWidgetState(); +} + +class _PreferredLanguageWidgetState extends State { + String? selectedValue; + late ProfileSettingsViewModel profileSettingsViewModel; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + setState(() { + selectedValue = profileSettingsViewModel.getPatientInfoForUpdate.preferredLanguage!; + }); + }); + } + + @override + Widget build(BuildContext context) { + profileSettingsViewModel = Provider.of(context, listen: false); + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 24.h, + children: [ + LocaleKeys.communicationLanguage.tr(context: context).toText14(), + Container( + padding: EdgeInsets.only(top: 4, bottom: 4), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), + child: Column( + children: [ + languageItem("English", "2"), + 1.divider, + languageItem("العربية", "1"), + ], + ), + ), + CustomButton( + text: LocaleKeys.save.tr(context: context), + onPressed: () { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.loadingText.tr(context: context)); + profileSettingsViewModel!.updatePatientInfo( + patientInfo: { + "PreferredLanguage": selectedValue, + "EmailAddress": profileSettingsViewModel.getPatientInfoForUpdate.emailAddress, + "EmergencyContactName": profileSettingsViewModel.getPatientInfoForUpdate.emergencyContactName, + "EmergencyContactNo": profileSettingsViewModel.getPatientInfoForUpdate.emergencyContactNo, + "IsEmailAlertRequired": true, + "IsSMSAlertRequired": true, + }, + onSuccess: (response) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.success.tr(context: context), child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr()), + callBackFunc: () async { + Navigator.of(context).pop(); + profileSettingsViewModel.getProfileSettings(); + }, isFullScreen: false); + }, + onError: (error) { + LoaderBottomSheet.hideLoader(); + // Show error message + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(error)), + ); + }, + ); + }), + ], + ); + } + + Widget languageItem(String title, String _value) { + return SizedBox( + height: 72, + child: Row( + spacing: 8.h, + children: [ + Radio( + value: _value, + groupValue: selectedValue, + activeColor: AppColors.errorColor, + onChanged: (value) { + setState(() { + selectedValue = _value; + }); + }, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), + title.toText16(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1, fontFamily: _value == "1" ? 'GESSTwo' : 'Poppins').expanded, + ], + ).paddingOnly(left: 16, right: 16).onPress(() { + setState(() { + selectedValue = _value; + }); + }), + ); + } +} diff --git a/lib/presentation/profile_settings/widgets/update_email_widget.dart b/lib/presentation/profile_settings/widgets/update_email_widget.dart index ad9b9d5a..cb844bcb 100644 --- a/lib/presentation/profile_settings/widgets/update_email_widget.dart +++ b/lib/presentation/profile_settings/widgets/update_email_widget.dart @@ -31,7 +31,11 @@ class _UpdateEmailDialogState extends State { void initState() { _textFieldFocusNode = FocusNode(); textController = TextEditingController(); - textController!.text = getIt.get().getAuthenticatedUser()!.emailAddress ?? ""; + WidgetsBinding.instance.addPostFrameCallback((_) { + setState(() { + textController!.text = profileSettingsViewModel!.getPatientInfoForUpdate.emailAddress ?? ""; + }); + }); super.initState(); } @@ -52,7 +56,7 @@ class _UpdateEmailDialogState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Enter the new email address to be updated in your HMG File: ".toText16(textAlign: TextAlign.start, weight: FontWeight.w500), + "Enter the new email address to be updated: ".toText16(textAlign: TextAlign.start, weight: FontWeight.w500), SizedBox(height: 12.h), TextInputWidget( labelText: LocaleKeys.email.tr(), @@ -78,12 +82,20 @@ class _UpdateEmailDialogState extends State { onPressed: () { LoaderBottomSheet.showLoader(loadingText: LocaleKeys.updatingEmailAddress.tr(context: context)); profileSettingsViewModel!.updatePatientInfo( - patientInfo: {"EmailAddress": textController!.text}, + patientInfo: { + "PreferredLanguage": profileSettingsViewModel!.getPatientInfoForUpdate.preferredLanguage, + "EmailAddress": textController!.text, + "EmergencyContactName": profileSettingsViewModel!.getPatientInfoForUpdate.emergencyContactName, + "EmergencyContactNo": profileSettingsViewModel!.getPatientInfoForUpdate.emergencyContactNo, + "IsEmailAlertRequired": true, + "IsSMSAlertRequired": true, + }, onSuccess: (response) { LoaderBottomSheet.hideLoader(); showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.success.tr(context: context), child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr()), callBackFunc: () async { Navigator.of(context).pop(); + profileSettingsViewModel!.getProfileSettings(); }, isFullScreen: false); }, onError: (error) { diff --git a/lib/presentation/profile_settings/widgets/update_emergency_contact_widget.dart b/lib/presentation/profile_settings/widgets/update_emergency_contact_widget.dart new file mode 100644 index 00000000..f725bba1 --- /dev/null +++ b/lib/presentation/profile_settings/widgets/update_emergency_contact_widget.dart @@ -0,0 +1,118 @@ +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_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.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'; +import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import 'package:hmg_patient_app_new/widgets/input_widget.dart'; +import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; +import 'package:provider/provider.dart'; + +class UpdateEmergencyContactDialog extends StatefulWidget { + UpdateEmergencyContactDialog({super.key}); + + @override + State createState() => _UpdateEmergencyContactDialogState(); +} + +class _UpdateEmergencyContactDialogState extends State { + late FocusNode _textFieldFocusNode; + late TextEditingController? textController; + ProfileSettingsViewModel? profileSettingsViewModel; + + @override + void initState() { + _textFieldFocusNode = FocusNode(); + textController = TextEditingController(); + WidgetsBinding.instance.addPostFrameCallback((_) { + setState(() { + textController!.text = profileSettingsViewModel!.getPatientInfoForUpdate.emergencyContactNo!; + }); + }); + super.initState(); + } + + @override + void dispose() { + _textFieldFocusNode.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + profileSettingsViewModel = Provider.of(context); + return GestureDetector( + onTap: () { + _textFieldFocusNode.unfocus(); + FocusScope.of(context).unfocus(); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Enter the new emergency contact number to be updated: ".toText16(textAlign: TextAlign.start, weight: FontWeight.w500), + SizedBox(height: 12.h), + TextInputWidget( + labelText: LocaleKeys.emrgNo.tr(), + hintText: "05xxxxxxxx", + controller: textController, + focusNode: _textFieldFocusNode, + autoFocus: true, + padding: EdgeInsets.all(8.h), + keyboardType: TextInputType.number, + isEnable: true, + isReadOnly: false, + prefix: null, + isBorderAllowed: false, + isAllowLeadingIcon: true, + fontSize: 14.f, + isCountryDropDown: false, + leadingIcon: AppAssets.call_fill, + fontFamily: "Poppins", + ), + SizedBox(height: 12.h), + CustomButton( + text: LocaleKeys.submit.tr(context: context), + onPressed: () { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.loadingText.tr(context: context)); + profileSettingsViewModel!.updatePatientInfo( + patientInfo: { + "PreferredLanguage": profileSettingsViewModel!.getPatientInfoForUpdate.preferredLanguage, + "EmailAddress": profileSettingsViewModel!.getPatientInfoForUpdate.emailAddress, + "EmergencyContactName": profileSettingsViewModel!.getPatientInfoForUpdate.emergencyContactName, + "EmergencyContactNo": textController!.text, + "IsEmailAlertRequired": true, + "IsSMSAlertRequired": true, + }, + onSuccess: (response) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.success.tr(context: context), child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr()), + callBackFunc: () async { + Navigator.of(context).pop(); + profileSettingsViewModel!.getProfileSettings(); + }, isFullScreen: false); + }, + onError: (error) { + LoaderBottomSheet.hideLoader(); + // Show error message + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(error)), + ); + }, + ); + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: const Color(0xFFffffff), + ), + ], + ), + ); + } +} 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(); + } } diff --git a/lib/presentation/todo_section/ancillary_procedures_details_page.dart b/lib/presentation/todo_section/ancillary_procedures_details_page.dart index 38d4f978..ef1aba72 100644 --- a/lib/presentation/todo_section/ancillary_procedures_details_page.dart +++ b/lib/presentation/todo_section/ancillary_procedures_details_page.dart @@ -640,7 +640,7 @@ class _AncillaryOrderDetailsListState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox( - width: 150.h, + width: 200.h, child: Utils.getPaymentMethods(), ), Row( diff --git a/lib/presentation/vital_sign/vital_sign_page.dart b/lib/presentation/vital_sign/vital_sign_page.dart index 200a223e..82c64686 100644 --- a/lib/presentation/vital_sign/vital_sign_page.dart +++ b/lib/presentation/vital_sign/vital_sign_page.dart @@ -69,16 +69,16 @@ class _VitalSignPageState extends State { : null; // Debug logging for blood pressure - if (latestVitalSign != null) { - print('=== Blood Pressure Debug ==='); - print('bloodPressureHigher: ${latestVitalSign.bloodPressureHigher}'); - print('bloodPressureLower: ${latestVitalSign.bloodPressureLower}'); - print('bloodPressureHigher type: ${latestVitalSign.bloodPressureHigher.runtimeType}'); - print('bloodPressureLower type: ${latestVitalSign.bloodPressureLower.runtimeType}'); - print('bloodPressureHigher == 0: ${latestVitalSign.bloodPressureHigher == 0}'); - print('bloodPressureLower == 0: ${latestVitalSign.bloodPressureLower == 0}'); - print('========================'); - } + // if (latestVitalSign != null) { + // print('=== Blood Pressure Debug ==='); + // print('bloodPressureHigher: ${latestVitalSign.bloodPressureHigher}'); + // print('bloodPressureLower: ${latestVitalSign.bloodPressureLower}'); + // print('bloodPressureHigher type: ${latestVitalSign.bloodPressureHigher.runtimeType}'); + // print('bloodPressureLower type: ${latestVitalSign.bloodPressureLower.runtimeType}'); + // print('bloodPressureHigher == 0: ${latestVitalSign.bloodPressureHigher == 0}'); + // print('bloodPressureLower == 0: ${latestVitalSign.bloodPressureLower == 0}'); + // print('========================'); + // } return SingleChildScrollView( child: Column( diff --git a/lib/widgets/scroll_wheel_time_picker.dart b/lib/widgets/scroll_wheel_time_picker.dart index a6e155bb..e1a35d6f 100644 --- a/lib/widgets/scroll_wheel_time_picker.dart +++ b/lib/widgets/scroll_wheel_time_picker.dart @@ -115,18 +115,21 @@ class _ScrollWheelTimePickerState extends State { widget.use24HourFormat ? index : index + 1; final isSelected = hour == _selectedHour; return Visibility( - visible: isSelected, - child: Center( - child: AnimatedDefaultTextStyle( + visible: true, + child: Center( + child: AnimatedDefaultTextStyle( duration: const Duration(milliseconds: 200), style: digitStyle.copyWith( color: isSelected ? AppColors.textColor : AppColors.textColor.withValues(alpha: 0.3), ), - child: Text(hour.toString().padLeft(2, '0')), + child: Text( + hour.toString().padLeft(2, '0'), + ), + ), ), - )); + ); }, ), ), @@ -157,8 +160,8 @@ class _ScrollWheelTimePickerState extends State { builder: (context, index) { final isSelected = index == _selectedMinute; return Visibility( - visible: isSelected, - child: + visible: true, + child: Center( child: AnimatedDefaultTextStyle( duration: const Duration(milliseconds: 200), diff --git a/pubspec.yaml b/pubspec.yaml index b476f050..3b112673 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,8 +2,8 @@ name: hmg_patient_app_new description: "New HMG Patient App" publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 0.0.15+12 -#version: 0.0.1+14 +#version: 0.0.15+12 +version: 0.0.1+16 environment: sdk: ">=3.6.0 <4.0.0" @@ -99,6 +99,8 @@ dependencies: scrollable_positioned_list: ^0.3.8 + in_app_review: ^2.0.11 + dev_dependencies: flutter_test: sdk: flutter