Merge branch 'master' into haroon_dev

haroon_dev
haroon amjad 17 hours ago
commit 9adac10d39

@ -219,7 +219,7 @@
"unit": "الوحدة", "unit": "الوحدة",
"request": "الطلبات", "request": "الطلبات",
"memberName": "اسم العضو", "memberName": "اسم العضو",
"switchLogin": "عرض", "switchLogin": "عرض الملف",
"removeMember": "إزالة", "removeMember": "إزالة",
"allowView": "السماح", "allowView": "السماح",
"rejectView": "رفض", "rejectView": "رفض",
@ -1349,7 +1349,7 @@
"monthlyHealthSummaryReportDisclaimer": "يعكس تقرير الملخص الصحي الشهري هذا المؤشرات الصحية ونتائج التحليل لأحدث الزيارات. يرجى ملاحظة أن هذا سيتم إرساله تلقائيًا من النظام ولا يعتبر تقريرًا رسميًا لذا لا ينبغي اتخاذ أي قرار طبي بناءً عليه", "monthlyHealthSummaryReportDisclaimer": "يعكس تقرير الملخص الصحي الشهري هذا المؤشرات الصحية ونتائج التحليل لأحدث الزيارات. يرجى ملاحظة أن هذا سيتم إرساله تلقائيًا من النظام ولا يعتبر تقريرًا رسميًا لذا لا ينبغي اتخاذ أي قرار طبي بناءً عليه",
"updatingMonthlyReportStatus": "جاري تحديث حالة التقرير الشهري...", "updatingMonthlyReportStatus": "جاري تحديث حالة التقرير الشهري...",
"monthlyReportStatusUpdatedSuccessfully": "تم تحديث حالة التقرير الشهري بنجاح", "monthlyReportStatusUpdatedSuccessfully": "تم تحديث حالة التقرير الشهري بنجاح",
"whoCanViewMyMedicalFile": "من يمكنه عرض ملفي الطبي؟", "whoCanViewMyMedicalFile": "من يمكنه الاطلاع على ملفي الطبي",
"acceptedYourRequestToBeYourFamilyMember": "{status} طلب الانضمام الى أفراد عائلتك", "acceptedYourRequestToBeYourFamilyMember": "{status} طلب الانضمام الى أفراد عائلتك",
"canViewYourFile": "يمكنه عرض ملفك", "canViewYourFile": "يمكنه عرض ملفك",
"hasARequestPendingToBeYourFamilyMember": "لديه طلب {status} ليكون فردًا من عائلتك", "hasARequestPendingToBeYourFamilyMember": "لديه طلب {status} ليكون فردًا من عائلتك",
@ -1360,7 +1360,7 @@
"selectAProfile": "الرجاء تحديد ملف تعريف", "selectAProfile": "الرجاء تحديد ملف تعريف",
"switchFamilyFile": "قم بالتبديل من قائمة الملفات الطبية أدناه", "switchFamilyFile": "قم بالتبديل من قائمة الملفات الطبية أدناه",
"medicalFiles": "الملفات الطبية", "medicalFiles": "الملفات الطبية",
"addANewFamilyMember": "إضافة فرد جديد", "addANewFamilyMember": "اضافة",
"viewInvoiceDetails": "عرض تفاصيل الفاتورة", "viewInvoiceDetails": "عرض تفاصيل الفاتورة",
"outPatient": "مريض خارجي", "outPatient": "مريض خارجي",
"invoiceDetails": "تفاصيل الفاتورة", "invoiceDetails": "تفاصيل الفاتورة",
@ -1664,6 +1664,7 @@
"sortByLocation": "الترتيب حسب الموقع", "sortByLocation": "الترتيب حسب الموقع",
"timeForFirstReminder": "اضافةتذكير", "timeForFirstReminder": "اضافةتذكير",
"reminderRemovalNote": "يمكنك إلغاء التذكير لاحقاً من التقويم.", "reminderRemovalNote": "يمكنك إلغاء التذكير لاحقاً من التقويم.",
"prescriptionDatePassedError": "تاريخ الوصفة الطبية قد انتهى. لا يمكنك إضافة تذكير لهذه الوصفة.",
"communicationLanguage": "لغة التواصل", "communicationLanguage": "لغة التواصل",
"cmcServiceHeader": "فحص صحي شامل: تشخيص متقدم، معلومات صحية مفصلة", "cmcServiceHeader": "فحص صحي شامل: تشخيص متقدم، معلومات صحية مفصلة",
"cmcServiceDescription": "احصل على معلومات تفصيلية عن صحتك من خلال خدمات التشخيص المتقدمة لدينا. افهم جسمك بشكل أفضل لمستقبل صحي.", "cmcServiceDescription": "احصل على معلومات تفصيلية عن صحتك من خلال خدمات التشخيص المتقدمة لدينا. افهم جسمك بشكل أفضل لمستقبل صحي.",
@ -1702,7 +1703,7 @@
"doctorRemovedFromFavourite": "تمت إزالة من قائمة الأطباء المفضلين", "doctorRemovedFromFavourite": "تمت إزالة من قائمة الأطباء المفضلين",
"addNewFavorite": "إضافة مفضلة جديدة", "addNewFavorite": "إضافة مفضلة جديدة",
"favourites": "المفضلة", "favourites": "المفضلة",
"pendingAncillaryOrders": "مدفوعات طلبات الاضافية", "pendingAncillaryOrders": "طلبات غير مكتمله",
"liveCarePermissions": "يتطلب لايف كير أذونات الكاميرا والميكروفون وإشعارات، يرجى السماح لها بالمتابعة.", "liveCarePermissions": "يتطلب لايف كير أذونات الكاميرا والميكروفون وإشعارات، يرجى السماح لها بالمتابعة.",
"containsImage": "يحتوي على صورة", "containsImage": "يحتوي على صورة",
"servicesSelected": "الخدمة / الخدمات", "servicesSelected": "الخدمة / الخدمات",
@ -1810,5 +1811,18 @@
"watchUsOnYoutube": "شاهدنا على إنستغرام", "watchUsOnYoutube": "شاهدنا على إنستغرام",
"connectOnLinkedin": "تواصل معنا على لينكد إن", "connectOnLinkedin": "تواصل معنا على لينكد إن",
"riskFactorPageTitle": "اعراض تشعر بها", "riskFactorPageTitle": "اعراض تشعر بها",
"symptomsCheckSuggestions": "الاحتمالات" "bloodDonationService": "التبرع \n بالدم",
"bookAppointmentService": "حجز\nموعد",
"pinchToZoom": "اضغط للتكبير",
"gotIt": "فهمت",
"zoomIntoDetails": "قم بالتكبير لرؤية التفاصيل",
"pinchWithTwoFingersToZoom": "اضغط بإصبعين للتكبير",
"dragToMoveAround": "اسحب للتحرك",
"startExploring": "ابدأ الاستكشاف",
"symptomsCheckSuggestions": "الاحتمالات",
"appointmentArrived": "تم الحضور",
"calendarPermissionAlertForAppointment": "يرجى منح إذن الوصول إلى التقويم من إعدادات التطبيق لضبط تذكير الموعد",
"rechargePageKey": "اختر المستفيد",
"selectFamilyFile": "اختيار ",
"ancillaryOrdersListNew": "طلبات غير مكتملة"
} }

@ -1652,6 +1652,7 @@
"calendarPermissionAlert": "Please grant calendar access permission from app settings to set medication reminder.", "calendarPermissionAlert": "Please grant calendar access permission from app settings to set medication reminder.",
"timeForFirstReminder": "Add Reminder", "timeForFirstReminder": "Add 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",
"prescriptionDatePassedError": "Prescription date has already passed. You cannot add a reminder for this prescription.",
"sortByLocation": "Sort by location", "sortByLocation": "Sort by location",
"sortByNearestLocation": "Sort by nearest to your location", "sortByNearestLocation": "Sort by nearest to your location",
"giveLocationPermissionForNearestList": "Please grant location permission from app settings to see the nearest locations.", "giveLocationPermissionForNearestList": "Please grant location permission from app settings to see the nearest locations.",
@ -1800,7 +1801,20 @@
"watchUsOnYoutube": "Watch us on Instagram", "watchUsOnYoutube": "Watch us on Instagram",
"connectOnLinkedin": "Connect on LinkedIn", "connectOnLinkedin": "Connect on LinkedIn",
"riskFactorPageTitle": "What do you feel?", "riskFactorPageTitle": "What do you feel?",
"symptomsCheckSuggestions": "Suggestions" "bloodDonationService": "Blood Donation",
"bookAppointmentService": "Book\nAppointment",
"pinchToZoom": "Pinch to zoom",
"gotIt": "Got it",
"zoomIntoDetails": "Zoom into details",
"pinchWithTwoFingersToZoom": "Pinch with two fingers to zoom",
"dragToMoveAround": "Drag to move around",
"startExploring": "Start exploring",
"symptomsCheckSuggestions": "Suggestions",
"appointmentArrived": "Arrived",
"calendarPermissionAlertForAppointment": "Please grant calendar access permission from app settings to set appointment reminder.",
"rechargePageKey": "Recharge Wallet",
"selectFamilyFile": "Select",
"ancillaryOrdersListNew": "Ancillary Orders List"
} }

@ -80,4 +80,5 @@ class CacheConst {
static const String zoomRoomID = 'zoom-room-id'; static const String zoomRoomID = 'zoom-room-id';
static const String callTypeID = 'call-type-id'; static const String callTypeID = 'call-type-id';
static String isAppOpenedFromCall = "is_app_opened_from_call"; static String isAppOpenedFromCall = "is_app_opened_from_call";
static const String organSelectorTutorialShown = 'organ_selector_tutorial_shown';
} }

@ -126,8 +126,7 @@ class CalenderUtilsNew {
String? prescriptionNumber, String? prescriptionNumber,
DateTime? scheduleDateTime, DateTime? scheduleDateTime,
}) async { }) async {
DateTime currentDay = DateTime.now(); DateTime startTimeOfDay = scheduleDateTime ?? DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 8, 0);
DateTime actualDate = scheduleDateTime ?? DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 8, 0);
print("the frequency is $frequencyNumber"); print("the frequency is $frequencyNumber");
frequencyNumber ??= 2; //Some time frequency number is null so by default will be 2 frequencyNumber ??= 2; //Some time frequency number is null so by default will be 2
int interval = calculateIntervalAsPerFrequency(frequencyNumber); int interval = calculateIntervalAsPerFrequency(frequencyNumber);
@ -139,28 +138,29 @@ class CalenderUtilsNew {
// Validate that prescription is still active // Validate that prescription is still active
if (remainingDays <= 0) { if (remainingDays <= 0) {
onFailure?.call("Prescription date has already passed. You cannot add a reminder for this prescription."); onFailure?.call(LocaleKeys.prescriptionDatePassedError.tr());
return false; return false;
} }
bool statusOfOperation = false; bool statusOfOperation = false;
for (int i = 0; i < remainingDays; i++) { for (int i = 0; i < remainingDays; i++) {
//event for number of days. // Reset to the original time for each new day
DateTime actualDate = startTimeOfDay.add(Duration(days: i));
//event for number of days (frequency per day)
for (int j = 0; j < frequencyNumber; j++) { for (int j = 0; j < frequencyNumber; j++) {
statusOfOperation = await createOrUpdateEvent( statusOfOperation = await createOrUpdateEvent(
title: "$itemDescriptionN} Medication about to due for prescription , #$prescriptionNumber", title: "$itemDescriptionN Medication about to due for prescription, #$prescriptionNumber",
description: "$itemDescriptionN $frequencyNumber $route ", description: "$itemDescriptionN $frequencyNumber $route ",
scheduleDateTime: actualDate, scheduleDateTime: actualDate,
location: '', location: '',
//event id with varitions //event id with variations
reminderMinutes: reminderMinutes); reminderMinutes: reminderMinutes);
if (!statusOfOperation) return false; if (!statusOfOperation) return false;
actualDate = actualDate.add(Duration(hours: interval)); actualDate = actualDate.add(Duration(hours: interval));
// if (actualDate.difference(currentDay).inDays == 1) break;
} }
actualDate = actualDate.add(Duration(days: 1));
} }
return statusOfOperation; return statusOfOperation;
@ -178,7 +178,10 @@ class CalenderUtilsNew {
} }
FutureOr<bool> checkIfEventExist(String admissionId) async { FutureOr<bool> checkIfEventExist(String admissionId) async {
// await ensureCalendarsLoaded();
if (writableCalender.isEmpty) {
await ensureCalendarsLoaded(); await ensureCalendarsLoaded();
}
List<Event> events = await getEvents(); List<Event> events = await getEvents();
if (events.isEmpty) return false; if (events.isEmpty) return false;
for (var event in events) { for (var event in events) {

@ -231,30 +231,31 @@ class BloodDonationViewModel extends ChangeNotifier {
} }
Future<bool> validateSelections() async { Future<bool> validateSelections() async {
AppState appState = getIt<AppState>();
if (selectedCity == null) { if (selectedCity == null) {
await dialogService.showErrorBottomSheet( await dialogService.showErrorBottomSheet(
message: "Please choose city", message: appState.isArabic() ? "اختر المدينة" :"Please choose city",
); );
return false; return false;
} }
if (selectedGender == null) { if (selectedGender == null) {
await dialogService.showErrorBottomSheet( await dialogService.showErrorBottomSheet(
message: "Please choose Gender", message: appState.isArabic() ? "اختير الجنس" :"Please choose Gender",
); );
return false; return false;
} }
if (selectedBloodType == null) { if (selectedBloodType == null) {
await dialogService.showErrorBottomSheet( await dialogService.showErrorBottomSheet(
message: "Please choose Blood Group", message: appState.isArabic() ? "اختير فصيلة الدم" :"Please choose Blood Group",
); );
return false; return false;
} }
if (!isTermsAccepted) { if (!isTermsAccepted) {
await dialogService.showErrorBottomSheet( await dialogService.showErrorBottomSheet(
message: "Please accept Terms and Conditions to continue", message:appState.isArabic() ? "يرجى الموافقة على الشروط والأحكام للمتابعة" : "Please accept Terms and Conditions to continue",
); );
return false; return false;
} }

@ -37,7 +37,7 @@ class AppointmentType {
case 42: case 42:
return LocaleKeys.confirmed.tr(); return LocaleKeys.confirmed.tr();
case 43: case 43:
return LocaleKeys.arrived.tr(); return LocaleKeys.appointmentArrived.tr();
default: default:
return LocaleKeys.booked.tr(); return LocaleKeys.booked.tr();
} }

@ -74,7 +74,7 @@ class PrescriptionsViewModel extends ChangeNotifier {
Future<bool> checkIfReminderExistForPrescription(int index) async { Future<bool> checkIfReminderExistForPrescription(int index) async {
prescriptionDetailsList[index].hasReminder = await CalenderUtilsNew.instance.checkIfEventExist(prescriptionDetailsList[index].itemID?.toString() ?? ""); prescriptionDetailsList[index].hasReminder = await CalenderUtilsNew.instance.checkIfEventExist(prescriptionDetailsList[index].itemID?.toString() ?? "");
notifyListeners(); // notifyListeners();
return prescriptionDetailsList[index].hasReminder ?? false; return prescriptionDetailsList[index].hasReminder ?? false;
} }
@ -226,7 +226,11 @@ class PrescriptionsViewModel extends ChangeNotifier {
} }
showError(String errorMessage) { showError(String errorMessage) {
getIt<NavigationService>().pop();
Future.delayed(Duration(milliseconds: 500), (){
getIt<DialogService>().showErrorBottomSheet(message: errorMessage); getIt<DialogService>().showErrorBottomSheet(message: errorMessage);
});
} }
Future<void> submitPrescriptionDeliveryRequest( Future<void> submitPrescriptionDeliveryRequest(

@ -1658,6 +1658,7 @@ abstract class LocaleKeys {
static const sortByLocation = 'sortByLocation'; static const sortByLocation = 'sortByLocation';
static const timeForFirstReminder = 'timeForFirstReminder'; static const timeForFirstReminder = 'timeForFirstReminder';
static const reminderRemovalNote = 'reminderRemovalNote'; static const reminderRemovalNote = 'reminderRemovalNote';
static const prescriptionDatePassedError = 'prescriptionDatePassedError';
static const communicationLanguage = 'communicationLanguage'; static const communicationLanguage = 'communicationLanguage';
static const cmcServiceHeader = 'cmcServiceHeader'; static const cmcServiceHeader = 'cmcServiceHeader';
static const cmcServiceDescription = 'cmcServiceDescription'; static const cmcServiceDescription = 'cmcServiceDescription';
@ -1803,5 +1804,10 @@ abstract class LocaleKeys {
static const connectOnLinkedin = 'connectOnLinkedin'; static const connectOnLinkedin = 'connectOnLinkedin';
static const riskFactorPageTitle = 'riskFactorPageTitle'; static const riskFactorPageTitle = 'riskFactorPageTitle';
static const symptomsCheckSuggestions = 'symptomsCheckSuggestions'; static const symptomsCheckSuggestions = 'symptomsCheckSuggestions';
static const appointmentArrived = 'appointmentArrived';
static const calendarPermissionAlertForAppointment = 'calendarPermissionAlertForAppointment';
static const rechargePageKey = 'rechargePageKey';
static const selectFamilyFile = 'selectFamilyFile';
static const ancillaryOrdersListNew = 'ancillaryOrdersListNew';
} }

@ -478,6 +478,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
myAppointmentsViewModel.setAppointmentReminder(isEventAddedOrRemoved, widget.patientAppointmentHistoryResponseModel); myAppointmentsViewModel.setAppointmentReminder(isEventAddedOrRemoved, widget.patientAppointmentHistoryResponseModel);
}); });
}, },
isForAppointment: true
); );
// If permission was not granted, revert the switch back to OFF // If permission was not granted, revert the switch back to OFF

@ -131,9 +131,13 @@ class _NewReferralPageState extends State<NewReferralPage> {
hmgServicesVM.createEReferral( hmgServicesVM.createEReferral(
requestModel: createReferralRequestModel, requestModel: createReferralRequestModel,
onSuccess: (GenericApiModel response) { onSuccess: (GenericApiModel response) async{
LoaderBottomSheet.hideLoader(); LoaderBottomSheet.hideLoader();
showSuccessBottomSheet(int.parse(response.data), hmgServicesVM); showSuccessBottomSheet(int.parse(response.data), hmgServicesVM);
await Future.delayed(Duration(milliseconds: 2000)).then((value) {
if (mounted) Navigator.pop(context);
});
}, },
onError: (errorMessage) { onError: (errorMessage) {
// Handle error (e.g., show error message) // Handle error (e.g., show error message)

@ -62,7 +62,7 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
children: [ children: [
Expanded( Expanded(
child: CollapsingListView( child: CollapsingListView(
title: LocaleKeys.createAdvancedPayment.tr(context: context), title: LocaleKeys.rechargePageKey.tr(context: context),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Padding( child: Padding(
padding: EdgeInsets.all(24.h), padding: EdgeInsets.all(24.h),

@ -88,7 +88,7 @@ class _ServicesPageState extends State<ServicesPage> {
// await getIt.get<AuthenticationViewModel>().onLoginPressed(); // await getIt.get<AuthenticationViewModel>().onLoginPressed();
// } // }
}), }),
HmgServicesComponentModel(11, LocaleKeys.bookAppointment.tr(), "", AppAssets.appointment_calendar_icon, bgColor: AppColors.bookAppointment, true, route: null, onTap: () { HmgServicesComponentModel(11, LocaleKeys.bookAppointmentService.tr(), "", AppAssets.appointment_calendar_icon, bgColor: AppColors.bookAppointment, true, route: null, onTap: () {
getIt.get<BookAppointmentsViewModel>().onTabChanged(0); getIt.get<BookAppointmentsViewModel>().onTabChanged(0);
Navigator.of(getIt<NavigationService>().navigatorKey.currentContext!).push(CustomPageRoute(page: BookAppointmentPage())); Navigator.of(getIt<NavigationService>().navigatorKey.currentContext!).push(CustomPageRoute(page: BookAppointmentPage()));
}), }),
@ -169,7 +169,7 @@ class _ServicesPageState extends State<ServicesPage> {
}), }),
HmgServicesComponentModel( HmgServicesComponentModel(
3, 3,
LocaleKeys.bloodDonation.tr(context: getIt.get<NavigationService>().navigatorKey.currentContext!), LocaleKeys.bloodDonationService.tr(context: getIt.get<NavigationService>().navigatorKey.currentContext!),
"".needTranslation, "".needTranslation,
AppAssets.blood_donation_icon, AppAssets.blood_donation_icon,
bgColor: AppColors.bloodDonationCardColor, bgColor: AppColors.bloodDonationCardColor,
@ -632,7 +632,7 @@ class _ServicesPageState extends State<ServicesPage> {
iconSize: 24.h, iconSize: 24.h,
iconColor: AppColors.primaryRedColor, iconColor: AppColors.primaryRedColor,
textColor: AppColors.primaryRedColor, textColor: AppColors.primaryRedColor,
text: LocaleKeys.addMember.tr(), text: getIt.get<AppState>().isArabic() ? LocaleKeys.add.tr() :LocaleKeys.addMember.tr(),
borderWidth: 0.w, borderWidth: 0.w,
isBold: true, isBold: true,
borderColor: Colors.transparent, borderColor: Colors.transparent,

@ -57,6 +57,7 @@ class ServiceGridViewItem extends StatelessWidget {
isBold: true, isBold: true,
color: AppColors.textColor, color: AppColors.textColor,
maxLine: 2, maxLine: 2,
), ),
], ],
)); ));

@ -1219,7 +1219,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
); );
}), }),
MedicalFileCard( MedicalFileCard(
label: LocaleKeys.ancillaryOrdersList.tr(context: context), label: LocaleKeys.ancillaryOrdersListNew.tr(context: context),
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.ancillary_orders_list_icon, svgIcon: AppAssets.ancillary_orders_list_icon,

@ -178,6 +178,34 @@ class _MedicalFileAppointmentCardState extends State<MedicalFileAppointmentCard>
], ],
), ),
SizedBox(height: 12.h), SizedBox(height: 12.h),
// Check if doctor is active - if not, show only View Details button
(widget.patientAppointmentHistoryResponseModel.isActiveDoctor ?? true)
? // Doctor is active - check rebooking logic
(AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) &&
widget.patientAppointmentHistoryResponseModel.isClinicReBookingAllowed == false)
? // Show only the button without arrow when rebooking not allowed
widget.myAppointmentsViewModel.isMyAppointmentsLoading
? Container().toShimmer2(isShow: true, height: 40.h, width: 100.w, radius: 12.r)
: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)
? getArrivedAppointmentButton(context).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading)
: CustomButton(
text: AppointmentType.getNextActionText(widget.patientAppointmentHistoryResponseModel.nextAction),
onPressed: () {
handleAppointmentNextAction(widget.patientAppointmentHistoryResponseModel.nextAction, context);
},
backgroundColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.15),
borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.01),
textColor: AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction),
fontSize: 14.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 40.h,
icon: AppointmentType.getNextActionIcon(widget.patientAppointmentHistoryResponseModel.nextAction),
iconColor: AppointmentType.getNextActionTextColor(widget.patientAppointmentHistoryResponseModel.nextAction),
iconSize: 14.h,
).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading)
: // Normal flow - show button with arrow
Row( Row(
children: [ children: [
widget.myAppointmentsViewModel.isMyAppointmentsLoading widget.myAppointmentsViewModel.isMyAppointmentsLoading
@ -246,7 +274,31 @@ class _MedicalFileAppointmentCardState extends State<MedicalFileAppointmentCard>
}), }),
), ),
], ],
)
: // Doctor is not active - show only View Details button
CustomButton(
text: LocaleKeys.viewDetails.tr(context: context),
onPressed: () {
Navigator.of(context)
.push(
CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel),
), ),
)
.then((_) {
widget.myAppointmentsViewModel.initAppointmentsViewModel();
widget.myAppointmentsViewModel.getPatientAppointments(true, false);
});
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: (isFoldable || isTablet) ? 12.f : 14.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 40.h,
).toShimmer2(isShow: widget.myAppointmentsViewModel.isMyAppointmentsLoading),
], ],
).paddingAll(16.w), ).paddingAll(16.w),
), ),
@ -255,6 +307,34 @@ class _MedicalFileAppointmentCardState extends State<MedicalFileAppointmentCard>
} }
Widget getArrivedAppointmentButton(BuildContext context) { Widget getArrivedAppointmentButton(BuildContext context) {
// Check if rebooking is not allowed - show View Details button
if (widget.patientAppointmentHistoryResponseModel.isClinicReBookingAllowed == false) {
return CustomButton(
text: LocaleKeys.viewDetails.tr(context: context),
onPressed: () {
Navigator.of(context)
.push(
CustomPageRoute(
page: AppointmentDetailsPage(patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel),
),
)
.then((_) {
widget.myAppointmentsViewModel.initAppointmentsViewModel();
widget.myAppointmentsViewModel.getPatientAppointments(true, false);
});
},
backgroundColor: AppColors.secondaryLightRedColor,
borderColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor,
fontSize: (isFoldable || isTablet) ? 12.f : 14.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
padding: EdgeInsets.symmetric(horizontal: 10.w),
height: 40.h,
);
}
// Check if clinic allows rebooking or if doctor is excluded
if ((((widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false) || if ((((widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false) ||
(widget.patientAppointmentHistoryResponseModel.isExecludeDoctor ?? false) || (widget.patientAppointmentHistoryResponseModel.isExecludeDoctor ?? false) ||
!Utils.isClinicAllowedForRebook(widget.patientAppointmentHistoryResponseModel.clinicID ?? 0))) && !Utils.isClinicAllowedForRebook(widget.patientAppointmentHistoryResponseModel.clinicID ?? 0))) &&

@ -9,12 +9,14 @@ 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/date_util.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.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/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
import 'package:hmg_patient_app_new/extensions/string_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/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/prescriptions/models/resp_models/patient_prescriptions_response_model.dart'; import 'package:hmg_patient_app_new/features/prescriptions/models/resp_models/patient_prescriptions_response_model.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart'; import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_item_view.dart'; import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_item_view.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/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.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/buttons/custom_button.dart';
@ -237,7 +239,8 @@ class _PrescriptionDetailPageState extends State<PrescriptionDetailPage> {
), ),
), ),
), ),
Container( Column(
children: [ Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor, color: AppColors.whiteColor,
borderRadius: 24.h, borderRadius: 24.h,
@ -268,8 +271,55 @@ class _PrescriptionDetailPageState extends State<PrescriptionDetailPage> {
icon: AppAssets.prescription_refill_icon, icon: AppAssets.prescription_refill_icon,
iconColor: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? Colors.white : AppColors.textColor.withOpacity(0.35), iconColor: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? Colors.white : AppColors.textColor.withOpacity(0.35),
iconSize: 20.h, iconSize: 20.h,
).paddingSymmetrical(24.h, 24.h), ).paddingSymmetrical(24.h, 0.h),
),
Utils.havePrivilege(119) ? Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.h,
hasShadow: true,
),
child: Container(
height: 56.h,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12.r),
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
stops: [0.236, 1.0], // 53.6% and 100%
colors: [
Color(0xFF8A38F5), // Transparent
Color(0xFFE20BBB), // Solid #F8F8F8
],
), ),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.only(right: 4.w, left: 4.w),
child: Utils.buildSvgWithAssets(icon: AppAssets.aiOverView, width: 16.h, height: 16.h, iconColor: Colors.white),
),
LocaleKeys.generateAiAnalysisResult.tr(context: context).toText16(isBold: true, color: Colors.white)
],
),
).paddingSymmetrical(24.h, 24.h).onPress(() async {
final _dialogService = getIt.get<DialogService>();
await _dialogService.showCommonBottomSheetWithoutH(
message: LocaleKeys.aiDisclaimer.tr(),
label: LocaleKeys.consent.tr(),
okLabel: LocaleKeys.acceptLbl.tr(),
cancelLabel: LocaleKeys.rejectView.tr(),
onOkPressed: () {
},
onCancelPressed: () {
context.pop();
});
}),
) : SizedBox(height: 24,) ,
])
], ],
), ),
); );

@ -1,3 +1,5 @@
import 'dart:io' show Platform;
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart';
@ -8,12 +10,14 @@ 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/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart'; import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/services/permission_service.dart';
import 'package:hmg_patient_app_new/theme/colors.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/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.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:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
import 'package:hmg_patient_app_new/widgets/scroll_wheel_time_picker.dart'; import 'package:hmg_patient_app_new/widgets/scroll_wheel_time_picker.dart';
import 'package:permission_handler/permission_handler.dart';
class PrescriptionItemView extends StatelessWidget { class PrescriptionItemView extends StatelessWidget {
int index; int index;
@ -233,4 +237,71 @@ class PrescriptionItemView extends StatelessWidget {
], ],
); );
} }
/// Checks and requests calendar permissions for both Android and iOS
/// Returns true if all required permissions are granted
Future<bool> _checkAndRequestCalendarPermissions() async {
if (Platform.isAndroid) {
// Android: Check existing permission first using PermissionService
bool hasPermission = await PermissionService.isCalendarPermissionEnabled();
if (hasPermission) {
return true;
}
// Request calendarFullAccess permission (Android 14+ requires this)
// This internally requests both READ_CALENDAR and WRITE_CALENDAR
PermissionStatus status = await Permission.calendarFullAccess.request();
// If calendarFullAccess request didn't show dialog or failed,
// fallback to requesting individual permissions
if (!status.isGranted) {
Map<Permission, PermissionStatus> statuses = await [
Permission.calendarWriteOnly,
].request();
return statuses[Permission.calendarWriteOnly]?.isGranted ?? false;
}
return status.isGranted;
} else {
// iOS: Check if we already have full access
PermissionStatus fullAccessStatus = await Permission.calendarFullAccess.status;
if (fullAccessStatus.isGranted) {
return true;
}
// Request write permission first (required before full access on iOS)
PermissionStatus writeStatus = await Permission.calendarWriteOnly.request();
if (!writeStatus.isGranted) {
return false;
}
// Then request full access permission
PermissionStatus fullStatus = await Permission.calendarFullAccess.request();
return fullStatus.isGranted;
}
}
/// Shows permission denied dialog with option to open settings
Future<void> _showPermissionDeniedDialog(BuildContext context) async {
showCommonBottomSheetWithoutHeight(
context,
title: LocaleKeys.notice.tr(context: context),
child: Utils.getWarningWidget(
loadingText: LocaleKeys.calendarPermissionAlert.tr(),
isShowActionButtons: true,
onCancelTap: () {
Navigator.of(context).pop();
},
onConfirmTap: () async {
Navigator.of(context).pop();
await openAppSettings();
},
),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
}
} }

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_assets.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_export.dart';
import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/cache_consts.dart';
import 'package:hmg_patient_app_new/core/dependencies.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/enums.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart';
@ -11,6 +12,8 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/symptoms_checker_view_model.dart'; import 'package:hmg_patient_app_new/features/symptoms_checker/symptoms_checker_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/widgets/interactive_body_widget.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/widgets/interactive_body_widget.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/widgets/pinch_zoom_tutorial_overlay.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart';
import 'package:hmg_patient_app_new/services/dialog_service.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/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
@ -28,12 +31,36 @@ class OrganSelectorPage extends StatefulWidget {
class _OrganSelectorPageState extends State<OrganSelectorPage> { class _OrganSelectorPageState extends State<OrganSelectorPage> {
late final AppState _appState; late final AppState _appState;
late final DialogService dialogService; late final DialogService dialogService;
late final CacheService cacheService;
bool _showTutorial = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_appState = getIt.get<AppState>(); _appState = getIt.get<AppState>();
dialogService = getIt<DialogService>(); dialogService = getIt<DialogService>();
cacheService = getIt<CacheService>();
_checkAndShowTutorial();
}
Future<void> _checkAndShowTutorial() async {
final hasSeenTutorial = cacheService.getBool(key: CacheConst.organSelectorTutorialShown) ?? false;
if (!hasSeenTutorial) {
// Show tutorial after a short delay to ensure the screen is fully built
await Future.delayed(const Duration(milliseconds: 500));
if (mounted) {
setState(() {
_showTutorial = true;
});
}
}
}
void _onTutorialComplete() async {
await cacheService.saveBool(key: CacheConst.organSelectorTutorialShown, value: true);
setState(() {
_showTutorial = false;
});
} }
void _onNextPressed(SymptomsCheckerViewModel viewModel) async { void _onNextPressed(SymptomsCheckerViewModel viewModel) async {
@ -65,7 +92,9 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Stack(
children: [
Scaffold(
backgroundColor: AppColors.bgScaffoldColor, backgroundColor: AppColors.bgScaffoldColor,
appBar: _buildAppBar(), appBar: _buildAppBar(),
body: Consumer<SymptomsCheckerViewModel>( body: Consumer<SymptomsCheckerViewModel>(
@ -80,7 +109,7 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> {
children: [ children: [
_buildBodyViewer(viewModel), _buildBodyViewer(viewModel),
_buildViewToggleButtons(viewModel), _buildViewToggleButtons(viewModel),
_buildViewZoomButtons(viewModel), // _buildViewZoomButtons(viewModel),
_buildBottomSheet(viewModel), _buildBottomSheet(viewModel),
], ],
), ),
@ -89,6 +118,13 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> {
); );
}, },
), ),
),
// Tutorial overlay
if (_showTutorial)
PinchZoomTutorialOverlay(
onComplete: _onTutorialComplete,
),
],
); );
} }

@ -0,0 +1,261 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_export.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';
class PinchZoomTutorialOverlay extends StatefulWidget {
final VoidCallback onComplete;
const PinchZoomTutorialOverlay({
Key? key,
required this.onComplete,
}) : super(key: key);
@override
State<PinchZoomTutorialOverlay> createState() => _PinchZoomTutorialOverlayState();
}
class _PinchZoomTutorialOverlayState extends State<PinchZoomTutorialOverlay> with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<double> _fadeAnimation;
int _currentStep = 0;
@override
void initState() {
super.initState();
_animationController = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
_fadeAnimation = CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
);
_animationController.forward();
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void _nextStep() {
if (_currentStep < 1) {
setState(() {
_currentStep++;
});
} else {
_animationController.reverse().then((_) {
widget.onComplete();
});
}
}
@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: _fadeAnimation,
child: Material(
color: Colors.black.withValues(alpha: 0.85),
child: SafeArea(
child: Stack(
children: [
// Tap to dismiss overlay
Positioned.fill(
child: GestureDetector(
onTap: () {},
child: Container(color: Colors.transparent),
),
),
// Tutorial content
Center(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.w),
child: _currentStep == 0 ? _buildFirstStep() : _buildSecondStep(),
),
),
],
),
),
),
);
}
Widget _buildFirstStep() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Pinch gesture illustration
Container(
width: 200.w,
height: 200.h,
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(20.r),
),
child: Center(
child: _buildPinchGestureAnimation(),
),
),
SizedBox(height: 32.h),
// Title
Text(
LocaleKeys.pinchToZoom.tr(context: context),
style: TextStyle(
color: Colors.white,
fontSize: 24.f,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
SizedBox(height: 32.h),
// Button
CustomButton(
text: LocaleKeys.gotIt.tr(context: context),
onPressed: _nextStep,
backgroundColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 16.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
height: 50.h,
),
],
);
}
Widget _buildSecondStep() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Illustration container with rounded corners
Container(
padding: EdgeInsets.all(24.w),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.95),
borderRadius: BorderRadius.circular(20.r),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
LocaleKeys.zoomIntoDetails.tr(context: context),
style: TextStyle(
color: AppColors.textColor,
fontSize: 20.f,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
SizedBox(height: 24.h),
// Pinch instruction
_buildInstructionRow(
icon: Icons.pinch_outlined,
text: LocaleKeys.pinchWithTwoFingersToZoom.tr(context: context),
),
SizedBox(height: 16.h),
// Drag instruction
_buildInstructionRow(
icon: Icons.pan_tool_outlined,
text: LocaleKeys.dragToMoveAround.tr(context: context),
),
],
),
),
SizedBox(height: 32.h),
// Button
CustomButton(
text: LocaleKeys.startExploring.tr(context: context),
onPressed: _nextStep,
backgroundColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor,
fontSize: 16.f,
fontWeight: FontWeight.w600,
borderRadius: 12.r,
height: 50.h,
),
],
);
}
Widget _buildInstructionRow({required IconData icon, required String text}) {
return Row(
children: [
Container(
width: 48.w,
height: 48.h,
decoration: BoxDecoration(
color: AppColors.primaryRedColor.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(12.r),
),
child: Icon(
icon,
color: AppColors.primaryRedColor,
size: 24.w,
),
),
SizedBox(width: 16.w),
Expanded(
child: Text(
text,
style: TextStyle(
color: AppColors.textColor,
fontSize: 14.f,
fontWeight: FontWeight.w500,
),
),
),
],
);
}
Widget _buildPinchGestureAnimation() {
return TweenAnimationBuilder<double>(
tween: Tween(begin: 1.0, end: 0.7),
duration: const Duration(milliseconds: 1500),
curve: Curves.easeInOut,
builder: (context, value, child) {
return Transform.scale(
scale: value,
child: Stack(
alignment: Alignment.center,
children: [
// Left hand
Positioned(
left: 40.w * (1 - value),
child: Transform.rotate(
angle: -0.3,
child: Icon(
Icons.pan_tool,
size: 50.w,
color: Colors.white.withValues(alpha: 0.9),
),
),
),
// Right hand
Positioned(
right: 40.w * (1 - value),
child: Transform.rotate(
angle: 0.3,
child: Icon(
Icons.pan_tool,
size: 50.w,
color: Colors.white.withValues(alpha: 0.9),
),
),
),
],
),
);
},
onEnd: () {
// Restart animation
setState(() {});
},
);
}
}

@ -18,7 +18,7 @@ import 'package:permission_handler/permission_handler.dart';
class BottomSheetUtils { class BottomSheetUtils {
Future<bool> showReminderBottomSheet(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, Future<bool> showReminderBottomSheet(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted,
{required Function() onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool isMultiAllowed = false}) async { {required Function() onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool isMultiAllowed = false, bool isForAppointment = false}) async {
// Check and request permissions based on platform // Check and request permissions based on platform
bool hasPermission = await _checkAndRequestCalendarPermissions(); bool hasPermission = await _checkAndRequestCalendarPermissions();
@ -79,7 +79,7 @@ class BottomSheetUtils {
} }
/// Shows permission denied dialog with option to open settings /// Shows permission denied dialog with option to open settings
Future<void> _showPermissionDeniedDialog() async { Future<void> _showPermissionDeniedDialog({bool isForAppointment = false}) async {
BuildContext? context = GetIt.instance<NavigationService>().navigatorKey.currentContext; BuildContext? context = GetIt.instance<NavigationService>().navigatorKey.currentContext;
if (context == null) return; if (context == null) return;
@ -87,7 +87,7 @@ class BottomSheetUtils {
context, context,
title: LocaleKeys.notice.tr(context: context), title: LocaleKeys.notice.tr(context: context),
child: Utils.getWarningWidget( child: Utils.getWarningWidget(
loadingText: LocaleKeys.calendarPermissionAlert.tr(), loadingText: isForAppointment ? LocaleKeys.calendarPermissionAlertForAppointment.tr() : LocaleKeys.calendarPermissionAlert.tr(),
isShowActionButtons: true, isShowActionButtons: true,
onCancelTap: () { onCancelTap: () {
GetIt.instance<NavigationService>().pop(); GetIt.instance<NavigationService>().pop();

Loading…
Cancel
Save