Merge pull request 'dev_sultan' (#241) from dev_sultan into master

Reviewed-on: #241
pull/243/head
khansultan1 1 day ago
commit 81cdb4be30

@ -198,6 +198,7 @@
"enterEmail": "يرجى إدخال البريد الإلكتروني", "enterEmail": "يرجى إدخال البريد الإلكتروني",
"family": "عائلتي", "family": "عائلتي",
"familyTitle": "ملفات عائلتي", "familyTitle": "ملفات عائلتي",
"familyTitle2": "ملفات العائلة",
"myFamily": "عائلتي", "myFamily": "عائلتي",
"addNewMember": "إضافة فرد جديد للعائلة", "addNewMember": "إضافة فرد جديد للعائلة",
"sentRequests": "الطلبات المرسلة", "sentRequests": "الطلبات المرسلة",
@ -218,7 +219,7 @@
"unit": "الوحدة", "unit": "الوحدة",
"request": "طلب", "request": "طلب",
"memberName": "اسم العضو", "memberName": "اسم العضو",
"switchLogin": "تبديل", "switchLogin": "عرض",
"removeMember": "إزالة", "removeMember": "إزالة",
"allowView": "السماح", "allowView": "السماح",
"rejectView": "رفض", "rejectView": "رفض",
@ -488,7 +489,7 @@
"shareReview": "شارك التقييم", "shareReview": "شارك التقييم",
"review": " التقييمات", "review": " التقييمات",
"viewMedicalFile": "عرض التفاصيل", "viewMedicalFile": "عرض التفاصيل",
"viewAllServices": "عرض جميع الخدمات", "viewAllServices": "جميع الخدمات",
"medicalFile": "الملف الطبي", "medicalFile": "الملف الطبي",
"verified": "تم التحقق", "verified": "تم التحقق",
"checkup": "فحص", "checkup": "فحص",
@ -930,7 +931,7 @@
"vat15": "ضريبة القيمة المضافة 15%", "vat15": "ضريبة القيمة المضافة 15%",
"general": "عام", "general": "عام",
"liveCare": "لايف كير", "liveCare": "لايف كير",
"recentVisits": "الزيارات الأخيرة", "recentVisits": "قائمة الزيارات",
"favouriteDoctors": "الأطباء المفضلون", "favouriteDoctors": "الأطباء المفضلون",
"searchByClinic": "العيادة", "searchByClinic": "العيادة",
"tapToSelectClinic": "انقر لاختيار العيادة", "tapToSelectClinic": "انقر لاختيار العيادة",
@ -951,7 +952,7 @@
"freeMedicineDelivery": "توصيل مجاني للأدوية", "freeMedicineDelivery": "توصيل مجاني للأدوية",
"offersFreeMedicineDelivery": "يوفر توصيل مجاني للأدوية لموعد لايف كير", "offersFreeMedicineDelivery": "يوفر توصيل مجاني للأدوية لموعد لايف كير",
"dentalChiefComplaints": "الشكاوى الرئيسة للأسنان", "dentalChiefComplaints": "الشكاوى الرئيسة للأسنان",
"viewAvailableAppointments": "عرض المواعيد المتاحة", "viewAvailableAppointments": "المواعيد المتاحة",
"doctorProfile": " ملف الطبيب", "doctorProfile": " ملف الطبيب",
"waitingAppointment": "موعد الانتظار", "waitingAppointment": "موعد الانتظار",
"hospitalInformation": "معلومات المستشفى", "hospitalInformation": "معلومات المستشفى",
@ -1239,6 +1240,7 @@
"hmgServices": "خدمات مجموعة الحبيب الطبية", "hmgServices": "خدمات مجموعة الحبيب الطبية",
"personalServices": "الخدمات الشخصية", "personalServices": "الخدمات الشخصية",
"habibWallet": "محفظة الحبيب", "habibWallet": "محفظة الحبيب",
"habibWallet2": "المحفظة",
"loginToViewWalletBalance": "سجل الدخول لعرض رصيد محفظتك", "loginToViewWalletBalance": "سجل الدخول لعرض رصيد محفظتك",
"recharge": "إعادة الشحن", "recharge": "إعادة الشحن",
"loginToViewMedicalFile": "سجل الدخول لعرض ملفك الطبي", "loginToViewMedicalFile": "سجل الدخول لعرض ملفك الطبي",
@ -1297,7 +1299,7 @@
"referenceRange": "النطاق المرجعي", "referenceRange": "النطاق المرجعي",
"downloadReport": "تحميل التقارير", "downloadReport": "تحميل التقارير",
"generatingReport": "جارٍ إنشاء التقرير، يرجى الانتظار...", "generatingReport": "جارٍ إنشاء التقرير، يرجى الانتظار...",
"noLabResults": يس لديك أي نتائج مختبرية حتى الآن.", "noLabResults": ا يوجد نتائج",
"labResultDetails": "تفاصيل نتائج المختبر", "labResultDetails": "تفاصيل نتائج المختبر",
"resultOf": "نتيجة", "resultOf": "نتيجة",
"whatIsThisResult": "ما هي هذه النتيجة؟", "whatIsThisResult": "ما هي هذه النتيجة؟",
@ -1471,7 +1473,7 @@
"beforeSyncingDataFollowInstructions": "قبل مزامنة البيانات، يرجى التأكد من اتباع التعليمات بشكل صحيح.", "beforeSyncingDataFollowInstructions": "قبل مزامنة البيانات، يرجى التأكد من اتباع التعليمات بشكل صحيح.",
"viewWatchInstructions": "عرض تعليمات الساعة", "viewWatchInstructions": "عرض تعليمات الساعة",
"healthConnectAppNotInstalled": "يبدو أنه ليس لديك تطبيق Health Connect مثبتًا. يرجى تثبيته من متجر Play لمزامنة بيانات صحتك.", "healthConnectAppNotInstalled": "يبدو أنه ليس لديك تطبيق Health Connect مثبتًا. يرجى تثبيته من متجر Play لمزامنة بيانات صحتك.",
"setTimerOfReminder": "ضبط مؤقت التذكير", "setTimerOfReminder": "ضبط التذكير",
"youHaveAppointmentWithDr": "لديك موعد مع د. ", "youHaveAppointmentWithDr": "لديك موعد مع د. ",
"hours": "ساعات", "hours": "ساعات",
"minutes": "دقائق", "minutes": "دقائق",
@ -1536,7 +1538,7 @@
"notifyMeBeforeConsumptionTime": "أبلغني قبل وقت الاستهلاك", "notifyMeBeforeConsumptionTime": "أبلغني قبل وقت الاستهلاك",
"noMedicationsToday": "لا أدوية اليوم", "noMedicationsToday": "لا أدوية اليوم",
"reminders": "تذكيرات", "reminders": "تذكيرات",
"reminderAddedToCalendar": "تمت إضافة تذكير إلى التقويم ", "reminderAddedToCalendar": "تمت إضافة تذكير إلى التقويم ",
"errorWhileSettingCalendar": "حدث خطأ أثناء ضبط التقويم:{error}", "errorWhileSettingCalendar": "حدث خطأ أثناء ضبط التقويم:{error}",
"instructions": "التعليمات", "instructions": "التعليمات",
"requests": "الطلبات", "requests": "الطلبات",
@ -1562,14 +1564,14 @@
"bmi": "مؤشر كتلة الجسم", "bmi": "مؤشر كتلة الجسم",
"yesPleaseINeedHelp": "نعم، من فضلك أريد المساعدة", "yesPleaseINeedHelp": "نعم، من فضلك أريد المساعدة",
"aiOverView": "AI ملخص", "aiOverView": "AI ملخص",
"generateAiAnalysis": "قم بإجراء تحليل لهذا الطلب AI", "generateAiAnalysis": "التحليل باستخدام الذكاء الاصطناعي",
"aiAnalysis": "AI تحليل", "aiAnalysis": "AI تحليل",
"prediction": "تنبؤ", "prediction": "التوقعات",
"prevention": "الوقاية", "prevention": "الوقاية",
"disclaimer": "تنبيه", "disclaimer": "تنبيه",
"thisAboveInfo": "المعلومات المذكورة أعلاه مُولّدة بواسطة AI بناءً على نتائج تحاليلك المخبرية، وهي لأغراض إعلامية فقط. لا ينبغي اعتبارها تشخيصًا طبيًا أو خطة علاجية. استشر طبيبك دائمًا للحصول على نصيحة طبية مُخصصة قبل اتخاذ أي قرارات تتعلق بصحتك.", "thisAboveInfo": "المعلومات المذكورة أعلاه مُولّدة بواسطة AI بناءً على نتائج تحاليلك المخبرية، وهي لأغراض إعلامية فقط. لا ينبغي اعتبارها تشخيصًا طبيًا أو خطة علاجية. استشر طبيبك دائمًا للحصول على نصيحة طبية مُخصصة قبل اتخاذ أي قرارات تتعلق بصحتك.",
"aiDisclaimer": "سيتم مشاركة بيانات نتائج تحاليلك المخبرية بشكل آمن مع خدمة الذكاء الاصطناعي لدينا لتحليلها. يساعد هذا في تقديم رؤى صحية مُخصصة. هل ترغب في المتابعة؟", "aiDisclaimer": "سيتم مشاركة بيانات نتائج تحاليلك المخبرية بشكل آمن مع خدمة الذكاء الاصطناعي لدينا لتحليلها. يساعد هذا في تقديم رؤى صحية مُخصصة. هل ترغب في المتابعة؟",
"consent": "موافقة", "consent": "نتائج المختبر",
"bmiNormalDescription": "مؤشر كتلة جسمك ضمن المعدل الصحي. استمر في اتباع نظام غذائي متوازن، وممارسة النشاط البدني بانتظام، وإجراء الفحوصات الدورية للحفاظ على صحة جيدة. راقب أي تغييرات ملحوظة مع مرور الوقت.", "bmiNormalDescription": "مؤشر كتلة جسمك ضمن المعدل الصحي. استمر في اتباع نظام غذائي متوازن، وممارسة النشاط البدني بانتظام، وإجراء الفحوصات الدورية للحفاظ على صحة جيدة. راقب أي تغييرات ملحوظة مع مرور الوقت.",
"bmiUnderweightDescription": "يشير مؤشر كتلة الجسم إلى أنك تعاني من نقص الوزن. لذا، يُنصح بزيادة السعرات الحرارية المتناولة من خلال تناول الأطعمة الغنية بالعناصر الغذائية، وممارسة تمارين المقاومة لبناء العضلات، واستشارة أخصائي رعاية صحية للتحقق من وجود أسباب كامنة.", "bmiUnderweightDescription": "يشير مؤشر كتلة الجسم إلى أنك تعاني من نقص الوزن. لذا، يُنصح بزيادة السعرات الحرارية المتناولة من خلال تناول الأطعمة الغنية بالعناصر الغذائية، وممارسة تمارين المقاومة لبناء العضلات، واستشارة أخصائي رعاية صحية للتحقق من وجود أسباب كامنة.",
"bmiOverweightDescription": "يشير مؤشر كتلة الجسم إلى زيادة الوزن. لذا، يُنصح بالسعي إلى إنقاص الوزن تدريجياً وبشكل مستدام من خلال تقليل السعرات الحرارية بشكل معتدل، وممارسة النشاط البدني بانتظام، واختيار الأطعمة الصحية. استشر طبيبك قبل إجراء أي تغييرات جذرية في نمط حياتك.", "bmiOverweightDescription": "يشير مؤشر كتلة الجسم إلى زيادة الوزن. لذا، يُنصح بالسعي إلى إنقاص الوزن تدريجياً وبشكل مستدام من خلال تقليل السعرات الحرارية بشكل معتدل، وممارسة النشاط البدني بانتظام، واختيار الأطعمة الصحية. استشر طبيبك قبل إجراء أي تغييرات جذرية في نمط حياتك.",
@ -1645,7 +1647,7 @@
"insuranceRequestSubmittedSuccessfully": "تم إرسال طلب تحديث بيانات التأمين بنجاح. سيتم إعلامك بمجرد الانتهاء.", "insuranceRequestSubmittedSuccessfully": "تم إرسال طلب تحديث بيانات التأمين بنجاح. سيتم إعلامك بمجرد الانتهاء.",
"updatingEmailAddress": "جارٍ تحديث عنوان البريد الإلكتروني، يرجى الانتظار...", "updatingEmailAddress": "جارٍ تحديث عنوان البريد الإلكتروني، يرجى الانتظار...",
"verifyInsurance": "التحقق من التأمين", "verifyInsurance": "التحقق من التأمين",
"tests": "تحليل", "tests": "تحاليل",
"calendarPermissionAlert": "يرجى منح إذن الوصول إلى التقويم من إعدادات التطبيق لضبط تذكير تناول الدواء.", "calendarPermissionAlert": "يرجى منح إذن الوصول إلى التقويم من إعدادات التطبيق لضبط تذكير تناول الدواء.",
"sortByNearestLocation": "حسب الأقرب الى موقعك", "sortByNearestLocation": "حسب الأقرب الى موقعك",
"giveLocationPermissionForNearestList": "يرجى منح إذن الوصول إلى الموقع من إعدادات التطبيق لعرض أقرب المواقع.", "giveLocationPermissionForNearestList": "يرجى منح إذن الوصول إلى الموقع من إعدادات التطبيق لعرض أقرب المواقع.",
@ -1673,7 +1675,7 @@
"homeHealthCareServiceHeader": "صحتك، في أبهى صورها. رعاية فائقة الجودة، تصلك إلى عتبة دارك.", "homeHealthCareServiceHeader": "صحتك، في أبهى صورها. رعاية فائقة الجودة، تصلك إلى عتبة دارك.",
"homeHealthCareServiceDescription": "نقدم لكم رعاية صحية عالية الجودة تصلكم إلى عتبة منزلكم. ممرضات ذوات خبرةممرضات ذوات خبرة يقدمون لكم الرعاية اللازمة.", "homeHealthCareServiceDescription": "نقدم لكم رعاية صحية عالية الجودة تصلكم إلى عتبة منزلكم. ممرضات ذوات خبرةممرضات ذوات خبرة يقدمون لكم الرعاية اللازمة.",
"profileOnlyText": "الملف الشخصي", "profileOnlyText": "الملف الشخصي",
"information": "معلومة", "information": "معلومات الطبيب",
"noFavouriteDoctors": "ليس لديك أي قائمة مفضلة حتى الآن", "noFavouriteDoctors": "ليس لديك أي قائمة مفضلة حتى الآن",
"addDoctors": "إضافة الأطباء", "addDoctors": "إضافة الأطباء",
"favouriteList": "قائمة المفضلة", "favouriteList": "قائمة المفضلة",

@ -196,6 +196,7 @@
"enterEmail": "Please Enter Email", "enterEmail": "Please Enter Email",
"family": "My Family", "family": "My Family",
"familyTitle": "My Family Files", "familyTitle": "My Family Files",
"familyTitle2": "My Family Files",
"addNewMember": "Add Family Member", "addNewMember": "Add Family Member",
"sentRequests": "Sent Requests", "sentRequests": "Sent Requests",
"recievedRequests": "Recieved Requests", "recievedRequests": "Recieved Requests",
@ -1229,6 +1230,7 @@
"hmgServices": "HMG Services", "hmgServices": "HMG Services",
"personalServices": "Personal Services", "personalServices": "Personal Services",
"habibWallet": "Habib Wallet", "habibWallet": "Habib Wallet",
"habibWallet2": "Habib Wallet",
"loginToViewWalletBalance": "Login to view your wallet balance", "loginToViewWalletBalance": "Login to view your wallet balance",
"loginToViewMedicalFile": "Login to view your medical file", "loginToViewMedicalFile": "Login to view your medical file",
"addMember": "Add Member", "addMember": "Add Member",

@ -94,24 +94,33 @@ class AppState {
String? get getProfileImageData => _profileImageData; String? get getProfileImageData => _profileImageData;
set setProfileImageData(String? value) { set setProfileImageData(String? value) {
// Clear old data first
if (_profileImageData != null && _profileImageData != value) {
print('🔄 Replacing profile image: old data length=${_profileImageData!.length}, new data length=${value?.length ?? 0}');
}
// Set new value directly WITHOUT caching
_profileImageData = value; _profileImageData = value;
// Persist to cache
if (value != null && value.isNotEmpty) { if (value != null && value.isNotEmpty) {
cacheService.saveString(key: _profileImageKey, value: value); print('✅ Profile image set (length: ${value.length}) - NO CACHE');
} else { } else {
cacheService.remove(key: _profileImageKey); print('🗑️ Profile image cleared - NO CACHE');
} }
} }
/// Load profile image from cache on app initialization /// Load profile image from cache on app initialization - DISABLED
void _loadProfileImageFromCache() { void _loadProfileImageFromCache() {
_profileImageData = cacheService.getString(key: _profileImageKey); // DO NOT LOAD FROM CACHE - always fetch fresh from API
_profileImageData = null;
print('📂 Profile image cache disabled - will fetch from API');
} }
/// Clear profile image from cache (e.g., on logout) /// Clear profile image data (e.g., on logout or user switch)
void clearProfileImageCache() { void clearProfileImageCache() {
print('🧹 Clearing profile image data (was: ${_profileImageData != null ? "${_profileImageData!.length} chars" : "null"})');
_profileImageData = null; _profileImageData = null;
cacheService.remove(key: _profileImageKey); print('✅ Profile image data cleared - NO CACHE');
} }
SelectDeviceByImeiRespModelElement? _selectDeviceByImeiRespModelElement; SelectDeviceByImeiRespModelElement? _selectDeviceByImeiRespModelElement;

@ -1240,6 +1240,12 @@ class AuthenticationViewModel extends ChangeNotifier {
try { try {
log("Fetching profile image for patient ID: $patientID"); log("Fetching profile image for patient ID: $patientID");
// IMPORTANT: Clear old cache BEFORE fetching new image
// This ensures old data is removed immediately
_appState.clearProfileImageCache();
log("🧹 Cleared profile image cache before fetch");
final profileSettingsRepo = GetIt.instance<ProfileSettingsRepo>(); final profileSettingsRepo = GetIt.instance<ProfileSettingsRepo>();
final result = await profileSettingsRepo.getProfileImage(patientID: patientID); final result = await profileSettingsRepo.getProfileImage(patientID: patientID);
@ -1247,6 +1253,8 @@ class AuthenticationViewModel extends ChangeNotifier {
(failure) { (failure) {
// Silently fail - profile image is optional // Silently fail - profile image is optional
log("Failed to fetch profile image: ${failure.message}"); log("Failed to fetch profile image: ${failure.message}");
// Ensure cache is cleared even on failure
_appState.setProfileImageData = null;
}, },
(apiResponse) { (apiResponse) {
if (apiResponse.data != null && apiResponse.data['Patient_GetProfileImageDataList'] != null) { if (apiResponse.data != null && apiResponse.data['Patient_GetProfileImageDataList'] != null) {
@ -1254,21 +1262,26 @@ class AuthenticationViewModel extends ChangeNotifier {
if (imageList is List && imageList.isNotEmpty) { if (imageList is List && imageList.isNotEmpty) {
String? imageData = imageList[0]['ImageData']; String? imageData = imageList[0]['ImageData'];
if (imageData != null && imageData.isNotEmpty) { if (imageData != null && imageData.isNotEmpty) {
// Set new profile image data - this will update cache and notify all listeners
_appState.setProfileImageData = imageData; _appState.setProfileImageData = imageData;
log("✅ Profile image loaded and cached successfully"); log("✅ Profile image loaded and cached successfully for patient: $patientID");
} else { } else {
log("⚠️ Profile image data is empty"); log("⚠️ Profile image data is empty for patient: $patientID");
_appState.setProfileImageData = null;
} }
} else { } else {
log("⚠️ Profile image list is empty"); log("⚠️ Profile image list is empty for patient: $patientID");
_appState.setProfileImageData = null;
} }
} else { } else {
log("⚠️ No profile image data in response"); log("⚠️ No profile image data in response for patient: $patientID");
_appState.setProfileImageData = null;
} }
}, },
); );
} catch (e) { } catch (e) {
log("❌ Error fetching profile image: $e"); log("❌ Error fetching profile image: $e");
_appState.setProfileImageData = null;
} }
} }
} }

@ -151,7 +151,7 @@ class ProfileSettingsRepoImp implements ProfileSettingsRepo {
} }
@override @override
Future<Either<Failure, GenericApiModel<dynamic>>> getProfileImage({ Future<Either<Failure, GenericApiModel<dynamic>>> getProfileImage({
required int patientID, required int patientID,
}) async { }) async {
final Map<String, dynamic> body = { final Map<String, dynamic> body = {

@ -189,19 +189,15 @@ class ProfileSettingsViewModel extends ChangeNotifier {
Function(String)? onError, Function(String)? onError,
bool forceRefresh = false, // Add flag to force refresh bool forceRefresh = false, // Add flag to force refresh
}) async { }) async {
// Skip API call if image is already loaded and not forcing refresh print('🌐 Fetching profile image from API for patient: $patientID (forceRefresh: $forceRefresh)');
if (!forceRefresh && GetIt.instance<AppState>().getProfileImageData != null) {
// Use cached data // IMPORTANT: Always clear old data BEFORE fetching
profileImageData = GetIt.instance<AppState>().getProfileImageData; // Do NOT use cached data - always fetch fresh from API
if (onSuccess != null) { profileImageData = null;
onSuccess(profileImageData);
}
return;
}
isProfileImageLoading = true; isProfileImageLoading = true;
profileImageError = null; profileImageError = null;
notifyListeners(); notifyListeners(); // Notify to show loading state
final result = await profileSettingsRepo.getProfileImage(patientID: patientID); final result = await profileSettingsRepo.getProfileImage(patientID: patientID);
@ -209,6 +205,11 @@ class ProfileSettingsViewModel extends ChangeNotifier {
(failure) { (failure) {
isProfileImageLoading = false; isProfileImageLoading = false;
profileImageError = failure.message; profileImageError = failure.message;
print('❌ Failed to fetch profile image: ${failure.message}');
// Ensure data is cleared on failure
profileImageData = null;
notifyListeners(); notifyListeners();
if (onError != null) { if (onError != null) {
onError(failure.message); onError(failure.message);
@ -216,44 +217,48 @@ class ProfileSettingsViewModel extends ChangeNotifier {
}, },
(response) { (response) {
isProfileImageLoading = false; isProfileImageLoading = false;
// Extract image data from response // Extract image data from response
if (response.data != null && response.data['Patient_GetProfileImageDataList'] != null) { if (response.data != null && response.data['Patient_GetProfileImageDataList'] != null) {
var imageList = response.data['Patient_GetProfileImageDataList']; var imageList = response.data['Patient_GetProfileImageDataList'];
if (imageList is List && imageList.isNotEmpty) { if (imageList is List && imageList.isNotEmpty) {
profileImageData = imageList[0]['ImageData']; profileImageData = imageList[0]['ImageData'];
// Store in AppState for global access
GetIt.instance<AppState>().setProfileImageData = profileImageData;
if (profileImageData != null && profileImageData!.isNotEmpty) {
// ONLY store in ViewModel - AppState will be updated separately by auth flow
print('✅ Profile image loaded from API (length: ${profileImageData!.length})');
} else {
profileImageData = null;
print('⚠️ Profile image data is empty in API response');
}
} else { } else {
profileImageData = null; profileImageData = null;
GetIt.instance<AppState>().setProfileImageData = null; print('⚠️ Profile image list is empty in API response');
} }
} else { } else {
profileImageData = null; profileImageData = null;
GetIt.instance<AppState>().setProfileImageData = null; print('⚠️ No profile image data in API response');
} }
notifyListeners();
notifyListeners(); // Notify to update UI with new/null data
onSuccess?.call(response.data); onSuccess?.call(response.data);
}, },
); );
} }
/// Clear cached profile image data /// Clear profile image data from ViewModel
void clearProfileImageCache() { void clearProfileImageCache() {
print('🧹 Clearing profile image from ViewModel');
profileImageData = null; profileImageData = null;
GetIt.instance<AppState>().setProfileImageData = null;
notifyListeners(); notifyListeners();
} }
/// Sync profile image data from AppState /// Sync profile image data from AppState - DISABLED
/// Profile Settings screen uses only ViewModel data from API
void syncProfileImageFromAppState() { void syncProfileImageFromAppState() {
final appStateImageData = GetIt.instance<AppState>().getProfileImageData; // DO NOTHING - Profile Settings uses only direct API data
if (appStateImageData != null && appStateImageData.isNotEmpty) { // No syncing from AppState to avoid stale cache issues
if (profileImageData != appStateImageData) { print('⚠️ syncProfileImageFromAppState called but disabled - use API data only');
profileImageData = appStateImageData;
notifyListeners();
}
}
} }
Future<void> uploadProfileImage({ Future<void> uploadProfileImage({

@ -99,6 +99,8 @@ class CodegenLoader extends AssetLoader{
"bookSuccessConfirmMore2412": "ستكون عملية الدفع عبر الإنترنت متاحة قبل 24 ساعة <20><>ن الموعد.", "bookSuccessConfirmMore2412": "ستكون عملية الدفع عبر الإنترنت متاحة قبل 24 ساعة <20><>ن الموعد.",
"upcomingPaymentPending": "سيتم تفعيل الدفع عبر الإنترنت قبل 24 ساعة من موعد الموعد", "upcomingPaymentPending": "سيتم تفعيل الدفع عبر الإنترنت قبل 24 ساعة من موعد الموعد",
"upcomingPaymentNow": "ادفع عبر الإنترنت الآن لتجنب الانتظار الطويل", "upcomingPaymentNow": "ادفع عبر الإنترنت الآن لتجنب الانتظار الطويل",
"timeUntilAppointment": "الوقت المتبقي حتى الموعد",
"appointmentTimePassed": "انتهى وقت الموعد",
"upcomingQR": "استخدم رمز الاستجابة السريعة لتسجيل الوصول في المستشفى", "upcomingQR": "استخدم رمز الاستجابة السريعة لتسجيل الوصول في المستشفى",
"upcomingVirtual": "هذا موعد افتراضي، يرجى الالتزام بالتعليمات لتجربة سلسة.", "upcomingVirtual": "هذا موعد افتراضي، يرجى الالتزام بالتعليمات لتجربة سلسة.",
"upcomingLivecare": "هذا موعد لايف كير", "upcomingLivecare": "هذا موعد لايف كير",
@ -212,6 +214,7 @@ class CodegenLoader extends AssetLoader{
"enterEmail": "يرجى إدخال البريد الإلكتروني", "enterEmail": "يرجى إدخال البريد الإلكتروني",
"family": "عائلتي", "family": "عائلتي",
"familyTitle": "ملفات عائلتي", "familyTitle": "ملفات عائلتي",
"familyTitle2": "ملفات العائلة",
"myFamily": "عائلتي", "myFamily": "عائلتي",
"addNewMember": "إضافة فرد جديد للعائلة", "addNewMember": "إضافة فرد جديد للعائلة",
"sentRequests": "الطلبات المرسلة", "sentRequests": "الطلبات المرسلة",
@ -232,7 +235,7 @@ class CodegenLoader extends AssetLoader{
"unit": "الوحدة", "unit": "الوحدة",
"request": "طلب", "request": "طلب",
"memberName": "اسم العضو", "memberName": "اسم العضو",
"switchLogin": "تبديل", "switchLogin": "عرض",
"removeMember": "إزالة", "removeMember": "إزالة",
"allowView": "السماح", "allowView": "السماح",
"rejectView": "رفض", "rejectView": "رفض",
@ -289,7 +292,7 @@ class CodegenLoader extends AssetLoader{
"parkingDescription": "خدمة المواقف هي لك لمسح موقع السيارة حتى تتمكن من العثور عليها بسهولة عند مغادرتك. انقر على زر (مسح الموقف) لحفظ موقع الموقف، ثم سيظهر زر (عرض موقفي) لإظهار الطريق إلى الموقف. إذا كنت ترغب في إعادة مسح موقف السيارة QR فقط انقر على (مسح بياناتي).", "parkingDescription": "خدمة المواقف هي لك لمسح موقع السيارة حتى تتمكن من العثور عليها بسهولة عند مغادرتك. انقر على زر (مسح الموقف) لحفظ موقع الموقف، ثم سيظهر زر (عرض موقفي) لإظهار الطريق إلى الموقف. إذا كنت ترغب في إعادة مسح موقف السيارة QR فقط انقر على (مسح بياناتي).",
"appointments": "المواعيد", "appointments": "المواعيد",
"all2": "الكل", "all2": "الكل",
"checkinOption": "تسجيل الوصول", "checkinOption": "تسجيل الحضور",
"readBarcode": "قراءة الكود", "readBarcode": "قراءة الكود",
"showMyPark": "عرض الموقف", "showMyPark": "عرض الموقف",
"clearMyData": "امسح البيانات", "clearMyData": "امسح البيانات",
@ -311,7 +314,7 @@ class CodegenLoader extends AssetLoader{
"radiology": "الأشعة", "radiology": "الأشعة",
"radiologySubtitle": "النتيجة", "radiologySubtitle": "النتيجة",
"lab": "المختبر", "lab": "المختبر",
"labSubtitle": "النتائج", "labSubtitle": "نتائج",
"medicines": "الأدوية", "medicines": "الأدوية",
"medicinesSubtitle": "الوصفات", "medicinesSubtitle": "الوصفات",
"vitalSigns": "علامات حيوية", "vitalSigns": "علامات حيوية",
@ -327,9 +330,11 @@ class CodegenLoader extends AssetLoader{
"myMedicalSubtitle": "الأدوية", "myMedicalSubtitle": "الأدوية",
"myDoctor": "أطبائي", "myDoctor": "أطبائي",
"myDoctorSubtitle": "القائمة", "myDoctorSubtitle": "القائمة",
"myDoctorSubtitle2": "قائمة",
"eye": "العين", "eye": "العين",
"eyeSubtitle": "القياس", "eyeSubtitle": "القياس",
"insurance": "التأمين", "insurance": "التأمين",
"insurance2": "تأمين",
"insuranceSubtitle": "البطاقة", "insuranceSubtitle": "البطاقة",
"updateInsurance": "تحديث", "updateInsurance": "تحديث",
"updateInsuranceSubtitle": "التأمين", "updateInsuranceSubtitle": "التأمين",
@ -344,6 +349,7 @@ class CodegenLoader extends AssetLoader{
"monthly": "شهري", "monthly": "شهري",
"monthlySubtitle": "التقرير", "monthlySubtitle": "التقرير",
"sick": "مريض", "sick": "مريض",
"sick2": "المريضة",
"sickSubtitle": "الإجازات", "sickSubtitle": "الإجازات",
"myBalance": "رصيدي", "myBalance": "رصيدي",
"myBalanceSubtitle": "الرصيد", "myBalanceSubtitle": "الرصيد",
@ -497,7 +503,7 @@ class CodegenLoader extends AssetLoader{
"shareReview": "شارك التقييم", "shareReview": "شارك التقييم",
"review": " التقييمات", "review": " التقييمات",
"viewMedicalFile": "عرض التفاصيل", "viewMedicalFile": "عرض التفاصيل",
"viewAllServices": "عرض جميع الخدمات", "viewAllServices": "جميع الخدمات",
"medicalFile": "الملف الطبي", "medicalFile": "الملف الطبي",
"verified": "تم التحقق", "verified": "تم التحقق",
"checkup": "فحص", "checkup": "فحص",
@ -506,9 +512,11 @@ class CodegenLoader extends AssetLoader{
"refferalTitle": "إحالة إلكترونية", "refferalTitle": "إحالة إلكترونية",
"refferalSubTitle": "الخدمة", "refferalSubTitle": "الخدمة",
"healthCare": "الرعاية الصحية", "healthCare": "الرعاية الصحية",
"emergency": "حالة طوارئ", "emergency": "طوارئ",
"emergency2": "الطوارئ",
"erservices": "خدمات الطوارئ", "erservices": "خدمات الطوارئ",
"services2": "الخدمات", "services2": "الخدمات",
"services3": "خدمات",
"cantSeeProfile": "لرؤية ملفك الطبي، يرجى تسجيل الدخول أو التسجيل الآن", "cantSeeProfile": "لرؤية ملفك الطبي، يرجى تسجيل الدخول أو التسجيل الآن",
"loginRegisterNow": "تسجيل الدخول أو التسجيل الآن", "loginRegisterNow": "تسجيل الدخول أو التسجيل الآن",
"hmgPharmacy": "صيدلية الحبيب", "hmgPharmacy": "صيدلية الحبيب",
@ -779,6 +787,7 @@ class CodegenLoader extends AssetLoader{
"erConsultation": "تتيح لك هذه الخدمة إجراء استشارة افتراضية عبر الإنترنت عبر مكالمة فيديو مباشرة مع الطبيب من أي مكان وفي أي وقت.", "erConsultation": "تتيح لك هذه الخدمة إجراء استشارة افتراضية عبر الإنترنت عبر مكالمة فيديو مباشرة مع الطبيب من أي مكان وفي أي وقت.",
"myInvoice": "القائمة", "myInvoice": "القائمة",
"invoiceList": "فواتيري", "invoiceList": "فواتيري",
"invoiceList2": "فواتيري",
"allInvoices": "كل الفواتير", "allInvoices": "كل الفواتير",
"hospitals": "المستشفيات", "hospitals": "المستشفيات",
"clinics": "العيادات", "clinics": "العيادات",
@ -933,7 +942,7 @@ class CodegenLoader extends AssetLoader{
"totalAmountToPay": "المبلغ الإجمالي المستحق", "totalAmountToPay": "المبلغ الإجمالي المستحق",
"vat15": "ضريبة القيمة المضافة 15%", "vat15": "ضريبة القيمة المضافة 15%",
"liveCare": "لايف كير", "liveCare": "لايف كير",
"recentVisits": "الزيارات الأخيرة", "recentVisits": "قائمة الزيارات",
"favouriteDoctors": "الأطباء المفضلون", "favouriteDoctors": "الأطباء المفضلون",
"searchByClinic": "البحث حسب العيادة", "searchByClinic": "البحث حسب العيادة",
"tapToSelectClinic": "انقر لاختيار العيادة", "tapToSelectClinic": "انقر لاختيار العيادة",
@ -944,7 +953,7 @@ class CodegenLoader extends AssetLoader{
"immediateConsultation": "استشارة فورية", "immediateConsultation": "استشارة فورية",
"scheduledConsultation": "استشارة مجدولة", "scheduledConsultation": "استشارة مجدولة",
"pharmaLiveCare": "لايف كير الصيدلية", "pharmaLiveCare": "لايف كير الصيدلية",
"notSureHelpMeChooseClinic": "غير متأكد؟ ساعدني في اختيار عيادة!", "notSureHelpMeChooseClinic": "هل تريد مساعدة في اختيار العياة؟",
"mentionYourSymptomsAndFindDoctors": "اذكر أعراضك واعثر على قائمة الأطباء وفقاً لذلك", "mentionYourSymptomsAndFindDoctors": "اذكر أعراضك واعثر على قائمة الأطباء وفقاً لذلك",
"immediateService": "خدمة فورية", "immediateService": "خدمة فورية",
"noNeedToWaitGetMedicalConsultation": "لا حاجة للانتظار، ستحصل على استشارة طبية فورية عبر مكالمة فيديو", "noNeedToWaitGetMedicalConsultation": "لا حاجة للانتظار، ستحصل على استشارة طبية فورية عبر مكالمة فيديو",
@ -954,7 +963,7 @@ class CodegenLoader extends AssetLoader{
"freeMedicineDelivery": "توصيل مجاني للأدوية", "freeMedicineDelivery": "توصيل مجاني للأدوية",
"offersFreeMedicineDelivery": "يوفر توصيل مجاني للأدوية لموعد لايف كير", "offersFreeMedicineDelivery": "يوفر توصيل مجاني للأدوية لموعد لايف كير",
"dentalChiefComplaints": "الشكاوى الرئيسة للأسنان", "dentalChiefComplaints": "الشكاوى الرئيسة للأسنان",
"viewAvailableAppointments": "عرض المواعيد المتاحة", "viewAvailableAppointments": "المواعيد المتاحة",
"doctorProfile": " ملف الطبيب", "doctorProfile": " ملف الطبيب",
"waitingAppointment": "موعد الانتظار", "waitingAppointment": "موعد الانتظار",
"hospitalInformation": "معلومات المستشفى", "hospitalInformation": "معلومات المستشفى",
@ -1008,7 +1017,7 @@ class CodegenLoader extends AssetLoader{
"processingCheckIn": "جاري معالجة تسجيل الحضور...", "processingCheckIn": "جاري معالجة تسجيل الحضور...",
"bookingWaitingAppointment": "جاري حجز موعد الانتظار، يرجى الانتظار...", "bookingWaitingAppointment": "جاري حجز موعد الانتظار، يرجى الانتظار...",
"enterValidIDorIqama": "يرجى إدخال رقم هوية وطنية أو رقم ملف صالح", "enterValidIDorIqama": "يرجى إدخال رقم هوية وطنية أو رقم ملف صالح",
"selectAppointment": "حدد الموعد", "selectAppointment": "اختر الموعد",
"rebookSameDoctor": "أعد الحجز مع نفس الطبيب", "rebookSameDoctor": "أعد الحجز مع نفس الطبيب",
"queueing": "قائمة الانتظار", "queueing": "قائمة الانتظار",
"inQueue": "في قائمة الانتظار", "inQueue": "في قائمة الانتظار",
@ -1181,14 +1190,22 @@ class CodegenLoader extends AssetLoader{
"monitorCholesterolLevels": "راقب مستويات الكوليسترول، وقيّم مخاطر صحة القلب، واتخذ خطوات استباقية للرفاهية.", "monitorCholesterolLevels": "راقب مستويات الكوليسترول، وقيّم مخاطر صحة القلب، واتخذ خطوات استباقية للرفاهية.",
"triglyceridesFatBlood": "الدهون الثلاثية في الدم", "triglyceridesFatBlood": "الدهون الثلاثية في الدم",
"understandTriglyceridesImpact": "افهم تأثير الدهون الثلاثية على صحة القلب مع رؤى مخصصة وتوصيات الخبراء.", "understandTriglyceridesImpact": "افهم تأثير الدهون الثلاثية على صحة القلب مع رؤى مخصصة وتوصيات الخبراء.",
"bmiCalculator": "حاسبة\nمؤشر كتلة الجسم", "bmiCalculator": "حاسبة مؤشر كتلة الجسم",
"caloriesCalculator": "حاسبة\nالسعرات الحرارية", "bmiCalculatorDesc": "احسب مؤشر كتلة جسمك لفهم نطاق وزنك الصحي.",
"bmrCalculator": "حاسبة\nمعدل الأيض الأساسي", "caloriesCalculator": "حاسبةالسعرات الحرارية",
"idealBodyWeight": "الوزن المثالي\nللجسم", "caloriesCalculatorDesc": "اكتشف عدد السعرات الحرارية التي تحتاجها يومياً للحفاظ على الوزن أو فقدانه.",
"bodyFatCalculator": "حاسبة\nدهون الجسم", "bmrCalculator": "حاسبة معدل الأيض الأساسي",
"carbsProteinFat": "الكربوهيدرات\nالبروتين والدهون", "bmrCalculatorDesc": "حدد معدل الأيض الأساسي ومتطلباتك اليومية من الطاقة.",
"ovulationPeriod": "فترة\nالإباضة", "idealBodyWeight": "الوزن المثالي للجسم",
"deliveryDueDate": "تاريخ الولادة\nالمتوقع", "idealBodyWeightDesc": "اكتشف وزنك المثالي بناءً على الطول والعمر وبنية الجسم.",
"bodyFatCalculator": "حاسبة دهون الجسم",
"bodyFatCalculatorDesc": "قدّر نسبة دهون جسمك لتتبع أهداف اللياقة والصحة.",
"carbsProteinFat": "الكربوهيدرات البروتين والدهون",
"carbsProteinFatDesc": "وازن بين العناصر الغذائية مع النسب الصحيحة من الكربوهيدرات والبروتين والدهون.",
"ovulationPeriod": "فترة الإباضة",
"ovulationPeriodDesc": "تتبع فترة خصوبتك وخطط للحمل بدقة.",
"deliveryDueDate": "تاريخ الولادة المتوقع",
"deliveryDueDateDesc": "احسب تاريخ ولادتك المتوقع وراقب مراحل الحمل.",
"low": "منخفض", "low": "منخفض",
"preDiabetic": "ما قبل السكري", "preDiabetic": "ما قبل السكري",
"high": "مرتفع", "high": "مرتفع",
@ -1233,6 +1250,7 @@ class CodegenLoader extends AssetLoader{
"hmgServices": "خدمات مجموعة الحبيب الطبية", "hmgServices": "خدمات مجموعة الحبيب الطبية",
"personalServices": "الخدمات الشخصية", "personalServices": "الخدمات الشخصية",
"habibWallet": "محفظة الحبيب", "habibWallet": "محفظة الحبيب",
"habibWallet2": "المحفظة",
"loginToViewWalletBalance": "سجل الدخول لعرض رصيد محفظتك", "loginToViewWalletBalance": "سجل الدخول لعرض رصيد محفظتك",
"loginToViewMedicalFile": "سجل الدخول لعرض ملفك الطبي", "loginToViewMedicalFile": "سجل الدخول لعرض ملفك الطبي",
"addMember": "إضافة عضو", "addMember": "إضافة عضو",
@ -1290,7 +1308,7 @@ class CodegenLoader extends AssetLoader{
"referenceRange": "النطاق المرجعي", "referenceRange": "النطاق المرجعي",
"downloadReport": "تنزيل التقرير", "downloadReport": "تنزيل التقرير",
"generatingReport": "جارٍ إنشاء التقرير، يرجى الانتظار...", "generatingReport": "جارٍ إنشاء التقرير، يرجى الانتظار...",
"noLabResults": "ليس لديك أي نتائج مختبرية حتى الآن.", "noLabResults": "لا يوجد نتائج",
"labResultDetails": "تفاصيل نتائج المختبر", "labResultDetails": "تفاصيل نتائج المختبر",
"resultOf": "نتيجة {date}", "resultOf": "نتيجة {date}",
"whatIsThisResult": "ما هي هذه النتيجة؟", "whatIsThisResult": "ما هي هذه النتيجة؟",
@ -1302,7 +1320,7 @@ class CodegenLoader extends AssetLoader{
"rebook": "إعادة الحجز", "rebook": "إعادة الحجز",
"noOphthalmologyAppointments": "لم يتم العثور على أي مواعيد في قسم طب العيون...", "noOphthalmologyAppointments": "لم يتم العثور على أي مواعيد في قسم طب العيون...",
"noVitalSignsRecordedYet": "لا توجد علامات حيوية مسجلة بعد", "noVitalSignsRecordedYet": "لا توجد علامات حيوية مسجلة بعد",
"appointmentsAndVisits": "المواعيد والزيارات", "appointmentsAndVisits": "المواعيد",
"labAndRadiology": "المختبر والأشعة", "labAndRadiology": "المختبر والأشعة",
"activeMedicationsAndPrescriptions": "الوصفات الطبية", "activeMedicationsAndPrescriptions": "الوصفات الطبية",
"allPrescriptions": "جميع الوصفات", "allPrescriptions": "جميع الوصفات",
@ -1463,7 +1481,7 @@ class CodegenLoader extends AssetLoader{
"beforeSyncingDataFollowInstructions": "قبل مزامنة البيانات، يرجى التأكد من اتباع التعليمات بشكل صحيح.", "beforeSyncingDataFollowInstructions": "قبل مزامنة البيانات، يرجى التأكد من اتباع التعليمات بشكل صحيح.",
"viewWatchInstructions": "عرض تعليمات الساعة", "viewWatchInstructions": "عرض تعليمات الساعة",
"healthConnectAppNotInstalled": "يبدو أنه ليس لديك تطبيق Health Connect مثبتًا. يرجى تثبيته من متجر Play لمزامنة بيانات صحتك.", "healthConnectAppNotInstalled": "يبدو أنه ليس لديك تطبيق Health Connect مثبتًا. يرجى تثبيته من متجر Play لمزامنة بيانات صحتك.",
"setTimerOfReminder": "ضبط مؤقت التذكير", "setTimerOfReminder": "ضبط التذكير",
"youHaveAppointmentWithDr": "لديك موعد مع د. ", "youHaveAppointmentWithDr": "لديك موعد مع د. ",
"hours": "ساعات", "hours": "ساعات",
"minutes": "دقائق", "minutes": "دقائق",
@ -1477,6 +1495,7 @@ class CodegenLoader extends AssetLoader{
"distanceDescription": "المسافة المقطوعة على مدار اليوم", "distanceDescription": "المسافة المقطوعة على مدار اليوم",
"overview": "نظرة عامة", "overview": "نظرة عامة",
"details": "التفاصيل", "details": "التفاصيل",
"details2": "تفاصيل",
"healthy": "صحي", "healthy": "صحي",
"warning": "تحذير", "warning": "تحذير",
"vitalSignDetails": "تفاصيل العلامات الحيوية", "vitalSignDetails": "تفاصيل العلامات الحيوية",
@ -1526,7 +1545,7 @@ class CodegenLoader extends AssetLoader{
"notifyMeBeforeConsumptionTime": "أبلغني قبل وقت الاستهلاك", "notifyMeBeforeConsumptionTime": "أبلغني قبل وقت الاستهلاك",
"noMedicationsToday": "لا أدوية اليوم", "noMedicationsToday": "لا أدوية اليوم",
"reminders": "تذكيرات", "reminders": "تذكيرات",
"reminderAddedToCalendar": "تمت إضافة تذكير إلى التقويم ", "reminderAddedToCalendar": "تمت إضافة تذكير إلى التقويم ",
"errorWhileSettingCalendar": "حدث خطأ أثناء ضبط التقويم:{error}", "errorWhileSettingCalendar": "حدث خطأ أثناء ضبط التقويم:{error}",
"instructions": "التعليمات", "instructions": "التعليمات",
"requests": "الطلبات", "requests": "الطلبات",
@ -1552,14 +1571,14 @@ class CodegenLoader extends AssetLoader{
"bmi": "مؤشر كتلة الجسم", "bmi": "مؤشر كتلة الجسم",
"yesPleaseINeedHelp": "نعم، من فضلك أريد المساعدة", "yesPleaseINeedHelp": "نعم، من فضلك أريد المساعدة",
"aiOverView": "AI ملخص", "aiOverView": "AI ملخص",
"generateAiAnalysis": "قم بإجراء تحليل لهذا الطلب AI", "generateAiAnalysis": "التحليل باستخدام الذكاء الاصطناعي",
"aiAnalysis": "AI تحليل", "aiAnalysis": "AI تحليل",
"prediction": "تنبؤ", "prediction": "التوقعات",
"prevention": "وقاية", "prevention": "وقاية",
"disclaimer": "تنصل", "disclaimer": "تنصل",
"thisAboveInfo": "المعلومات المذكورة أعلاه مُولّدة بواسطة AI بناءً على نتائج تحاليلك المخبرية، وهي لأغراض إعلامية فقط. لا ينبغي اعتبارها تشخيصًا طبيًا أو خطة علاجية. استشر طبيبك دائمًا للحصول على نصيحة طبية مُخصصة قبل اتخاذ أي قرارات تتعلق بصحتك.", "thisAboveInfo": "المعلومات المذكورة أعلاه مُولّدة بواسطة AI بناءً على نتائج تحاليلك المخبرية، وهي لأغراض إعلامية فقط. لا ينبغي اعتبارها تشخيصًا طبيًا أو خطة علاجية. استشر طبيبك دائمًا للحصول على نصيحة طبية مُخصصة قبل اتخاذ أي قرارات تتعلق بصحتك.",
"aiDisclaimer": "سيتم مشاركة بيانات نتائج تحاليلك المخبرية بشكل آمن مع خدمة الذكاء الاصطناعي لدينا لتحليلها. يساعد هذا في تقديم رؤى صحية مُخصصة. هل ترغب في المتابعة؟", "aiDisclaimer": "سيتم مشاركة بيانات نتائج تحاليلك المخبرية بشكل آمن مع خدمة الذكاء الاصطناعي لدينا لتحليلها. يساعد هذا في تقديم رؤى صحية مُخصصة. هل ترغب في المتابعة؟",
"consent": "موافقة", "consent": "نتائج المختبر",
"bmiNormalDescription": "مؤشر كتلة جسمك ضمن المعدل الصحي. استمر في اتباع نظام غذائي متوازن، وممارسة النشاط البدني بانتظام، وإجراء الفحوصات الدورية للحفاظ على صحة جيدة. راقب أي تغييرات ملحوظة مع مرور الوقت.", "bmiNormalDescription": "مؤشر كتلة جسمك ضمن المعدل الصحي. استمر في اتباع نظام غذائي متوازن، وممارسة النشاط البدني بانتظام، وإجراء الفحوصات الدورية للحفاظ على صحة جيدة. راقب أي تغييرات ملحوظة مع مرور الوقت.",
"bmiUnderweightDescription": "يشير مؤشر كتلة الجسم إلى أنك تعاني من نقص الوزن. لذا، يُنصح بزيادة السعرات الحرارية المتناولة من خلال تناول الأطعمة الغنية بالعناصر الغذائية، وممارسة تمارين المقاومة لبناء العضلات، واستشارة أخصائي رعاية صحية للتحقق من وجود أسباب كامنة.", "bmiUnderweightDescription": "يشير مؤشر كتلة الجسم إلى أنك تعاني من نقص الوزن. لذا، يُنصح بزيادة السعرات الحرارية المتناولة من خلال تناول الأطعمة الغنية بالعناصر الغذائية، وممارسة تمارين المقاومة لبناء العضلات، واستشارة أخصائي رعاية صحية للتحقق من وجود أسباب كامنة.",
"bmiOverweightDescription": "يشير مؤشر كتلة الجسم إلى زيادة الوزن. لذا، يُنصح بالسعي إلى إنقاص الوزن تدريجياً وبشكل مستدام من خلال تقليل السعرات الحرارية بشكل معتدل، وممارسة النشاط البدني بانتظام، واختيار الأطعمة الصحية. استشر طبيبك قبل إجراء أي تغييرات جذرية في نمط حياتك.", "bmiOverweightDescription": "يشير مؤشر كتلة الجسم إلى زيادة الوزن. لذا، يُنصح بالسعي إلى إنقاص الوزن تدريجياً وبشكل مستدام من خلال تقليل السعرات الحرارية بشكل معتدل، وممارسة النشاط البدني بانتظام، واختيار الأطعمة الصحية. استشر طبيبك قبل إجراء أي تغييرات جذرية في نمط حياتك.",
@ -1634,7 +1653,7 @@ class CodegenLoader extends AssetLoader{
"insuranceRequestSubmittedSuccessfully": "تم إرسال طلب تحديث بيانات التأمين بنجاح. سيتم إعلامك بمجرد الانتهاء.", "insuranceRequestSubmittedSuccessfully": "تم إرسال طلب تحديث بيانات التأمين بنجاح. سيتم إعلامك بمجرد الانتهاء.",
"updatingEmailAddress": "جارٍ تحديث عنوان البريد الإلكتروني، يرجى الانتظار...", "updatingEmailAddress": "جارٍ تحديث عنوان البريد الإلكتروني، يرجى الانتظار...",
"verifyInsurance": "التحقق من التأمين", "verifyInsurance": "التحقق من التأمين",
"tests": "تحليل", "tests": "تحاليل",
"calendarPermissionAlert": "يرجى منح إذن الوصول إلى التقويم من إعدادات التطبيق لضبط تذكير تناول الدواء.", "calendarPermissionAlert": "يرجى منح إذن الوصول إلى التقويم من إعدادات التطبيق لضبط تذكير تناول الدواء.",
"sortByNearestLocation": "فرز حسب الأقرب إلى موقعك", "sortByNearestLocation": "فرز حسب الأقرب إلى موقعك",
"giveLocationPermissionForNearestList": "يرجى منح إذن الوصول إلى الموقع من إعدادات التطبيق لعرض أقرب المواقع.", "giveLocationPermissionForNearestList": "يرجى منح إذن الوصول إلى الموقع من إعدادات التطبيق لعرض أقرب المواقع.",
@ -1661,7 +1680,7 @@ class CodegenLoader extends AssetLoader{
"homeHealthCareServiceHeader": "صحتك، في أبهى صورها. رعاية فائقة الجودة، تصلك إلى عتبة دارك.", "homeHealthCareServiceHeader": "صحتك، في أبهى صورها. رعاية فائقة الجودة، تصلك إلى عتبة دارك.",
"homeHealthCareServiceDescription": "نقدم لكم رعاية صحية عالية الجودة تصلكم إلى عتبة منزلكم. ممرضات ذوات خبرة يقدمون رعاية حانية في راحة منزلكم.", "homeHealthCareServiceDescription": "نقدم لكم رعاية صحية عالية الجودة تصلكم إلى عتبة منزلكم. ممرضات ذوات خبرة يقدمون رعاية حانية في راحة منزلكم.",
"profileOnlyText": "الملف الشخصي", "profileOnlyText": "الملف الشخصي",
"information": "معلومة", "information": "معلومات الطبيب",
"noFavouriteDoctors": "ليس لديك أي قائمة مفضلة حتى الآن", "noFavouriteDoctors": "ليس لديك أي قائمة مفضلة حتى الآن",
"addDoctors": "إضافة الأطباء", "addDoctors": "إضافة الأطباء",
"favouriteList": "قائمة المفضلة", "favouriteList": "قائمة المفضلة",
@ -1800,7 +1819,7 @@ static const Map<String,dynamic> _en_US = {
"date": "Date", "date": "Date",
"time": "Time", "time": "Time",
"pendingPayment": "Pending for payment", "pendingPayment": "Pending for payment",
"payNow": "Pay Now", "payNow": "Payment",
"viewQR": "View QR Code", "viewQR": "View QR Code",
"instruction": "Instructions", "instruction": "Instructions",
"livecare": "LiveCare", "livecare": "LiveCare",
@ -1927,6 +1946,7 @@ static const Map<String,dynamic> _en_US = {
"enterEmail": "Please Enter Email", "enterEmail": "Please Enter Email",
"family": "My Family", "family": "My Family",
"familyTitle": "My Family Files", "familyTitle": "My Family Files",
"familyTitle2": "My Family Files",
"addNewMember": "Add Family Member", "addNewMember": "Add Family Member",
"sentRequests": "Sent Requests", "sentRequests": "Sent Requests",
"recievedRequests": "Recieved Requests", "recievedRequests": "Recieved Requests",
@ -2042,6 +2062,7 @@ static const Map<String,dynamic> _en_US = {
"myMedicalSubtitle": "Medications", "myMedicalSubtitle": "Medications",
"myDoctor": "My Doctors", "myDoctor": "My Doctors",
"myDoctorSubtitle": "List", "myDoctorSubtitle": "List",
"myDoctorSubtitle2": "List",
"eye": "Eye", "eye": "Eye",
"eyeSubtitle": "Measurement", "eyeSubtitle": "Measurement",
"insurance": "Insurance", "insurance": "Insurance",
@ -2059,6 +2080,7 @@ static const Map<String,dynamic> _en_US = {
"monthly": "Monthly", "monthly": "Monthly",
"monthlySubtitle": "Report", "monthlySubtitle": "Report",
"sick": "Sick", "sick": "Sick",
"sick2": "Sick",
"sickSubtitle": "Leaves", "sickSubtitle": "Leaves",
"myBalance": "My Balance", "myBalance": "My Balance",
"myBalanceSubtitle": "Credit", "myBalanceSubtitle": "Credit",
@ -2216,8 +2238,10 @@ static const Map<String,dynamic> _en_US = {
"refferalSubTitle": "Service", "refferalSubTitle": "Service",
"healthCare": "Health Care", "healthCare": "Health Care",
"emergency": "Emergency", "emergency": "Emergency",
"emergency2": "Emergency",
"erservices": "Emergency", "erservices": "Emergency",
"services2": "Services", "services2": "Services",
"services3": "Services",
"cantSeeProfile": "To view your medical profile, please log in or register now", "cantSeeProfile": "To view your medical profile, please log in or register now",
"loginRegisterNow": "Login or Register Now", "loginRegisterNow": "Login or Register Now",
"hmgPharmacy": "HMG Pharmacy", "hmgPharmacy": "HMG Pharmacy",
@ -2489,6 +2513,7 @@ static const Map<String,dynamic> _en_US = {
"erConsultation": "This service allows you to make an online virtual consultation via video call directly with the doctor from anywhere at any time.", "erConsultation": "This service allows you to make an online virtual consultation via video call directly with the doctor from anywhere at any time.",
"myInvoice": "List", "myInvoice": "List",
"invoiceList": "My Invoice", "invoiceList": "My Invoice",
"invoiceList2": "My Invoice",
"allInvoices": "All Invoices", "allInvoices": "All Invoices",
"hospitals": "Hospitals", "hospitals": "Hospitals",
"clinics": "Clinics", "clinics": "Clinics",
@ -2894,13 +2919,21 @@ static const Map<String,dynamic> _en_US = {
"triglyceridesFatBlood": "Triglycerides Fat Blood", "triglyceridesFatBlood": "Triglycerides Fat Blood",
"understandTriglyceridesImpact": "Understand triglycerides' impact on heart health with personalized insights and expert recommendations.", "understandTriglyceridesImpact": "Understand triglycerides' impact on heart health with personalized insights and expert recommendations.",
"bmiCalculator": "BMI Calculator", "bmiCalculator": "BMI Calculator",
"bmiCalculatorDesc": "Calculate your body mass index to understand your healthy weight range.",
"caloriesCalculator": "Calories Calculator", "caloriesCalculator": "Calories Calculator",
"caloriesCalculatorDesc": "Find out how many calories you need daily to maintain or lose weight.",
"bmrCalculator": "BMR Calculator", "bmrCalculator": "BMR Calculator",
"bmrCalculatorDesc": "Determine your basal metabolic rate and daily energy requirements.",
"idealBodyWeight": "Ideal Body Weight", "idealBodyWeight": "Ideal Body Weight",
"idealBodyWeightDesc": "Discover your ideal weight based on height, age, and body structure.",
"bodyFatCalculator": "Body Fat Calculator", "bodyFatCalculator": "Body Fat Calculator",
"bodyFatCalculatorDesc": "Estimate your body fat percentage to track fitness and health goals.",
"carbsProteinFat": "Carbs Protein & Fat", "carbsProteinFat": "Carbs Protein & Fat",
"carbsProteinFatDesc": "Balance your macros with the right carbs, protein, and fat ratios.",
"ovulationPeriod": "Ovulation Period", "ovulationPeriod": "Ovulation Period",
"ovulationPeriodDesc": "Track your fertile window and plan for conception with accuracy.",
"deliveryDueDate": "Delivery Due Date", "deliveryDueDate": "Delivery Due Date",
"deliveryDueDateDesc": "Calculate your expected delivery date and monitor pregnancy milestones.",
"low": "Low", "low": "Low",
"preDiabetic": "Pre-diabetic", "preDiabetic": "Pre-diabetic",
"high": "High", "high": "High",
@ -2945,6 +2978,7 @@ static const Map<String,dynamic> _en_US = {
"hmgServices": "HMG Services", "hmgServices": "HMG Services",
"personalServices": "Personal Services", "personalServices": "Personal Services",
"habibWallet": "Habib Wallet", "habibWallet": "Habib Wallet",
"habibWallet2": "Habib Wallet",
"loginToViewWalletBalance": "Login to view your wallet balance", "loginToViewWalletBalance": "Login to view your wallet balance",
"loginToViewMedicalFile": "Login to view your medical file", "loginToViewMedicalFile": "Login to view your medical file",
"addMember": "Add Member", "addMember": "Add Member",
@ -3189,6 +3223,7 @@ static const Map<String,dynamic> _en_US = {
"distanceDescription": "Distance covered throughout the day", "distanceDescription": "Distance covered throughout the day",
"overview": "Overview", "overview": "Overview",
"details": "Details", "details": "Details",
"details2": "Details",
"healthy": "Healthy", "healthy": "Healthy",
"warning": "Warning", "warning": "Warning",
"vitalSignDetails": "Vital Sign Details", "vitalSignDetails": "Vital Sign Details",

File diff suppressed because it is too large Load Diff

@ -200,6 +200,7 @@ abstract class LocaleKeys {
static const enterEmail = 'enterEmail'; static const enterEmail = 'enterEmail';
static const family = 'family'; static const family = 'family';
static const familyTitle = 'familyTitle'; static const familyTitle = 'familyTitle';
static const familyTitle2 = 'familyTitle2';
static const myFamily = 'myFamily'; static const myFamily = 'myFamily';
static const addNewMember = 'addNewMember'; static const addNewMember = 'addNewMember';
static const sentRequests = 'sentRequests'; static const sentRequests = 'sentRequests';
@ -1236,6 +1237,7 @@ abstract class LocaleKeys {
static const hmgServices = 'hmgServices'; static const hmgServices = 'hmgServices';
static const personalServices = 'personalServices'; static const personalServices = 'personalServices';
static const habibWallet = 'habibWallet'; static const habibWallet = 'habibWallet';
static const habibWallet2 = 'habibWallet2';
static const loginToViewWalletBalance = 'loginToViewWalletBalance'; static const loginToViewWalletBalance = 'loginToViewWalletBalance';
static const loginToViewMedicalFile = 'loginToViewMedicalFile'; static const loginToViewMedicalFile = 'loginToViewMedicalFile';
static const addMember = 'addMember'; static const addMember = 'addMember';

@ -28,6 +28,7 @@ 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:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:hmg_patient_app_new/presentation/appointments/appointment_payment_page.dart'; import 'package:hmg_patient_app_new/presentation/appointments/appointment_payment_page.dart';
import 'package:lottie/lottie.dart';
class AppointmentCard extends StatefulWidget { class AppointmentCard extends StatefulWidget {
final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel; final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel;
@ -705,42 +706,46 @@ class _AppointmentCardState extends State<AppointmentCard> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
// Message text Lottie.asset(AppAnimations.warningAnimation,
repeat: false, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill),
SizedBox(height: 12,),
LocaleKeys.upcomingPaymentPending.tr(context: context).toText14( LocaleKeys.upcomingPaymentPending.tr(context: context).toText14(
color: AppColors.textColor, color: AppColors.textColor,
isCenter: true, isCenter: true,
), ),
SizedBox(height: 24.h), SizedBox(height: 24.h),
// Countdown Timer - DD : HH : MM : SS format with labels // Countdown Timer - DD : HH : MM : SS format with labels
Row( // Row(
mainAxisAlignment: MainAxisAlignment.center, // mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
children: [ // children: [
// Days // // Days
_buildTimeUnit( // _buildTimeUnit(
_timeRemaining != null ? _timeRemaining!.inDays.toString().padLeft(2, '0') : '00', // _timeRemaining != null ? _timeRemaining!.inDays.toString().padLeft(2, '0') : '00',
LocaleKeys.days.tr(context: context), // LocaleKeys.days.tr(context: context),
), // ),
_buildTimeSeparator(), // _buildTimeSeparator(),
// Hours // // Hours
_buildTimeUnit( // _buildTimeUnit(
_timeRemaining != null ? _timeRemaining!.inHours.remainder(24).toString().padLeft(2, '0') : '00', // _timeRemaining != null ? _timeRemaining!.inHours.remainder(24).toString().padLeft(2, '0') : '00',
LocaleKeys.hours.tr(context: context), // LocaleKeys.hours.tr(context: context),
), // ),
_buildTimeSeparator(), // _buildTimeSeparator(),
// Minutes // // Minutes
_buildTimeUnit( // _buildTimeUnit(
_timeRemaining != null ? _timeRemaining!.inMinutes.remainder(60).toString().padLeft(2, '0') : '00', // _timeRemaining != null ? _timeRemaining!.inMinutes.remainder(60).toString().padLeft(2, '0') : '00',
LocaleKeys.minutes.tr(context: context), // LocaleKeys.minutes.tr(context: context),
), // ),
_buildTimeSeparator(), // _buildTimeSeparator(),
// Seconds // // Seconds
_buildTimeUnit( // _buildTimeUnit(
_timeRemaining != null ? _timeRemaining!.inSeconds.remainder(60).toString().padLeft(2, '0') : '00', // _timeRemaining != null ? _timeRemaining!.inSeconds.remainder(60).toString().padLeft(2, '0') : '00',
LocaleKeys.seconds.tr(context: context), // LocaleKeys.seconds.tr(context: context),
), // ),
], // ],
), // ),
SizedBox(height: 24.h), SizedBox(height: 24.h),
// Green Acknowledge button with checkmark icon // Green Acknowledge button with checkmark icon
CustomButton( CustomButton(

@ -26,7 +26,7 @@ class HabibWalletCard extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
LocaleKeys.myBalance.tr(context: context).toText16(isBold: true), LocaleKeys.myBalanceSubtitle.tr(context: context).toText16(isBold: true),
// Row( // Row(
// children: [ // children: [
// LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true), // LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor, isBold: true),
@ -57,7 +57,7 @@ class HabibWalletCard extends StatelessWidget {
// Row( // Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween, // mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [ // children: [
LocaleKeys.habibWallet.tr(context: context).toText16(isBold: true, letterSpacing: -0.2), LocaleKeys.habibWallet2.tr(context: context).toText16(isBold: true, letterSpacing: -0.2),
// Container( // Container(
// height: 40.h, // height: 40.h,
// width: 40.h, // width: 40.h,

@ -34,13 +34,12 @@ class _ProfilePictureWidgetState extends State<ProfilePictureWidget> {
void initState() { void initState() {
super.initState(); super.initState();
_currentPatientId = _appState.getAuthenticatedUser()?.patientId; _currentPatientId = _appState.getAuthenticatedUser()?.patientId;
print('🎬 ProfilePictureWidget initState - patient: $_currentPatientId');
// Use addPostFrameCallback to ensure widget is built before loading // Use addPostFrameCallback to ensure widget is built before loading
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted) return; if (!mounted) return;
final profileVm = context.read<ProfileSettingsViewModel>();
final patientID = _appState.getAuthenticatedUser()?.patientId; final patientID = _appState.getAuthenticatedUser()?.patientId;
if (patientID == null) { if (patientID == null) {
@ -48,20 +47,9 @@ class _ProfilePictureWidgetState extends State<ProfilePictureWidget> {
return; return;
} }
// Check if we have data in AppState that matches current user // Always load fresh data from API - do NOT use AppState cache
final appStateImageData = _appState.getProfileImageData; print('📥 Loading fresh profile image from API for patient: $patientID');
_loadProfileImage(forceRefresh: true);
if (appStateImageData != null && appStateImageData.isNotEmpty) {
// Sync to ViewModel if it doesn't have data
if (profileVm.profileImageData == null || profileVm.profileImageData!.isEmpty) {
print('🔄 Syncing AppState data to ViewModel');
profileVm.syncProfileImageFromAppState();
}
} else {
// No cached data - load from API
print('📥 No cached data - loading from API for patient: $patientID');
_loadProfileImage(forceRefresh: false);
}
}); });
} }
@ -88,13 +76,25 @@ class _ProfilePictureWidgetState extends State<ProfilePictureWidget> {
final oldPatientId = _currentPatientId; final oldPatientId = _currentPatientId;
_currentPatientId = currentPatientId; _currentPatientId = currentPatientId;
// Clear the old profile image data // Clear the old profile image data from BOTH AppState and ViewModel
try { try {
final profileVm = context.read<ProfileSettingsViewModel>(); final profileVm = context.read<ProfileSettingsViewModel>();
print('🧹 Clearing cache for old user: $oldPatientId'); print('🧹 Clearing cache for old user: $oldPatientId');
// Clear AppState cache first
_appState.clearProfileImageCache();
// Then clear ViewModel cache
profileVm.clearProfileImageCache(); profileVm.clearProfileImageCache();
// Force rebuild to show default avatar immediately
if (mounted) {
setState(() {
_selectedImage = null; // Clear any selected image
});
}
print('📥 Loading profile image for new user: $currentPatientId'); print('📥 Loading profile image for new user: $currentPatientId');
// Load the new user's profile image immediately // Load the new user's profile image immediately
profileVm.getProfileImage( profileVm.getProfileImage(
@ -455,6 +455,7 @@ class _ProfilePictureWidgetState extends State<ProfilePictureWidget> {
Widget _buildProfileImage(ProfileSettingsViewModel profileVm) { Widget _buildProfileImage(ProfileSettingsViewModel profileVm) {
// Always get fresh user data // Always get fresh user data
final currentUser = _appState.getAuthenticatedUser(); final currentUser = _appState.getAuthenticatedUser();
final currentPatientId = currentUser?.patientId;
final gender = currentUser?.gender ?? 1; final gender = currentUser?.gender ?? 1;
final age = currentUser?.age ?? 0; final age = currentUser?.age ?? 0;
@ -480,11 +481,22 @@ class _ProfilePictureWidgetState extends State<ProfilePictureWidget> {
); );
} }
// Use ViewModel data if available, otherwise fall back to AppState // // IMPORTANT: Verify the cached image belongs to the current user
// This ensures we show the current logged-in user's image (same as homepage profile icon) // // If _currentPatientId doesn't match currentPatientId, don't show cached image
final String? imageData = profileVm.profileImageData ?? _appState.getProfileImageData; // if (currentPatientId != _currentPatientId) {
// print('⚠️ Patient ID mismatch - showing default avatar (current: $currentPatientId, cached: $_currentPatientId)');
// return Image.asset(
// defaultImage,
// width: 136.w,
// height: 136.h,
// );
// }
// IMPORTANT: Use ONLY ViewModel data, DO NOT fallback to AppState
// This prevents showing stale cached data when switching users
final String? imageData = profileVm.profileImageData;
print('🖼️ Building profile image - has data: ${imageData != null && imageData.isNotEmpty}, patient: ${currentUser?.patientId}'); print('🖼️ Building profile image - has data: ${imageData != null && imageData.isNotEmpty}, patient: $currentPatientId (ViewModel ONLY)');
// Show uploaded image if available // Show uploaded image if available
if (imageData != null && imageData.isNotEmpty) { if (imageData != null && imageData.isNotEmpty) {
@ -510,7 +522,7 @@ class _ProfilePictureWidgetState extends State<ProfilePictureWidget> {
} }
// Show default image (no image data or user has no uploaded image) // Show default image (no image data or user has no uploaded image)
print('📷 Showing default avatar for user ${currentUser?.patientId}'); print('📷 Showing default avatar for user $currentPatientId');
return Image.asset( return Image.asset(
defaultImage, defaultImage,
width: 136.w, width: 136.w,

Loading…
Cancel
Save