Merge pull request 'localization changes' (#247) from changes into master

Reviewed-on: #247
dev_aamir
khansultan1 15 hours ago
commit 5c3b1fe448

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

@ -99,7 +99,7 @@
"onlinePaymentSubtitle": "Payment", "onlinePaymentSubtitle": "Payment",
"cancelNocaps": "Cancel", "cancelNocaps": "Cancel",
"setReminder": "Set Reminder", "setReminder": "Set Reminder",
"nationalIdNumber": "National ID Number", "nationalIdNumber": "National ID / Iqama",
"medicalFileNumber": "Medical File Number", "medicalFileNumber": "Medical File Number",
"loginregister": "Login / Register", "loginregister": "Login / Register",
"poweredBy": "Powered by", "poweredBy": "Powered by",
@ -123,7 +123,7 @@
"profileInfo": "Please enter profile information", "profileInfo": "Please enter profile information",
"submit": "Submit", "submit": "Submit",
"forgotDesc": "Enter the mobile number to receive the Medical File Number via SMS", "forgotDesc": "Enter the mobile number to receive the Medical File Number via SMS",
"dob": "Birth Date:", "dob": "Birth Date",
"hijriDate": "Hijri Date", "hijriDate": "Hijri Date",
"gregorianDate": "Gregorian Date", "gregorianDate": "Gregorian Date",
"verifyLoginWith": "Please choose one of the following options to verify", "verifyLoginWith": "Please choose one of the following options to verify",
@ -806,7 +806,7 @@
"readInstructions": "Read Instructions", "readInstructions": "Read Instructions",
"searchLabReport": "Search Lab Report", "searchLabReport": "Search Lab Report",
"prescriptionDeliveryError": "This clinic doesn't support refill", "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", "iAcceptTermsConditions": "I Accept the Terms and Conditions",
"alreadyHaveAccount": "Already have an account?", "alreadyHaveAccount": "Already have an account?",
"loginNow": "Login Now", "loginNow": "Login Now",
@ -997,7 +997,7 @@
"processingCheckIn": "Processing Check-In...", "processingCheckIn": "Processing Check-In...",
"bookingWaitingAppointment": "Booking Waiting Appointment, Please wait...", "bookingWaitingAppointment": "Booking Waiting Appointment, Please wait...",
"enterValidIDorIqama": "Please enter a valid national ID or file number", "enterValidIDorIqama": "Please enter a valid national ID or file number",
"selectAppointment": "Select Appointment", "selectAppointment": "Select Axppointment",
"rebookSameDoctor": "Rebook with same doctor", "rebookSameDoctor": "Rebook with same doctor",
"queueing": "Queueing", "queueing": "Queueing",
"inQueue": "In Queue", "inQueue": "In Queue",
@ -1737,5 +1737,6 @@
"m": "m", "m": "m",
"inch": "in", "inch": "in",
"updateEmailAddressTitle": "Enter the new email address to be updated: ", "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; final DeviceCalendar calender = DeviceCalendar.instance;
List<Calendar> writableCalender = []; List<Calendar> writableCalender = [];
CalenderUtilsNew._instance() { /// Completer to ensure getCalenders() only runs once at a time
getCalenders(); Completer<void>? _calendarInitCompleter;
}
CalenderUtilsNew._instance();
static final CalenderUtilsNew instance = 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(); CalendarPermissionStatus result = await DeviceCalendar.instance.hasPermissions();
if (result != CalendarPermissionStatus.granted) { if (result != CalendarPermissionStatus.granted) {
await DeviceCalendar.instance.requestPermissions(); await DeviceCalendar.instance.requestPermissions();
showCommonBottomSheetWithoutHeight( result = await DeviceCalendar.instance.hasPermissions();
title: LocaleKeys.notice.tr(context: GetIt.instance<NavigationService>().navigatorKey.currentContext!), // if (result != CalendarPermissionStatus.granted) {
GetIt.instance<NavigationService>().navigatorKey.currentContext!, // print("the permission is not granted");
child: Utils.getWarningWidget( // showCommonBottomSheetWithoutHeight(
loadingText: LocaleKeys.calendarPermissionAlert.tr(), // title: LocaleKeys.notice.tr(context: GetIt
isShowActionButtons: true, // .instance<NavigationService>()
onCancelTap: () { // .navigatorKey
GetIt.instance<NavigationService>().pop(); // .currentContext!),
}, // GetIt
onConfirmTap: () async { // .instance<NavigationService>()
GetIt.instance<NavigationService>().pop(); // .navigatorKey
openAppSettings(); // .currentContext!,
}), // child: Utils.getWarningWidget(
callBackFunc: () {}, // loadingText: LocaleKeys.calendarPermissionAlert.tr(),
isFullScreen: false, // isShowActionButtons: true,
isCloseButtonVisible: true, // onCancelTap: () {
); // GetIt.instance<NavigationService>().pop();
// },
// onConfirmTap: () async {
// GetIt.instance<NavigationService>().pop();
// openAppSettings();
// }),
// callBackFunc: () {},
// isFullScreen: false,
// isCloseButtonVisible: true,
// );
// }
} }
var calenders = await calender.listCalendars(); var calenders = await calender.listCalendars();
calenders.forEach((calender) { 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 { FutureOr<bool> createOrUpdateEvent({required String title, required String description, required String location, DateTime? scheduleDateTime, String? eventId, int? reminderMinutes}) async {
if (writableCalender.isEmpty) { await ensureCalendarsLoaded();
await getCalenders();
}
var writableCalendars = writableCalender.first; var writableCalendars = writableCalender.first;
String eventResult = ""; String eventResult = "";
CalendarPermissionStatus result = await DeviceCalendar.instance.hasPermissions(); CalendarPermissionStatus result = await DeviceCalendar.instance.hasPermissions();
@ -146,9 +175,7 @@ class CalenderUtilsNew {
} }
FutureOr<bool> checkIfEventExist(String admissionId) async { FutureOr<bool> checkIfEventExist(String admissionId) async {
if (writableCalender.isEmpty) { await ensureCalendarsLoaded();
await getCalenders();
}
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) {
@ -161,7 +188,7 @@ class CalenderUtilsNew {
FutureOr<String> getEventIdIfEventExist(String admissionId) async { FutureOr<String> getEventIdIfEventExist(String admissionId) async {
if (writableCalender.isEmpty) { if (writableCalender.isEmpty) {
await getCalenders(); await ensureCalendarsLoaded();
} }
List<Event> events = await getEvents(); List<Event> events = await getEvents();
if (events.isEmpty) return ""; if (events.isEmpty) return "";
@ -174,7 +201,7 @@ class CalenderUtilsNew {
FutureOr<bool> checkAndRemove({required String id}) async { FutureOr<bool> checkAndRemove({required String id}) async {
if (writableCalender.isEmpty) { if (writableCalender.isEmpty) {
await getCalenders(); await ensureCalendarsLoaded();
} }
List<Event> events = await getEvents(); List<Event> events = await getEvents();
if (events.isEmpty) return false; if (events.isEmpty) return false;
@ -191,7 +218,7 @@ class CalenderUtilsNew {
FutureOr<bool> checkAndRemoveMultipleItems({required String id}) async { FutureOr<bool> checkAndRemoveMultipleItems({required String id}) async {
if (writableCalender.isEmpty) { if (writableCalender.isEmpty) {
await getCalenders(); await ensureCalendarsLoaded();
} }
List<Event> events = await getEvents(); List<Event> events = await getEvents();
if (events.isEmpty) return false; if (events.isEmpty) return false;

@ -1739,5 +1739,6 @@ abstract class LocaleKeys {
static const inch = 'inch'; static const inch = 'inch';
static const updateEmailAddressTitle = 'updateEmailAddressTitle'; static const updateEmailAddressTitle = 'updateEmailAddressTitle';
static const enterNewNewContactNumber = 'enterNewNewContactNumber'; 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 // // 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 // Initialize countdown timer for payment after first frame to ensure context is available
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) async {
if (mounted) { if (mounted) {
_startCountdownTimer(); _startCountdownTimer();
await _checkAndUpdateReminderStatus();
} }
}); });
} }
@ -373,6 +374,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
? null ? null
: Column( : Column(
children: [ children: [
SizedBox(height: 16.w), SizedBox(height: 16.w),
Divider(height: 1, color: AppColors.dividerColor), Divider(height: 1, color: AppColors.dividerColor),
SizedBox(height: 16.w), SizedBox(height: 16.w),

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

Loading…
Cancel
Save