pull/253/head
Sultan khan 1 day ago
commit c2d468bd74

@ -101,7 +101,7 @@
"onlinePaymentSubtitle": "الدفع",
"cancelNocaps": "إلغاء",
"setReminder": "تذكير",
"nationalIdNumber": "رقم الهوية الوطنية",
"nationalIdNumber": "رقم الهوية / الإقام",
"medicalFileNumber": "رقم الملف الطبي",
"loginregister": "تسجيل الدخول / التسجيل",
"poweredBy": "مدعوم من",
@ -125,7 +125,7 @@
"profileInfo": "يرجى إدخال معلومات الملف الشخصي",
"submit": "تحديث",
"forgotDesc": "أدخل رقم الهاتف المحمول لاستلام رقم الملف الطبي عبر الرسائل القصيرة",
"dob": "تاريخ الميلاد:",
"dob": "تاريخ الميلاد",
"hijriDate": "الت<D984><D8AA>ريخ الهجري",
"gregorianDate": "التاريخ الميلادي",
"verifyLoginWith": "يرجى اختيار واحدة من الخيارات التالية للتحقق",
@ -815,7 +815,7 @@
"enterEmailDesc": "أدخل عنوان بريدك الإلكتروني لإكمال عملية إنشاء ملف طبي",
"enterPhoneDesc": "أدخل رقم هاتفك لتلقي رمز التحقق ",
"pleaseChooseOption": "الرجاء اختيار من الخيارات أدناه لتلقي رمز التحقق OTP",
"prepareToElevate": "هل أنت مستعد لتحسين صحتك ورفاهيتك؟",
"prepareToElevate": "رعايتك الصحية تبدأ من هنا",
"iAcceptTermsConditions": "أوافق على الشروط والأحكام",
"alreadyHaveAccount": "هل لديك حساب بالفعل؟",
"loginNow": "تسجيل الدخول الآن",
@ -859,8 +859,8 @@
"didntReceiveIt": "لم تستلمه؟",
"resendOTP": "إعادة إرسال",
"resendIn": "إعادة الإرسال في",
"pleaseEnterAnationalID": "يرجى إدخال رقم الهوية الوطنية",
"pleaseEnterAFileNumber": "يرجى إدخال رقم الملف",
"pleaseEnterAnationalID": "تسجيل الدخول برقم الهوية او الاقامة",
"pleaseEnterAFileNumber": "يرجى إدخال / رقم الملف",
"pleaseEnterAValidEmail": "يرجى إدخال بريد إلكتروني صالح",
"pleaseEnterFullName": "يرجى إدخال الاسم الكامل",
"pleaseAcceptTermsConditions": "يرجى قبول الشروط والأحكام",
@ -1681,10 +1681,10 @@
"favouriteList": "قائمة المفضلة",
"later": "لاحقاً",
"cancelAppointmentConfirmMessage": "هل أنت متأكد من رغبتك في إلغاء هذا الموعد؟",
"acknowledged": "حسنا",
"acknowledged": "إغلاق",
"searchLabResults": "بحث نتائج المختبر",
"callForAssistance": "اتصل للحصول على المساعدة الفورية",
"oneWaySubtitle": "نقل من الموقع إلى المستشفى",
"oneWaySubtitle": "نقل م ن الموقع إلى المستشفى",
"twoWaySubtitle": "نقل من الموقع إلى المستشفى والعودة مرة أخرى",
"toHospitalSubtitle": "نقل من موقعك الحالي إلى المستشفى",
"fromHospitalSubtitle": "نقل من المستشفى إلى منزلك",
@ -1748,5 +1748,6 @@
"m": "متر",
"inch": "انش",
"updateEmailAddressTitle": "تحديث البريد الالكتروني: ",
"enterNewNewContactNumber": "الرجاء اضافة رقم اتصال في حالة الطواريء: "
"enterNewNewContactNumber": "الرجاء اضافة رقم اتصال في حالة الطواريء: ",
"nationalIdFileNumber": "رقم الهوية / الإقامة / الملف"
}

@ -99,7 +99,7 @@
"onlinePaymentSubtitle": "Payment",
"cancelNocaps": "Cancel",
"setReminder": "Set Reminder",
"nationalIdNumber": "National ID Number",
"nationalIdNumber": "National ID / Iqama",
"medicalFileNumber": "Medical File Number",
"loginregister": "Login / Register",
"poweredBy": "Powered by",
@ -123,7 +123,7 @@
"profileInfo": "Please enter profile information",
"submit": "Submit",
"forgotDesc": "Enter the mobile number to receive the Medical File Number via SMS",
"dob": "Birth Date:",
"dob": "Birth Date",
"hijriDate": "Hijri Date",
"gregorianDate": "Gregorian Date",
"verifyLoginWith": "Please choose one of the following options to verify",
@ -806,7 +806,7 @@
"readInstructions": "Read Instructions",
"searchLabReport": "Search Lab Report",
"prescriptionDeliveryError": "This clinic doesn't support refill",
"prepareToElevate": "Prepared to elevate your health and well-being?",
"prepareToElevate": "Your wellness journey starts here.",
"iAcceptTermsConditions": "I Accept the Terms and Conditions",
"alreadyHaveAccount": "Already have an account?",
"loginNow": "Login Now",
@ -997,7 +997,7 @@
"processingCheckIn": "Processing Check-In...",
"bookingWaitingAppointment": "Booking Waiting Appointment, Please wait...",
"enterValidIDorIqama": "Please enter a valid national ID or file number",
"selectAppointment": "Select Appointment",
"selectAppointment": "Select Axppointment",
"rebookSameDoctor": "Rebook with same doctor",
"queueing": "Queueing",
"inQueue": "In Queue",
@ -1737,5 +1737,6 @@
"m": "m",
"inch": "in",
"updateEmailAddressTitle": "Enter the new email address to be updated: ",
"enterNewNewContactNumber": "Enter the new emergency contact number to be updated: "
"enterNewNewContactNumber": "Enter the new emergency contact number to be updated: ",
"nationalIdFileNumber": "National ID/File Number"
}

@ -16,33 +16,64 @@ class CalenderUtilsNew {
final DeviceCalendar calender = DeviceCalendar.instance;
List<Calendar> writableCalender = [];
CalenderUtilsNew._instance() {
getCalenders();
}
/// Completer to ensure getCalenders() only runs once at a time
Completer<void>? _calendarInitCompleter;
CalenderUtilsNew._instance();
static final CalenderUtilsNew instance = CalenderUtilsNew._instance();
Future<void> getCalenders() async {
/// Ensures calendars are loaded exactly once. Safe to call multiple times
/// subsequent calls await the same future.
Future<void> ensureCalendarsLoaded() async {
if (writableCalender.isNotEmpty) return;
if (_calendarInitCompleter != null) {
// Already in progress just wait for it
return _calendarInitCompleter!.future;
}
_calendarInitCompleter = Completer<void>();
try {
await _loadCalendars();
_calendarInitCompleter!.complete();
} catch (e) {
_calendarInitCompleter!.completeError(e);
_calendarInitCompleter = null; // Allow retry on failure
rethrow;
}
}
Future<void> _loadCalendars() async {
print("the get calenders is called");
CalendarPermissionStatus result = await DeviceCalendar.instance.hasPermissions();
if (result != CalendarPermissionStatus.granted) {
await DeviceCalendar.instance.requestPermissions();
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: GetIt.instance<NavigationService>().navigatorKey.currentContext!),
GetIt.instance<NavigationService>().navigatorKey.currentContext!,
child: Utils.getWarningWidget(
loadingText: LocaleKeys.calendarPermissionAlert.tr(),
isShowActionButtons: true,
onCancelTap: () {
GetIt.instance<NavigationService>().pop();
},
onConfirmTap: () async {
GetIt.instance<NavigationService>().pop();
openAppSettings();
}),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
result = await DeviceCalendar.instance.hasPermissions();
// if (result != CalendarPermissionStatus.granted) {
// print("the permission is not granted");
// showCommonBottomSheetWithoutHeight(
// title: LocaleKeys.notice.tr(context: GetIt
// .instance<NavigationService>()
// .navigatorKey
// .currentContext!),
// GetIt
// .instance<NavigationService>()
// .navigatorKey
// .currentContext!,
// child: Utils.getWarningWidget(
// loadingText: LocaleKeys.calendarPermissionAlert.tr(),
// isShowActionButtons: true,
// onCancelTap: () {
// GetIt.instance<NavigationService>().pop();
// },
// onConfirmTap: () async {
// GetIt.instance<NavigationService>().pop();
// openAppSettings();
// }),
// callBackFunc: () {},
// isFullScreen: false,
// isCloseButtonVisible: true,
// );
// }
}
var calenders = await calender.listCalendars();
calenders.forEach((calender) {
@ -53,9 +84,7 @@ class CalenderUtilsNew {
}
FutureOr<bool> createOrUpdateEvent({required String title, required String description, required String location, DateTime? scheduleDateTime, String? eventId, int? reminderMinutes}) async {
if (writableCalender.isEmpty) {
await getCalenders();
}
await ensureCalendarsLoaded();
var writableCalendars = writableCalender.first;
String eventResult = "";
CalendarPermissionStatus result = await DeviceCalendar.instance.hasPermissions();
@ -146,9 +175,7 @@ class CalenderUtilsNew {
}
FutureOr<bool> checkIfEventExist(String admissionId) async {
if (writableCalender.isEmpty) {
await getCalenders();
}
await ensureCalendarsLoaded();
List<Event> events = await getEvents();
if (events.isEmpty) return false;
for (var event in events) {
@ -161,7 +188,7 @@ class CalenderUtilsNew {
FutureOr<String> getEventIdIfEventExist(String admissionId) async {
if (writableCalender.isEmpty) {
await getCalenders();
await ensureCalendarsLoaded();
}
List<Event> events = await getEvents();
if (events.isEmpty) return "";
@ -174,7 +201,7 @@ class CalenderUtilsNew {
FutureOr<bool> checkAndRemove({required String id}) async {
if (writableCalender.isEmpty) {
await getCalenders();
await ensureCalendarsLoaded();
}
List<Event> events = await getEvents();
if (events.isEmpty) return false;
@ -191,7 +218,7 @@ class CalenderUtilsNew {
FutureOr<bool> checkAndRemoveMultipleItems({required String id}) async {
if (writableCalender.isEmpty) {
await getCalenders();
await ensureCalendarsLoaded();
}
List<Event> events = await getEvents();
if (events.isEmpty) return false;

@ -1739,5 +1739,6 @@ abstract class LocaleKeys {
static const inch = 'inch';
static const updateEmailAddressTitle = 'updateEmailAddressTitle';
static const enterNewNewContactNumber = 'enterNewNewContactNumber';
static const nationalIdFileNumber = 'nationalIdFileNumber';
}

@ -103,14 +103,15 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
}
// // Check if reminder exists in calendar and update the flag
// await _checkAndUpdateReminderStatus();
}
});
// Initialize countdown timer for payment after first frame to ensure context is available
WidgetsBinding.instance.addPostFrameCallback((_) {
WidgetsBinding.instance.addPostFrameCallback((_) async {
if (mounted) {
_startCountdownTimer();
await _checkAndUpdateReminderStatus();
}
});
}
@ -373,6 +374,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
? null
: Column(
children: [
SizedBox(height: 16.w),
Divider(height: 1, color: AppColors.dividerColor),
SizedBox(height: 16.w),

@ -76,7 +76,7 @@ class LoginScreenState extends State<LoginScreen> {
SizedBox(height: 32.h),
Localizations.override(context: context, locale: Locale('en', 'US'), child: Container()), // Force English locale for this widget
TextInputWidget(
labelText: "${LocaleKeys.nationalId.tr(context: context)} / ${LocaleKeys.fileNo.tr(context: context)}",
labelText: "${LocaleKeys.nationalIdFileNumber.tr(context: context)}",
hintText: "xxxxxxxxx",
controller: authVm.nationalIdController,
focusNode: _nationalIdFocusNode,

Loading…
Cancel
Save