Compare commits

...

12 Commits

@ -1,3 +1,11 @@
# Translation prompt & Command
Read the context for both files & generate translations strings in the en-US.json & ar-SA.json files for the strings containing "needTranslation". Also replace the strings in the dart with the generated Strings. Also do not remove existing properties & do no generate duplicate strings in the json files
flutter3_32 pub run easy_localization:generate -O ./lib/generated -f keys -o locale_keys.g.dart --source-dir ./assets/langs
# HMG Patient App # HMG Patient App
A comprehensive Flutter-based mobile application for HMG (Habib Medical Group) patients, A comprehensive Flutter-based mobile application for HMG (Habib Medical Group) patients,

@ -0,0 +1,3 @@
<svg width="15" height="23" viewBox="0 0 15 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.32806 22.32C7.33606 22.32 6.34406 22.2 5.35206 21.96C4.37606 21.736 3.48006 21.36 2.66406 20.832C1.86406 20.304 1.21606 19.616 0.720063 18.768C0.240063 17.92 6.25104e-05 16.88 6.25104e-05 15.648C6.25104e-05 14.4 0.248063 13.248 0.744063 12.192C1.25606 11.12 1.96806 10.168 2.88006 9.336C3.80806 8.488 4.90406 7.784 6.16806 7.224C7.43206 6.664 8.81606 6.264 10.3201 6.024L10.9921 8.688C9.68006 8.928 8.51206 9.256 7.48806 9.672C6.48006 10.088 5.62406 10.584 4.92006 11.16C4.23206 11.736 3.71206 12.368 3.36006 13.056C3.00806 13.76 2.83206 14.512 2.83206 15.312C2.83206 15.952 2.94406 16.504 3.16806 16.968C3.40806 17.448 3.72006 17.848 4.10406 18.168C4.48806 18.488 4.92006 18.744 5.40006 18.936C5.88006 19.128 6.37606 19.264 6.88806 19.344C7.40006 19.44 7.88006 19.488 8.32806 19.488C9.33606 19.488 10.3041 19.392 11.2321 19.2C12.1601 19.024 12.9841 18.784 13.7041 18.48L14.5201 21.024C14.1361 21.216 13.6081 21.408 12.9361 21.6C12.2641 21.808 11.5281 21.976 10.7281 22.104C9.92806 22.248 9.12806 22.32 8.32806 22.32ZM3.86406 9.24C3.27206 9.048 2.72806 8.744 2.23206 8.328C1.75206 7.912 1.36806 7.4 1.08006 6.792C0.792063 6.184 0.648063 5.512 0.648063 4.776C0.648063 3.768 0.904063 2.912 1.41606 2.208C1.92806 1.488 2.59206 0.943998 3.40806 0.575998C4.24006 0.191998 5.13606 -1.90735e-06 6.09606 -1.90735e-06C6.56006 -1.90735e-06 7.00806 0.0319982 7.44006 0.0959983C7.87206 0.159998 8.30406 0.255998 8.73606 0.383997L8.25606 3.072C7.92006 2.992 7.57606 2.928 7.22406 2.88C6.87206 2.832 6.56006 2.808 6.28806 2.808C5.72806 2.808 5.23206 2.896 4.80006 3.072C4.38406 3.248 4.05606 3.496 3.81606 3.816C3.59206 4.136 3.48006 4.512 3.48006 4.944C3.48006 5.312 3.58406 5.656 3.79206 5.976C4.01606 6.28 4.29606 6.544 4.63206 6.768C4.98406 6.992 5.35206 7.168 5.73606 7.296C6.13606 7.424 6.50406 7.496 6.84006 7.512L3.86406 9.24Z" fill="#2B353E"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -0,0 +1,3 @@
<svg width="12" height="21" viewBox="0 0 12 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.72994 2.25V9.24H10.3499V11.49H2.72994V18.69H11.2499V20.94H-5.83827e-05V2.02656e-06H11.2499V2.25H2.72994Z" fill="#2B353E"/>
</svg>

After

Width:  |  Height:  |  Size: 242 B

@ -1377,6 +1377,18 @@
"suggestions": "الاقتراحات", "suggestions": "الاقتراحات",
"pleaseGoBackAndSelectOrgansFirst": "يرجى العودة واختيار الأعضاء أولاً", "pleaseGoBackAndSelectOrgansFirst": "يرجى العودة واختيار الأعضاء أولاً",
"symptomsSelector": "محدد الأعراض", "symptomsSelector": "محدد الأعراض",
"possibleSymptomsRelatedTo": "الأعراض المحتملة المتعلقة بـ",
"suggestionAIListDescription": "هذه قائمة بالأعراض المقترحة من قبل الذكاء الاصطناعي، بناءً على المعلومات التي تم جمعها حتى الآن خلال المقابلة",
"analyzing": "جاري التحليل...",
"seekMedicalAdvice": "اطلب المشورة الطبية",
"monitorDescription": "لا حاجة لطلب المشورة الطبية. فقط حافظ على روتين صحي.",
"seekMedicalAdviceDescription": "ليست حالة طوارئ ولكن من الأفضل مراقبة الأعراض.",
"emergencyDescription": "تحتاج إلى استشارة الطبيب في أقرب وقت ممكن قبل فوات الأوان.",
"colorScience": "دلالات الألوان",
"noNeedToVisitDoctor": "لا حاجة لزي<D8B2><D98A>رة الطبيب",
"commonSymptom": "الأعراض الشائعة",
"bookAppointment": "احجز موعد",
"notApplicable": "لا ينطبق",
"emergencyTriage": "طوارئ", "emergencyTriage": "طوارئ",
"emergencyEvidenceDetected": "تم اكتشاف دليل طوارئ. يرجى طلب العناية الطبية.", "emergencyEvidenceDetected": "تم اكتشاف دليل طوارئ. يرجى طلب العناية الطبية.",
"noQuestionItemsAvailable": "لا توجد عناصر أسئلة متاحة", "noQuestionItemsAvailable": "لا توجد عناصر أسئلة متاحة",
@ -1499,5 +1511,20 @@
"selectTime": "حدد الوقت", "selectTime": "حدد الوقت",
"pleaseWaitYouWillBeCalledForVitalSigns": "يرجى الانتظار! سيتم استدعاؤك لقياس العلامات الحيوية", "pleaseWaitYouWillBeCalledForVitalSigns": "يرجى الانتظار! سيتم استدعاؤك لقياس العلامات الحيوية",
"pleaseVisitRoomForVitalSigns": "يرجى زيارة الغرفة {roomNumber} لقياس العلامات الحيوية", "pleaseVisitRoomForVitalSigns": "يرجى زيارة الغرفة {roomNumber} لقياس العلامات الحيوية",
"pleaseVisitRoomToTheDoctor": "يرجى زيارة الغرفة {roomNumber} لمقابلة الطبيب" "pleaseVisitRoomToTheDoctor": "يرجى زيارة الغرفة {roomNumber} لمقابلة الطبيب",
"erOnlineCheckInRequest": "طلب تسجيل الوصول عبر الإنترنت لقسم الطوارئ",
"indoor": "داخلي",
"navigation": "الملاحة",
"health": "الصحة",
"calculators": "الحاسبات",
"converters": "المحولات",
"guide": "الدليل",
"liveCareServiceDesc": "احصل على استشارة طبية من طبيب متخصص عبر مكالمة فيديو",
"bloodGroup": "فصيلة الدم: {bloodType}",
"medicalServices": "الخدمات الطبية",
"insuranceAndPayments": "التأمين والمدفوعات",
"trackerAndOthers": "المتتبع وأخرى",
"bmi": "مؤشر كتلة الجسم"
} }

@ -1367,6 +1367,18 @@
"suggestions": "Suggestions", "suggestions": "Suggestions",
"pleaseGoBackAndSelectOrgansFirst": "Please go back and select organs first", "pleaseGoBackAndSelectOrgansFirst": "Please go back and select organs first",
"symptomsSelector": "Symptoms Selector", "symptomsSelector": "Symptoms Selector",
"possibleSymptomsRelatedTo": "Possible symptoms related to",
"suggestionAIListDescription": "This is a list of symptoms suggested by our AI, based on the information gathered so far during the interview",
"analyzing": "Analyzing...",
"seekMedicalAdvice": "Seek Medical Advice",
"monitorDescription": "No need to seek medical advice. Just keep healthy routine.",
"seekMedicalAdviceDescription": "Not emergency but better to monitor the symptoms.",
"emergencyDescription": "Need to consult doctor as soon as possible before getting too late.",
"colorScience": "Color Science",
"noNeedToVisitDoctor": "No need to visit doctor",
"commonSymptom": "Common Symptom",
"bookAppointment": "Book Appointment",
"notApplicable": "Not Applicable",
"emergencyTriage": "Emergency", "emergencyTriage": "Emergency",
"emergencyEvidenceDetected": "Emergency evidence detected. Please seek medical attention.", "emergencyEvidenceDetected": "Emergency evidence detected. Please seek medical attention.",
"noQuestionItemsAvailable": "No question items available", "noQuestionItemsAvailable": "No question items available",
@ -1490,5 +1502,20 @@
"selectTime": "Select Time", "selectTime": "Select Time",
"pleaseWaitYouWillBeCalledForVitalSigns": "Please wait! you will be called for vital signs", "pleaseWaitYouWillBeCalledForVitalSigns": "Please wait! you will be called for vital signs",
"pleaseVisitRoomForVitalSigns": "Please visit Room {roomNumber} for vital signs", "pleaseVisitRoomForVitalSigns": "Please visit Room {roomNumber} for vital signs",
"pleaseVisitRoomToTheDoctor": "Please visit Room {roomNumber} to the Doctor" "pleaseVisitRoomToTheDoctor": "Please visit Room {roomNumber} to the Doctor",
"erOnlineCheckInRequest": "ER Online Check-In Request",
"indoor": "Indoor",
"navigation": "Navigation",
"health": "Health",
"calculators": "Calculators",
"converters": "Converters",
"guide": "Guide",
"liveCareServiceDesc": "Get medical advice with a specialist doctor Via a video call",
"bloodGroup": "Blood: {bloodType}",
"medicalServices": "Medical Services",
"insuranceAndPayments": "Insurance & Payments",
"trackerAndOthers": "Tracker & Others",
"bmi": "BMI"
} }

@ -1,73 +1,73 @@
import 'dart:convert'; // import 'dart:convert';
import 'dart:io'; // import 'dart:io';
//
void main() async { // void main() async {
final file = File('assets/json/body_symptoms_data.json'); // final file = File('assets/json/body_symptoms_data.json');
final content = await file.readAsString(); // final content = await file.readAsString();
//
print('File size: ${content.length} characters'); // print('File size: ${content.length} characters');
//
// Split into two parts // // Split into two parts
final parts = content.split('export const SymptomsData = ['); // final parts = content.split('export const SymptomsData = [');
if (parts.length != 2) { // if (parts.length != 2) {
print('ERROR: Could not split file properly'); // print('ERROR: Could not split file properly');
exit(1); // exit(1);
} // }
//
print('Split into ${parts.length} parts'); // print('Split into ${parts.length} parts');
//
// Process BodySymptomsData // // Process BodySymptomsData
var bodyPart = parts[0] // var bodyPart = parts[0]
.replaceAll('export const BodySymptomsData = ', '') // .replaceAll('export const BodySymptomsData = ', '')
.trim() // .trim()
.replaceAll(RegExp(r';$'), ''); // .replaceAll(RegExp(r';$'), '');
//
print('Parsing body symptoms...'); // print('Parsing body symptoms...');
Map<String, dynamic> bodySymptomsData; // Map<String, dynamic> bodySymptomsData;
try { // try {
bodySymptomsData = json.decode(bodyPart); // bodySymptomsData = json.decode(bodyPart);
print('✅ Body symptoms parsed: ${bodySymptomsData.length} body parts'); // print('✅ Body symptoms parsed: ${bodySymptomsData.length} body parts');
} catch (e) { // } catch (e) {
print('❌ Error parsing body symptoms: $e'); // print('❌ Error parsing body symptoms: $e');
exit(1); // exit(1);
} // }
//
// Process SymptomsData // // Process SymptomsData
print('Processing symptoms data...'); // print('Processing symptoms data...');
var symptomsPart = parts[1] // var symptomsPart = parts[1]
.trim() // .trim()
.replaceAll(RegExp(r'\];$'), '') // .replaceAll(RegExp(r'\];$'), '')
.replaceAllMapped(RegExp(r'\n(\s*)id:'), (m) => '\n${m.group(1)}"id":') // .replaceAllMapped(RegExp(r'\n(\s*)id:'), (m) => '\n${m.group(1)}"id":')
.replaceAllMapped(RegExp(r'\n(\s*)type:'), (m) => '\n${m.group(1)}"type":') // .replaceAllMapped(RegExp(r'\n(\s*)type:'), (m) => '\n${m.group(1)}"type":')
.replaceAllMapped(RegExp(r'\n(\s*)name:'), (m) => '\n${m.group(1)}"name":') // .replaceAllMapped(RegExp(r'\n(\s*)name:'), (m) => '\n${m.group(1)}"name":')
.replaceAllMapped(RegExp(r'\n(\s*)common_name:'), (m) => '\n${m.group(1)}"common_name":'); // .replaceAllMapped(RegExp(r'\n(\s*)common_name:'), (m) => '\n${m.group(1)}"common_name":');
//
print('Parsing symptoms...'); // print('Parsing symptoms...');
List<dynamic> symptomsData; // List<dynamic> symptomsData;
try { // try {
symptomsData = json.decode('[$symptomsPart]'); // symptomsData = json.decode('[$symptomsPart]');
print('✅ Symptoms parsed: ${symptomsData.length} symptoms'); // print('✅ Symptoms parsed: ${symptomsData.length} symptoms');
} catch (e) { // } catch (e) {
print('❌ Error parsing symptoms: $e'); // print('❌ Error parsing symptoms: $e');
print('First 1000 chars:'); // print('First 1000 chars:');
print('[$symptomsPart]'.substring(0, 1000)); // print('[$symptomsPart]'.substring(0, 1000));
exit(1); // exit(1);
} // }
//
// Create final JSON // // Create final JSON
print('Creating final JSON structure...'); // print('Creating final JSON structure...');
final jsonStructure = { // final jsonStructure = {
'bodySymptoms': bodySymptomsData, // 'bodySymptoms': bodySymptomsData,
'symptoms': symptomsData, // 'symptoms': symptomsData,
}; // };
//
// Write to file // // Write to file
print('Writing to file...'); // print('Writing to file...');
final encoder = JsonEncoder.withIndent(' '); // final encoder = JsonEncoder.withIndent(' ');
await file.writeAsString(encoder.convert(jsonStructure)); // await file.writeAsString(encoder.convert(jsonStructure));
//
print('\n✅ SUCCESS! File converted to proper JSON'); // print('\n✅ SUCCESS! File converted to proper JSON');
print('✅ Body parts: ${bodySymptomsData.length}'); // print('✅ Body parts: ${bodySymptomsData.length}');
print('✅ Symptoms: ${symptomsData.length}'); // print('✅ Symptoms: ${symptomsData.length}');
} // }
//

@ -189,6 +189,8 @@ class ApiClientImp implements ApiClient {
// body['SessionID'] = "45786230487560q"; // body['SessionID'] = "45786230487560q";
} }
// body['IsNewFlutterApp'] = true;
body.removeWhere((key, value) => value == null); body.removeWhere((key, value) => value == null);
} }

@ -680,7 +680,7 @@ const DASHBOARD = 'Services/Patients.svc/REST/PatientDashboard';
class ApiConsts { class ApiConsts {
static const maxSmallScreen = 660; static const maxSmallScreen = 660;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat;
// static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT

@ -306,6 +306,9 @@ class AppAssets {
static const String bloodPressure = '$svgBasePath/blood_pressure.svg'; static const String bloodPressure = '$svgBasePath/blood_pressure.svg';
static const String temperature = '$svgBasePath/temperature.svg'; static const String temperature = '$svgBasePath/temperature.svg';
static const String arLangIcon = '$svgBasePath/ar_lang_icon.svg';
static const String enLangIcon = '$svgBasePath/en_lang_icon.svg';
// PNGS // // PNGS //
static const String hmgLogo = '$pngBasePath/hmg_logo.png'; static const String hmgLogo = '$pngBasePath/hmg_logo.png';
static const String liveCareService = '$pngBasePath/livecare_service.png'; static const String liveCareService = '$pngBasePath/livecare_service.png';

@ -814,7 +814,8 @@ class Utils {
child: Utils.buildSvgWithAssets(icon: AppAssets.saudi_riyal_icon, width: iconSize.h, height: iconSize.h, iconColor: iconColor), child: Utils.buildSvgWithAssets(icon: AppAssets.saudi_riyal_icon, width: iconSize.h, height: iconSize.h, iconColor: iconColor),
), ),
TextSpan( TextSpan(
text: NumberFormat.currency(locale: 'en_US', symbol: " ", decimalDigits: 0).format(habibWalletAmount), // text: NumberFormat.currency(locale: 'en_US', symbol: " ", decimalDigits: 0).format(habibWalletAmount),
text: " ${habibWalletAmount.toStringAsFixed(2)}",
style: TextStyle( style: TextStyle(
color: textColor, color: textColor,
fontSize: fontSize ?? 32.f, fontSize: fontSize ?? 32.f,

@ -571,7 +571,7 @@ class AuthenticationViewModel extends ChangeNotifier {
MedicalFileViewModel medicalVm = getIt<MedicalFileViewModel>(); MedicalFileViewModel medicalVm = getIt<MedicalFileViewModel>();
if (!_appState.getIsChildLoggedIn) { if (!_appState.getIsChildLoggedIn) {
await medicalVm.getFamilyFiles(status: 0); await medicalVm.getFamilyFiles(status: 0);
await medicalVm.getAllPendingRecordsByResponseId(); // await medicalVm.getAllPendingRecordsByResponseId();
_navigationService.replaceAllRoutesAndNavigateToLanding(); _navigationService.replaceAllRoutesAndNavigateToLanding();
} }
} else { } else {
@ -610,7 +610,7 @@ class AuthenticationViewModel extends ChangeNotifier {
MedicalFileViewModel medicalVm = getIt<MedicalFileViewModel>(); MedicalFileViewModel medicalVm = getIt<MedicalFileViewModel>();
insertPatientIMEIData(loginTypeEnum.toInt); insertPatientIMEIData(loginTypeEnum.toInt);
medicalVm.getFamilyFiles(status: 0); //TODO: Remove status: 1 by Aamir Need to Discuss With Sultan medicalVm.getFamilyFiles(status: 0); //TODO: Remove status: 1 by Aamir Need to Discuss With Sultan
medicalVm.getAllPendingRecordsByResponseId(); // medicalVm.getAllPendingRecordsByResponseId();
} }
await clearDefaultInputValues(); await clearDefaultInputValues();
if (isUserAgreedBefore) { if (isUserAgreedBefore) {

@ -545,20 +545,20 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SizedBox(height: 10.h), SizedBox(height: 10.h),
LocaleKeys.otpVerification.tr().toText24(isBold: true), LocaleKeys.otpVerification.tr(context: context).toText24(isBold: true),
SizedBox(height: 20.h), SizedBox(height: 20.h),
Wrap( Wrap(
spacing: 2.h, spacing: 2.h,
runSpacing: 2.h, runSpacing: 2.h,
children: [ children: [
LocaleKeys.weHaveSendOTP.tr().toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4), LocaleKeys.weHaveSendOTP.tr(context: context).toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4),
_getMaskedPhoneNumber().toText15(color: AppColors.inputLabelTextColor, isBold: true), _getMaskedPhoneNumber().toText15(color: AppColors.inputLabelTextColor, isBold: true),
LocaleKeys.via.tr().toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4), LocaleKeys.via.tr(context: context).toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4),
(widget.isFormFamilyFile ? LoginTypeEnum.sms.displayName : authVM.loginTypeEnum.displayName) (widget.isFormFamilyFile ? LoginTypeEnum.sms.displayName : authVM.loginTypeEnum.displayName)
.toText15(color: AppColors.inputLabelTextColor, isBold: true, letterSpacing: -0.4), .toText15(color: AppColors.inputLabelTextColor, isBold: true, letterSpacing: -0.4),
appState.getUserRegistrationPayload.isRegister != null && appState.getUserRegistrationPayload.isRegister == true appState.getUserRegistrationPayload.isRegister != null && appState.getUserRegistrationPayload.isRegister == true
? LocaleKeys.forRegistrationVerification.tr().toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4) ? LocaleKeys.forRegistrationVerification.tr(context: context).toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4)
: LocaleKeys.forLoginVerification.tr().toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4), : LocaleKeys.forLoginVerification.tr(context: context).toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4),
], ],
), ),
@ -590,7 +590,7 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
LocaleKeys.didntReceiveIt.tr().toText16(color: AppColors.inputLabelTextColor), LocaleKeys.didntReceiveIt.tr(context: context).toText16(color: AppColors.inputLabelTextColor),
SizedBox(width: 5.h), SizedBox(width: 5.h),
if (_resendTime > 0) if (_resendTime > 0)
Builder( Builder(
@ -599,7 +599,7 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
final seconds = (_resendTime % 60).toString().padLeft(2, '0'); final seconds = (_resendTime % 60).toString().padLeft(2, '0');
return Row( return Row(
children: [ children: [
LocaleKeys.resendIn.tr().toText16(color: AppColors.inputLabelTextColor), LocaleKeys.resendIn.tr(context: context).toText16(color: AppColors.inputLabelTextColor),
SizedBox(width: 2.h), SizedBox(width: 2.h),
' ($minutes:$seconds). '.toText16(color: AppColors.inputLabelTextColor) ' ($minutes:$seconds). '.toText16(color: AppColors.inputLabelTextColor)
], ],
@ -609,7 +609,7 @@ class _OTPVerificationScreenState extends State<OTPVerificationScreen> {
else else
GestureDetector( GestureDetector(
onTap: _resendOtp, onTap: _resendOtp,
child: LocaleKeys.resendOTP.tr().toText16(color: AppColors.primaryRedColor), child: LocaleKeys.resendOTP.tr(context: context).toText16(color: AppColors.primaryRedColor),
), ),
], ],
), ),

@ -45,9 +45,7 @@ class ImmediateLiveCareViewModel extends ChangeNotifier {
initImmediateLiveCare() { initImmediateLiveCare() {
_appState = getIt<AppState>(); _appState = getIt<AppState>();
immediateLiveCareClinicsList = []; immediateLiveCareClinicsList = [];
patientLiveCareHistoryList = [];
isImmediateLiveCareClinicsLoading = true; isImmediateLiveCareClinicsLoading = true;
patientHasPendingLiveCareRequest = false;
liveCareSelectedCallType = 0; // 1- Video, 2- Audio, 3- Phone liveCareSelectedCallType = 0; // 1- Video, 2- Audio, 3- Phone
immediateLiveCareSelectedClinic = GetLiveCareClinicListResponseModel(); immediateLiveCareSelectedClinic = GetLiveCareClinicListResponseModel();
liveCareImmediateAppointmentFeesList = LiveCareImmediateAppointmentFeesList(); liveCareImmediateAppointmentFeesList = LiveCareImmediateAppointmentFeesList();
@ -136,6 +134,10 @@ class ImmediateLiveCareViewModel extends ChangeNotifier {
} }
Future<void> getPatientLiveCareHistory({Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getPatientLiveCareHistory({Function(dynamic)? onSuccess, Function(String)? onError}) async {
patientLiveCareHistoryList = [];
patientHasPendingLiveCareRequest = false;
notifyListeners();
final result = await immediateLiveCareRepo.getPatientLiveCareHistory(); final result = await immediateLiveCareRepo.getPatientLiveCareHistory();
result.fold( result.fold(

@ -220,6 +220,7 @@ class MyAppointmentsViewModel extends ChangeNotifier {
} }
Future<void> getPatientAppointments(bool isActiveAppointment, bool isArrivedAppointments, {Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getPatientAppointments(bool isActiveAppointment, bool isArrivedAppointments, {Function(dynamic)? onSuccess, Function(String)? onError}) async {
isPatientHasQueueAppointment = false;
if (!isAppointmentDataToBeLoaded) return; if (!isAppointmentDataToBeLoaded) return;
filteredAppointmentList.clear(); filteredAppointmentList.clear();
@ -727,6 +728,7 @@ class MyAppointmentsViewModel extends ChangeNotifier {
Future<void> getPatientAppointmentQueueDetails({Function(dynamic)? onSuccess, Function(String)? onError}) async { Future<void> getPatientAppointmentQueueDetails({Function(dynamic)? onSuccess, Function(String)? onError}) async {
//TODO: Discuss With Haroon, Is the User Has no data it return No Element Bad State; //TODO: Discuss With Haroon, Is the User Has no data it return No Element Bad State;
isPatientHasQueueAppointment = false;
isAppointmentQueueDetailsLoading = true; isAppointmentQueueDetailsLoading = true;
notifyListeners(); notifyListeners();
final result = await myAppointmentsRepo.getPatientAppointmentQueueDetails( final result = await myAppointmentsRepo.getPatientAppointmentQueueDetails(

@ -8,28 +8,36 @@ class OrganData {
OrganModel( OrganModel(
id: 'head', id: 'head',
name: 'whole_head', name: 'whole_head',
nameAr: 'الرأس_كامل',
description: 'Head', description: 'Head',
descriptionAr: 'الرأس',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.50, y: 0.03), position: OrganPosition(x: 0.50, y: 0.03),
), ),
OrganModel( OrganModel(
id: 'left_eye', id: 'left_eye',
name: 'eyes', name: 'eyes',
nameAr: 'العيون',
description: 'Left Eye', description: 'Left Eye',
descriptionAr: 'العين اليسرى',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.43, y: 0.07), position: OrganPosition(x: 0.43, y: 0.07),
), ),
OrganModel( OrganModel(
id: 'right_eye', id: 'right_eye',
name: 'eyes', name: 'eyes',
nameAr: 'العيون',
description: 'Right Eye', description: 'Right Eye',
descriptionAr: 'العين اليمنى',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.57, y: 0.07), position: OrganPosition(x: 0.57, y: 0.07),
), ),
OrganModel( OrganModel(
id: 'nose_mouth', id: 'nose_mouth',
name: 'oral_cavity', name: 'oral_cavity',
nameAr: 'تجويف_الفم',
description: 'Nose/Mouth', description: 'Nose/Mouth',
descriptionAr: 'الأنف/الفم',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.50, y: 0.09), position: OrganPosition(x: 0.50, y: 0.09),
), ),
@ -38,7 +46,9 @@ class OrganData {
OrganModel( OrganModel(
id: 'throat', id: 'throat',
name: 'neck_or_throat', name: 'neck_or_throat',
nameAr: 'الرقبة_أو_الحلق',
description: 'Throat', description: 'Throat',
descriptionAr: 'الحلق',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.50, y: 0.15), position: OrganPosition(x: 0.50, y: 0.15),
), ),
@ -47,14 +57,18 @@ class OrganData {
OrganModel( OrganModel(
id: 'left_shoulder', id: 'left_shoulder',
name: 'upper_arm', name: 'upper_arm',
nameAr: 'الذراع_العلوي',
description: 'Left Shoulder', description: 'Left Shoulder',
descriptionAr: 'الكتف الأيسر',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.22, y: 0.22), position: OrganPosition(x: 0.22, y: 0.22),
), ),
OrganModel( OrganModel(
id: 'right_shoulder', id: 'right_shoulder',
name: 'upper_arm', name: 'upper_arm',
nameAr: 'الذراع_العلوي',
description: 'Right Shoulder', description: 'Right Shoulder',
descriptionAr: 'الكتف الأيمن',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.8, y: 0.22), position: OrganPosition(x: 0.8, y: 0.22),
), ),
@ -63,21 +77,27 @@ class OrganData {
OrganModel( OrganModel(
id: 'left_chest', id: 'left_chest',
name: 'chest', name: 'chest',
nameAr: 'الصدر',
description: 'Left Chest', description: 'Left Chest',
descriptionAr: 'الصدر الأيسر',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.38, y: 0.22), position: OrganPosition(x: 0.38, y: 0.22),
), ),
OrganModel( OrganModel(
id: 'center_chest', id: 'center_chest',
name: 'chest', name: 'chest',
nameAr: 'الصدر',
description: 'Center Chest', description: 'Center Chest',
descriptionAr: 'وسط الصدر',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.52, y: 0.25), position: OrganPosition(x: 0.52, y: 0.25),
), ),
OrganModel( OrganModel(
id: 'right_chest', id: 'right_chest',
name: 'chest', name: 'chest',
nameAr: 'الصدر',
description: 'Right Chest', description: 'Right Chest',
descriptionAr: 'الصدر الأيمن',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.65, y: 0.22), position: OrganPosition(x: 0.65, y: 0.22),
), ),
@ -86,14 +106,18 @@ class OrganData {
OrganModel( OrganModel(
id: 'left_ribs', id: 'left_ribs',
name: 'chest', name: 'chest',
nameAr: 'الصدر',
description: 'Left Ribs', description: 'Left Ribs',
descriptionAr: 'الأضلاع اليسرى',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.38, y: 0.35), position: OrganPosition(x: 0.38, y: 0.35),
), ),
OrganModel( OrganModel(
id: 'right_ribs', id: 'right_ribs',
name: 'chest', name: 'chest',
nameAr: 'الصدر',
description: 'Right Ribs', description: 'Right Ribs',
descriptionAr: 'الأضلاع اليمنى',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.64, y: 0.35), position: OrganPosition(x: 0.64, y: 0.35),
), ),
@ -102,21 +126,27 @@ class OrganData {
OrganModel( OrganModel(
id: 'upper_abdomen', id: 'upper_abdomen',
name: 'upper_abdomen', name: 'upper_abdomen',
nameAr: 'البطن_العلوي',
description: 'Upper Abdomen', description: 'Upper Abdomen',
descriptionAr: 'أعلى البطن',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.51, y: 0.31), position: OrganPosition(x: 0.51, y: 0.31),
), ),
OrganModel( OrganModel(
id: 'navel', id: 'navel',
name: 'mid_abdomen', name: 'mid_abdomen',
nameAr: 'البطن_الأوسط',
description: 'Navel', description: 'Navel',
descriptionAr: 'السرة',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.51, y: 0.38), position: OrganPosition(x: 0.51, y: 0.38),
), ),
OrganModel( OrganModel(
id: 'lower_abdomen', id: 'lower_abdomen',
name: 'lower_abdomen', name: 'lower_abdomen',
nameAr: 'البطن_السفلي',
description: 'Lower Abdomen', description: 'Lower Abdomen',
descriptionAr: 'أسفل البطن',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.51, y: 0.44), position: OrganPosition(x: 0.51, y: 0.44),
), ),
@ -125,14 +155,18 @@ class OrganData {
OrganModel( OrganModel(
id: 'left_groin', id: 'left_groin',
name: 'sexual_organs', name: 'sexual_organs',
nameAr: 'الأعضاء_التناسلية',
description: 'Left Groin', description: 'Left Groin',
descriptionAr: 'الفخذ الأيسر',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.42, y: 0.49), position: OrganPosition(x: 0.42, y: 0.49),
), ),
OrganModel( OrganModel(
id: 'right_groin', id: 'right_groin',
name: 'sexual_organs', name: 'sexual_organs',
nameAr: 'الأعضاء_التناسلية',
description: 'Right Groin', description: 'Right Groin',
descriptionAr: 'الفخذ الأيمن',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.59, y: 0.49), position: OrganPosition(x: 0.59, y: 0.49),
), ),
@ -142,21 +176,27 @@ class OrganData {
OrganModel( OrganModel(
id: 'left_elbow', id: 'left_elbow',
name: 'elbow', name: 'elbow',
nameAr: 'الكوع',
description: 'Left Elbow', description: 'Left Elbow',
descriptionAr: 'الكوع الأيسر',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.21, y: 0.35), position: OrganPosition(x: 0.21, y: 0.35),
), ),
OrganModel( OrganModel(
id: 'left_forearm', id: 'left_forearm',
name: 'forearm', name: 'forearm',
nameAr: 'الساعد',
description: 'Left Forearm', description: 'Left Forearm',
descriptionAr: 'الساعد الأيسر',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.19, y: 0.43), position: OrganPosition(x: 0.19, y: 0.43),
), ),
OrganModel( OrganModel(
id: 'left_wrist', id: 'left_wrist',
name: 'hand', name: 'hand',
nameAr: 'اليد',
description: 'Left Wrist', description: 'Left Wrist',
descriptionAr: 'المعصم الأيسر',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.14, y: 0.5), position: OrganPosition(x: 0.14, y: 0.5),
), ),
@ -166,21 +206,27 @@ class OrganData {
OrganModel( OrganModel(
id: 'right_elbow', id: 'right_elbow',
name: 'elbow', name: 'elbow',
nameAr: 'الكوع',
description: 'Right Elbow', description: 'Right Elbow',
descriptionAr: 'الكوع الأيمن',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.79, y: 0.35), position: OrganPosition(x: 0.79, y: 0.35),
), ),
OrganModel( OrganModel(
id: 'right_forearm', id: 'right_forearm',
name: 'forearm', name: 'forearm',
nameAr: 'الساعد',
description: 'Right Forearm', description: 'Right Forearm',
descriptionAr: 'الساعد الأيمن',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.81, y: 0.43), position: OrganPosition(x: 0.81, y: 0.43),
), ),
OrganModel( OrganModel(
id: 'right_wrist', id: 'right_wrist',
name: 'hand', name: 'hand',
nameAr: 'اليد',
description: 'Right Wrist', description: 'Right Wrist',
descriptionAr: 'المعصم الأيمن',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.85, y: 0.5), position: OrganPosition(x: 0.85, y: 0.5),
), ),
@ -189,28 +235,36 @@ class OrganData {
OrganModel( OrganModel(
id: 'left_thigh', id: 'left_thigh',
name: 'thigh', name: 'thigh',
nameAr: 'الفخذ',
description: 'Left Thigh', description: 'Left Thigh',
descriptionAr: 'الفخذ الأيسر',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.4, y: 0.60), position: OrganPosition(x: 0.4, y: 0.60),
), ),
OrganModel( OrganModel(
id: 'left_knee', id: 'left_knee',
name: 'knee', name: 'knee',
nameAr: 'الركبة',
description: 'Left Knee', description: 'Left Knee',
descriptionAr: 'الركبة اليسرى',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.4, y: 0.72), position: OrganPosition(x: 0.4, y: 0.72),
), ),
OrganModel( OrganModel(
id: 'left_shin', id: 'left_shin',
name: 'lower_leg', name: 'lower_leg',
nameAr: 'الساق_السفلي',
description: 'Left Shin', description: 'Left Shin',
descriptionAr: 'الساق اليسرى',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.41, y: 0.82), position: OrganPosition(x: 0.41, y: 0.82),
), ),
OrganModel( OrganModel(
id: 'left_ankle', id: 'left_ankle',
name: 'foot', name: 'foot',
nameAr: 'القدم',
description: 'Left Ankle', description: 'Left Ankle',
descriptionAr: 'الكاحل الأيسر',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.43, y: 0.91), position: OrganPosition(x: 0.43, y: 0.91),
), ),
@ -219,28 +273,36 @@ class OrganData {
OrganModel( OrganModel(
id: 'right_thigh', id: 'right_thigh',
name: 'thigh', name: 'thigh',
nameAr: 'الفخذ',
description: 'Right Thigh', description: 'Right Thigh',
descriptionAr: 'الفخذ الأيمن',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.65, y: 0.60), position: OrganPosition(x: 0.65, y: 0.60),
), ),
OrganModel( OrganModel(
id: 'right_knee', id: 'right_knee',
name: 'knee', name: 'knee',
nameAr: 'الركبة',
description: 'Right Knee', description: 'Right Knee',
descriptionAr: 'الركبة اليمنى',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.6, y: 0.72), position: OrganPosition(x: 0.6, y: 0.72),
), ),
OrganModel( OrganModel(
id: 'right_shin', id: 'right_shin',
name: 'lower_leg', name: 'lower_leg',
nameAr: 'الساق_السفلي',
description: 'Right Shin', description: 'Right Shin',
descriptionAr: 'الساق اليمنى',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.57, y: 0.82), position: OrganPosition(x: 0.57, y: 0.82),
), ),
OrganModel( OrganModel(
id: 'right_ankle', id: 'right_ankle',
name: 'foot', name: 'foot',
nameAr: 'القدم',
description: 'Right Ankle', description: 'Right Ankle',
descriptionAr: 'الكاحل الأيمن',
bodyView: BodyView.front, bodyView: BodyView.front,
position: OrganPosition(x: 0.57, y: 0.91), position: OrganPosition(x: 0.57, y: 0.91),
), ),
@ -252,14 +314,18 @@ class OrganData {
OrganModel( OrganModel(
id: 'back_of_head', id: 'back_of_head',
name: 'whole_head', name: 'whole_head',
nameAr: 'الرأس_كامل',
description: 'Back of Head', description: 'Back of Head',
descriptionAr: 'مؤخرة الرأس',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.50, y: 0.04), position: OrganPosition(x: 0.50, y: 0.04),
), ),
OrganModel( OrganModel(
id: 'neck_back', id: 'neck_back',
name: 'nape_of_neck', name: 'nape_of_neck',
nameAr: 'مؤخرة_الرقبة',
description: 'Neck', description: 'Neck',
descriptionAr: 'الرقبة',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.50, y: 0.14), position: OrganPosition(x: 0.50, y: 0.14),
), ),
@ -268,14 +334,18 @@ class OrganData {
OrganModel( OrganModel(
id: 'left_shoulder_back', id: 'left_shoulder_back',
name: 'upper_arm', name: 'upper_arm',
nameAr: 'الذراع_العلوي',
description: 'Left Shoulder', description: 'Left Shoulder',
descriptionAr: 'الكتف الأيسر',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.33, y: 0.19), position: OrganPosition(x: 0.33, y: 0.19),
), ),
OrganModel( OrganModel(
id: 'right_shoulder_back', id: 'right_shoulder_back',
name: 'upper_arm', name: 'upper_arm',
nameAr: 'الذراع_العلوي',
description: 'Right Shoulder', description: 'Right Shoulder',
descriptionAr: 'الكتف الأيمن',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.67, y: 0.19), position: OrganPosition(x: 0.67, y: 0.19),
), ),
@ -284,21 +354,27 @@ class OrganData {
OrganModel( OrganModel(
id: 'upper_spine', id: 'upper_spine',
name: 'back', name: 'back',
nameAr: 'الظهر',
description: 'Upper Spine', description: 'Upper Spine',
descriptionAr: 'العمود الفقري العلوي',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.50, y: 0.23), position: OrganPosition(x: 0.50, y: 0.23),
), ),
OrganModel( OrganModel(
id: 'left_upper_back', id: 'left_upper_back',
name: 'back', name: 'back',
nameAr: 'الظهر',
description: 'Left Upper Back', description: 'Left Upper Back',
descriptionAr: 'أعلى الظهر الأيسر',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.38, y: 0.28), position: OrganPosition(x: 0.38, y: 0.28),
), ),
OrganModel( OrganModel(
id: 'right_upper_back', id: 'right_upper_back',
name: 'back', name: 'back',
nameAr: 'الظهر',
description: 'Right Upper Back', description: 'Right Upper Back',
descriptionAr: 'أعلى الظهر الأيمن',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.62, y: 0.28), position: OrganPosition(x: 0.62, y: 0.28),
), ),
@ -307,21 +383,27 @@ class OrganData {
OrganModel( OrganModel(
id: 'mid_spine', id: 'mid_spine',
name: 'back', name: 'back',
nameAr: 'الظهر',
description: 'Mid Spine', description: 'Mid Spine',
descriptionAr: 'العمود الفقري الأوسط',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.50, y: 0.35), position: OrganPosition(x: 0.50, y: 0.35),
), ),
OrganModel( OrganModel(
id: 'left_mid_back', id: 'left_mid_back',
name: 'back', name: 'back',
nameAr: 'الظهر',
description: 'Left Mid Back', description: 'Left Mid Back',
descriptionAr: 'وسط الظهر الأيسر',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.38, y: 0.35), position: OrganPosition(x: 0.38, y: 0.35),
), ),
OrganModel( OrganModel(
id: 'right_mid_back', id: 'right_mid_back',
name: 'back', name: 'back',
nameAr: 'الظهر',
description: 'Right Mid Back', description: 'Right Mid Back',
descriptionAr: 'وسط الظهر الأيمن',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.62, y: 0.35), position: OrganPosition(x: 0.62, y: 0.35),
), ),
@ -330,21 +412,27 @@ class OrganData {
OrganModel( OrganModel(
id: 'lower_spine', id: 'lower_spine',
name: 'lower_back', name: 'lower_back',
nameAr: 'أسفل_الظهر',
description: 'Lower Back', description: 'Lower Back',
descriptionAr: 'أسفل الظهر',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.50, y: 0.43), position: OrganPosition(x: 0.50, y: 0.43),
), ),
OrganModel( OrganModel(
id: 'left_lower_back', id: 'left_lower_back',
name: 'lower_back', name: 'lower_back',
nameAr: 'أسفل_الظهر',
description: 'Left Lower Back', description: 'Left Lower Back',
descriptionAr: 'أسفل الظهر الأيسر',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.40, y: 0.43), position: OrganPosition(x: 0.40, y: 0.43),
), ),
OrganModel( OrganModel(
id: 'right_lower_back', id: 'right_lower_back',
name: 'lower_back', name: 'lower_back',
nameAr: 'أسفل_الظهر',
description: 'Right Lower Back', description: 'Right Lower Back',
descriptionAr: 'أسفل الظهر الأيمن',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.60, y: 0.43), position: OrganPosition(x: 0.60, y: 0.43),
), ),
@ -353,21 +441,27 @@ class OrganData {
OrganModel( OrganModel(
id: 'sacrum', id: 'sacrum',
name: 'lower_back', name: 'lower_back',
nameAr: 'أسفل_الظهر',
description: 'Sacrum', description: 'Sacrum',
descriptionAr: 'العجز',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.50, y: 0.52), position: OrganPosition(x: 0.50, y: 0.52),
), ),
OrganModel( OrganModel(
id: 'left_glute', id: 'left_glute',
name: 'buttocks', name: 'buttocks',
nameAr: 'الأرداف',
description: 'Left Glute', description: 'Left Glute',
descriptionAr: 'الأرداف اليسرى',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.45, y: 0.56), position: OrganPosition(x: 0.45, y: 0.56),
), ),
OrganModel( OrganModel(
id: 'right_glute', id: 'right_glute',
name: 'buttocks', name: 'buttocks',
nameAr: 'الأرداف',
description: 'Right Glute', description: 'Right Glute',
descriptionAr: 'الأرداف اليمنى',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.55, y: 0.56), position: OrganPosition(x: 0.55, y: 0.56),
), ),
@ -376,28 +470,36 @@ class OrganData {
OrganModel( OrganModel(
id: 'left_hamstring', id: 'left_hamstring',
name: 'thigh', name: 'thigh',
nameAr: 'الفخذ',
description: 'Left Hamstring', description: 'Left Hamstring',
descriptionAr: 'عضلة الفخذ الخلفية اليسرى',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.43, y: 0.65), position: OrganPosition(x: 0.43, y: 0.65),
), ),
OrganModel( OrganModel(
id: 'right_hamstring', id: 'right_hamstring',
name: 'thigh', name: 'thigh',
nameAr: 'الفخذ',
description: 'Right Hamstring', description: 'Right Hamstring',
descriptionAr: 'عضلة الفخذ الخلفية اليمنى',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.57, y: 0.65), position: OrganPosition(x: 0.57, y: 0.65),
), ),
OrganModel( OrganModel(
id: 'left_calf', id: 'left_calf',
name: 'lower_leg', name: 'lower_leg',
nameAr: 'الساق_السفلي',
description: 'Left Calf', description: 'Left Calf',
descriptionAr: 'ربلة الساق اليسرى',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.43, y: 0.79), position: OrganPosition(x: 0.43, y: 0.79),
), ),
OrganModel( OrganModel(
id: 'right_calf', id: 'right_calf',
name: 'lower_leg', name: 'lower_leg',
nameAr: 'الساق_السفلي',
description: 'Right Calf', description: 'Right Calf',
descriptionAr: 'ربلة الساق اليمنى',
bodyView: BodyView.back, bodyView: BodyView.back,
position: OrganPosition(x: 0.57, y: 0.79), position: OrganPosition(x: 0.57, y: 0.79),
), ),

@ -3,29 +3,47 @@ import 'package:hmg_patient_app_new/core/enums.dart';
class OrganModel { class OrganModel {
final String id; final String id;
final String name; final String name;
final String nameAr;
final String description; final String description;
final String descriptionAr;
final BodyView bodyView; final BodyView bodyView;
final OrganPosition position; final OrganPosition position;
const OrganModel({ const OrganModel({
required this.id, required this.id,
required this.name, required this.name,
required this.nameAr,
required this.description, required this.description,
required this.descriptionAr,
required this.bodyView, required this.bodyView,
required this.position, required this.position,
}); });
/// Get localized name based on isArabic flag
String getLocalizedName(bool isArabic) {
return isArabic ? nameAr : name;
}
/// Get localized description based on isArabic flag
String getLocalizedDescription(bool isArabic) {
return isArabic ? descriptionAr : description;
}
OrganModel copyWith({ OrganModel copyWith({
String? id, String? id,
String? name, String? name,
String? nameAr,
String? description, String? description,
String? descriptionAr,
BodyView? bodyView, BodyView? bodyView,
OrganPosition? position, OrganPosition? position,
}) { }) {
return OrganModel( return OrganModel(
id: id ?? this.id, id: id ?? this.id,
name: name ?? this.name, name: name ?? this.name,
nameAr: nameAr ?? this.nameAr,
description: description ?? this.description, description: description ?? this.description,
descriptionAr: descriptionAr ?? this.descriptionAr,
bodyView: bodyView ?? this.bodyView, bodyView: bodyView ?? this.bodyView,
position: position ?? this.position, position: position ?? this.position,
); );

@ -22,6 +22,8 @@ class RiskAndSuggestionsItemModel {
final String? type; final String? type;
final String? name; final String? name;
final String? commonName; final String? commonName;
final String? nameAr;
final String? commonNameAr;
final String? language; final String? language;
RiskAndSuggestionsItemModel({ RiskAndSuggestionsItemModel({
@ -29,6 +31,8 @@ class RiskAndSuggestionsItemModel {
this.type, this.type,
this.name, this.name,
this.commonName, this.commonName,
this.nameAr,
this.commonNameAr,
this.language, this.language,
}); });
@ -38,6 +42,8 @@ class RiskAndSuggestionsItemModel {
type: json['type'], type: json['type'],
name: json['name'], name: json['name'],
commonName: json['common_name'], commonName: json['common_name'],
nameAr: json['nameAr'],
commonNameAr: json['common_nameAr'],
language: json['language'], language: json['language'],
); );
} }
@ -48,12 +54,17 @@ class RiskAndSuggestionsItemModel {
'type': type, 'type': type,
'name': name, 'name': name,
'common_name': commonName, 'common_name': commonName,
'nameAr': nameAr,
'common_nameAr': commonNameAr,
'language': language, 'language': language,
}; };
} }
// Helper method to get display name // Helper method to get display name based on locale
String getDisplayName() { String getDisplayName({bool isArabic = false}) {
if (isArabic) {
return commonNameAr ?? nameAr ?? commonName ?? name ?? '';
}
return commonName ?? name ?? ''; return commonName ?? name ?? '';
} }
} }

@ -172,6 +172,8 @@ class TriageCondition {
final String? id; final String? id;
final String? name; final String? name;
final String? commonName; final String? commonName;
final String? nameAr;
final String? commonNameAr;
final double? probability; final double? probability;
final ConditionDetails? conditionDetails; final ConditionDetails? conditionDetails;
@ -179,6 +181,8 @@ class TriageCondition {
this.id, this.id,
this.name, this.name,
this.commonName, this.commonName,
this.nameAr,
this.commonNameAr,
this.probability, this.probability,
this.conditionDetails, this.conditionDetails,
}); });
@ -188,6 +192,8 @@ class TriageCondition {
id: json['id'], id: json['id'],
name: json['name'], name: json['name'],
commonName: json['common_name'], commonName: json['common_name'],
nameAr: json['nameAr'],
commonNameAr: json['common_nameAr'],
probability: json['probability']?.toDouble(), probability: json['probability']?.toDouble(),
conditionDetails: json['condition_details'] != null ? ConditionDetails.fromJson(json['condition_details']) : null, conditionDetails: json['condition_details'] != null ? ConditionDetails.fromJson(json['condition_details']) : null,
); );
@ -198,11 +204,21 @@ class TriageCondition {
'id': id, 'id': id,
'name': name, 'name': name,
'common_name': commonName, 'common_name': commonName,
'nameAr': nameAr,
'common_nameAr': commonNameAr,
'probability': probability, 'probability': probability,
'condition_details': conditionDetails?.toJson(), 'condition_details': conditionDetails?.toJson(),
}; };
} }
/// Get display name based on locale
String getDisplayName({bool isArabic = false}) {
if (isArabic) {
return commonNameAr ?? nameAr ?? commonName ?? name ?? '';
}
return commonName ?? name ?? '';
}
/// Get probability as percentage /// Get probability as percentage
String getProbabilityPercentage() { String getProbabilityPercentage() {
if (probability == null) return '0%'; if (probability == null) return '0%';

@ -63,7 +63,7 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo {
required String userName, required String userName,
required String password, required String password,
}) async { }) async {
Map<String, String> body = {"userName": userName, "password": password}; Map<String, dynamic> body = {"userName": userName, "password": password};
try { try {
GenericApiModel<SymptomsUserDetailsResponseModel>? apiResponse; GenericApiModel<SymptomsUserDetailsResponseModel>? apiResponse;

@ -23,6 +23,23 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
required this.appState, required this.appState,
}); });
// Gender constants for both English and Arabic
static const String _maleEn = "male";
static const String _femaleEn = "female";
static const String _maleAr = "ذكر";
static const String _femaleAr = "أنثى";
/// Convert gender string to integer (1 for male, 2 for female)
/// Handles both English and Arabic values
int _getGenderAsInt(String? gender) {
if (gender == null) return 1; // Default to male
final lowerGender = gender.toLowerCase();
if (lowerGender == _maleEn || gender == _maleAr) {
return 1;
}
return 2; // Female or any other value
}
// State variables // State variables
bool isBodyHidden = false; bool isBodyHidden = false;
BodyView _currentView = BodyView.front; BodyView _currentView = BodyView.front;
@ -440,7 +457,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
await getRiskFactors( await getRiskFactors(
age: _selectedAge!, age: _selectedAge!,
gender: _selectedGender!.toLowerCase() == "male" ? 1 : 2, gender: _getGenderAsInt(_selectedGender),
evidenceIds: evidenceIds, evidenceIds: evidenceIds,
sessionId: currentSessionId, sessionId: currentSessionId,
language: appState.isArabic() ? 'ar' : 'en', language: appState.isArabic() ? 'ar' : 'en',
@ -498,6 +515,8 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
id: "not_applicable", id: "not_applicable",
commonName: "Not Applicable", commonName: "Not Applicable",
name: "Not Applicable", name: "Not Applicable",
commonNameAr: "لا ينطبق",
nameAr: "لا ينطبق",
language: appState.isArabic() ? 'ar' : 'en', language: appState.isArabic() ? 'ar' : 'en',
type: null, type: null,
); );
@ -612,7 +631,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
await getSuggestions( await getSuggestions(
age: _selectedAge!, age: _selectedAge!,
gender: _selectedGender!.toLowerCase() == "male" ? 1 : 2, gender: _getGenderAsInt(_selectedGender),
evidenceIds: evidenceIds, evidenceIds: evidenceIds,
language: appState.isArabic() ? 'ar' : 'en', language: appState.isArabic() ? 'ar' : 'en',
onSuccess: (response) { onSuccess: (response) {
@ -668,6 +687,8 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
id: "not_applicable", id: "not_applicable",
commonName: "Not Applicable", commonName: "Not Applicable",
name: "Not Applicable", name: "Not Applicable",
commonNameAr: "لا ينطبق",
nameAr: "لا ينطبق",
language: appState.isArabic() ? 'ar' : 'en', language: appState.isArabic() ? 'ar' : 'en',
type: null, type: null,
); );
@ -764,7 +785,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
await getDiagnosisForTriage( await getDiagnosisForTriage(
age: _selectedAge!, age: _selectedAge!,
gender: _selectedGender!.toLowerCase() == "male" ? 1 : 2, gender: _getGenderAsInt(_selectedGender),
evidenceIds: evidenceIds, evidenceIds: evidenceIds,
language: appState.isArabic() ? 'ar' : 'en', language: appState.isArabic() ? 'ar' : 'en',
onSuccess: (response) { onSuccess: (response) {
@ -927,6 +948,22 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
bool get isUserInfoFirstPage => _userInfoCurrentPage == 0; bool get isUserInfoFirstPage => _userInfoCurrentPage == 0;
/// Check if current user info page has valid selection
bool get isCurrentUserInfoPageValid {
switch (_userInfoCurrentPage) {
case 0: // Gender page
return _selectedGender != null && _selectedGender!.isNotEmpty;
case 1: // Age/Birth date page
return _dateOfBirth != null || (_selectedAge != null && _selectedAge! > 0);
case 2: // Height page
return _selectedHeight > 0;
case 3: // Weight page
return _selectedWeight > 0;
default:
return false;
}
}
/// Validate and submit user info /// Validate and submit user info
Map<String, dynamic> getUserInfoData() { Map<String, dynamic> getUserInfoData() {
return { return {
@ -988,7 +1025,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier {
final result = await symptomsCheckerRepo.getBodySymptomsByName( final result = await symptomsCheckerRepo.getBodySymptomsByName(
organNames: organNames, organNames: organNames,
userSessionToken: currentSessionAuthToken, userSessionToken: currentSessionAuthToken,
gender: (selectedGender ?? "Male").toLowerCase() == "male" ? 1 : 2, gender: _getGenderAsInt(selectedGender ?? "Male"),
); );
result.fold( result.fold(

@ -1371,6 +1371,17 @@ abstract class LocaleKeys {
static const suggestions = 'suggestions'; static const suggestions = 'suggestions';
static const pleaseGoBackAndSelectOrgansFirst = 'pleaseGoBackAndSelectOrgansFirst'; static const pleaseGoBackAndSelectOrgansFirst = 'pleaseGoBackAndSelectOrgansFirst';
static const symptomsSelector = 'symptomsSelector'; static const symptomsSelector = 'symptomsSelector';
static const possibleSymptomsRelatedTo = 'possibleSymptomsRelatedTo';
static const suggestionAIListDescription = 'suggestionAIListDescription';
static const analyzing = 'analyzing';
static const seekMedicalAdvice = 'seekMedicalAdvice';
static const monitorDescription = 'monitorDescription';
static const seekMedicalAdviceDescription = 'seekMedicalAdviceDescription';
static const emergencyDescription = 'emergencyDescription';
static const colorScience = 'colorScience';
static const noNeedToVisitDoctor = 'noNeedToVisitDoctor';
static const commonSymptom = 'commonSymptom';
static const notApplicable = 'notApplicable';
static const emergencyTriage = 'emergencyTriage'; static const emergencyTriage = 'emergencyTriage';
static const emergencyEvidenceDetected = 'emergencyEvidenceDetected'; static const emergencyEvidenceDetected = 'emergencyEvidenceDetected';
static const noQuestionItemsAvailable = 'noQuestionItemsAvailable'; static const noQuestionItemsAvailable = 'noQuestionItemsAvailable';
@ -1488,5 +1499,18 @@ abstract class LocaleKeys {
static const pleaseWaitYouWillBeCalledForVitalSigns = 'pleaseWaitYouWillBeCalledForVitalSigns'; static const pleaseWaitYouWillBeCalledForVitalSigns = 'pleaseWaitYouWillBeCalledForVitalSigns';
static const pleaseVisitRoomForVitalSigns = 'pleaseVisitRoomForVitalSigns'; static const pleaseVisitRoomForVitalSigns = 'pleaseVisitRoomForVitalSigns';
static const pleaseVisitRoomToTheDoctor = 'pleaseVisitRoomToTheDoctor'; static const pleaseVisitRoomToTheDoctor = 'pleaseVisitRoomToTheDoctor';
static const erOnlineCheckInRequest = 'erOnlineCheckInRequest';
static const indoor = 'indoor';
static const navigation = 'navigation';
static const health = 'health';
static const calculators = 'calculators';
static const converters = 'converters';
static const guide = 'guide';
static const liveCareServiceDesc = 'liveCareServiceDesc';
static const bloodGroup = 'bloodGroup';
static const medicalServices = 'medicalServices';
static const insuranceAndPayments = 'insuranceAndPayments';
static const trackerAndOthers = 'trackerAndOthers';
static const bmi = 'bmi';
} }

@ -87,7 +87,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
children: [ children: [
Expanded( Expanded(
child: CollapsingListView( child: CollapsingListView(
title: LocaleKeys.appointmentDetails.tr(), title: LocaleKeys.appointmentDetails.tr(context: context),
report: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) report: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)
? () { ? () {
contactUsViewModel.setPatientFeedbackSelectedAppointment(widget.patientAppointmentHistoryResponseModel); contactUsViewModel.setPatientFeedbackSelectedAppointment(widget.patientAppointmentHistoryResponseModel);
@ -105,7 +105,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
AppointmentDoctorCard( AppointmentDoctorCard(
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
onAskDoctorTap: () async { onAskDoctorTap: () async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingDoctorAvailability.tr()); LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingDoctorAvailability.tr(context: context));
await myAppointmentsViewModel.isDoctorAvailable( await myAppointmentsViewModel.isDoctorAvailable(
projectID: widget.patientAppointmentHistoryResponseModel.projectID, projectID: widget.patientAppointmentHistoryResponseModel.projectID,
doctorId: widget.patientAppointmentHistoryResponseModel.doctorID, doctorId: widget.patientAppointmentHistoryResponseModel.doctorID,
@ -135,7 +135,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
onCancelTap: () async { onCancelTap: () async {
myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true);
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.cancellingAppointmentPleaseWait.tr()); LoaderBottomSheet.showLoader(loadingText: LocaleKeys.cancellingAppointmentPleaseWait.tr(context: context));
await myAppointmentsViewModel.cancelAppointment( await myAppointmentsViewModel.cancelAppointment(
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
onSuccess: (apiResponse) { onSuccess: (apiResponse) {
@ -144,7 +144,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
myAppointmentsViewModel.getPatientAppointments(true, false); myAppointmentsViewModel.getPatientAppointments(true, false);
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
context, context,
child: Utils.getSuccessWidget(loadingText: LocaleKeys.appointmentCancelledSuccessfully.tr()), child: Utils.getSuccessWidget(loadingText: LocaleKeys.appointmentCancelledSuccessfully.tr(context: context)),
callBackFunc: () { callBackFunc: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
@ -181,13 +181,13 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
children: [ children: [
Row( Row(
children: [ children: [
LocaleKeys.appointmentStatus.tr().toText16(isBold: true), LocaleKeys.appointmentStatus.tr(context: context).toText16(isBold: true),
], ],
), ),
SizedBox(height: 4.h), SizedBox(height: 4.h),
(!AppointmentType.isConfirmed(widget.patientAppointmentHistoryResponseModel) (!AppointmentType.isConfirmed(widget.patientAppointmentHistoryResponseModel)
? LocaleKeys.notConfirmed.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500) ? LocaleKeys.notConfirmed.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500)
: LocaleKeys.confirmed.tr().toText12(color: AppColors.successColor, fontWeight: FontWeight.w500)), : LocaleKeys.confirmed.tr(context: context).toText12(color: AppColors.successColor, fontWeight: FontWeight.w500)),
SizedBox(height: 16.h), SizedBox(height: 16.h),
//TODO Add countdown timer in case of LiveCare Appointment //TODO Add countdown timer in case of LiveCare Appointment
widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false
@ -199,7 +199,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.doctorWillCallYou.tr().toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), LocaleKeys.doctorWillCallYou.tr(context: context).toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
], ],
), ),
), ),
@ -225,7 +225,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
MapsLauncher.launchCoordinates(double.parse(widget.patientAppointmentHistoryResponseModel.latitude!), MapsLauncher.launchCoordinates(double.parse(widget.patientAppointmentHistoryResponseModel.latitude!),
double.parse(widget.patientAppointmentHistoryResponseModel.longitude!), widget.patientAppointmentHistoryResponseModel.projectName); double.parse(widget.patientAppointmentHistoryResponseModel.longitude!), widget.patientAppointmentHistoryResponseModel.projectName);
}, },
text: LocaleKeys.getDirections.tr(), text: LocaleKeys.getDirections.tr(context: context),
backgroundColor: AppColors.textColor.withValues(alpha: 0.8), backgroundColor: AppColors.textColor.withValues(alpha: 0.8),
borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.01), borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.01),
textColor: AppColors.whiteColor, textColor: AppColors.whiteColor,
@ -280,7 +280,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.setReminder.tr(context: context).toText13(isBold: true), LocaleKeys.setReminder.tr(context: context).toText13(isBold: true),
LocaleKeys.notifyMeBeforeAppointment.tr().toText11(color: AppColors.textColorLight, weight: FontWeight.w500), LocaleKeys.notifyMeBeforeAppointment.tr(context: context).toText11(color: AppColors.textColorLight, weight: FontWeight.w500),
], ],
), ),
const Spacer(), const Spacer(),
@ -365,7 +365,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
isLargeText: true, isLargeText: true,
iconSize: 36.w, iconSize: 36.w,
).onPress(() async { ).onPress(() async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingLabResults.tr()); LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingLabResults.tr(context: context));
await labViewModel.getLabResultsByAppointmentNo( await labViewModel.getLabResultsByAppointmentNo(
appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo, appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo,
projectID: widget.patientAppointmentHistoryResponseModel.projectID, projectID: widget.patientAppointmentHistoryResponseModel.projectID,
@ -398,7 +398,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
isLargeText: true, isLargeText: true,
iconSize: 36.w, iconSize: 36.w,
).onPress(() async { ).onPress(() async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingRadiologyResults.tr()); LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingRadiologyResults.tr(context: context));
await radiologyViewModel.getPatientRadiologyOrdersByAppointment( await radiologyViewModel.getPatientRadiologyOrdersByAppointment(
appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo, appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo,
projectID: widget.patientAppointmentHistoryResponseModel.projectID, projectID: widget.patientAppointmentHistoryResponseModel.projectID,
@ -425,7 +425,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
isLargeText: true, isLargeText: true,
iconSize: 36.w, iconSize: 36.w,
).onPress(() async { ).onPress(() async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingAppointmentPrescriptions.tr()); LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingAppointmentPrescriptions.tr(context: context));
await prescriptionsViewModel.getPrescriptionDetails( await prescriptionsViewModel.getPrescriptionDetails(
getPrescriptionRequestModel(), getPrescriptionRequestModel(),
onSuccess: (val) { onSuccess: (val) {
@ -453,7 +453,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
} else { } else {
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
context, context,
child: Utils.getErrorWidget(loadingText: LocaleKeys.noPrescriptionsForAppointment.tr()), child: Utils.getErrorWidget(loadingText: LocaleKeys.noPrescriptionsForAppointment.tr(context: context)),
callBackFunc: () {}, callBackFunc: () {},
isFullScreen: false, isFullScreen: false,
isCloseButtonVisible: true, isCloseButtonVisible: true,
@ -522,7 +522,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
// ], // ],
// ), // ),
// SizedBox(height: 16.h), // SizedBox(height: 16.h),
// LocaleKeys.prescriptions.tr().toText18(isBold: true), // LocaleKeys.prescriptions.tr(context: context).toText18(isBold: true),
// SizedBox(height: 16.h), // SizedBox(height: 16.h),
// Consumer<PrescriptionsViewModel>(builder: (context, prescriptionVM, child) { // Consumer<PrescriptionsViewModel>(builder: (context, prescriptionVM, child) {
// return prescriptionVM.isPrescriptionsDetailsLoading // return prescriptionVM.isPrescriptionsDetailsLoading
@ -708,7 +708,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
LocaleKeys.amountBeforeTax.tr().toText18(isBold: true), LocaleKeys.amountBeforeTax.tr(context: context).toText18(isBold: true),
Utils.getPaymentAmountWithSymbol( Utils.getPaymentAmountWithSymbol(
widget.patientAppointmentHistoryResponseModel.patientShare!.toString().toText16(isBold: true), widget.patientAppointmentHistoryResponseModel.patientShare!.toString().toText16(isBold: true),
AppColors.blackColor, AppColors.blackColor,
@ -752,7 +752,7 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
).paddingOnly(left: 16.h, top: 24.h, right: 16.h, bottom: 0.h), ).paddingOnly(left: 16.h, top: 24.h, right: 16.h, bottom: 0.h),
AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)
? CustomButton( ? CustomButton(
text: LocaleKeys.rebookAppointment.tr(), text: LocaleKeys.rebookAppointment.tr(context: context),
onPressed: () { onPressed: () {
openDoctorScheduleCalendar(); openDoctorScheduleCalendar();
}, },
@ -810,13 +810,13 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
projectName: widget.patientAppointmentHistoryResponseModel.projectName, projectName: widget.patientAppointmentHistoryResponseModel.projectName,
); );
bookAppointmentsViewModel.setSelectedDoctor(doctor); bookAppointmentsViewModel.setSelectedDoctor(doctor);
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingDoctorSchedulePleaseWait.tr()); LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingDoctorSchedulePleaseWait.tr(context: context));
await bookAppointmentsViewModel.getDoctorFreeSlots( await bookAppointmentsViewModel.getDoctorFreeSlots(
isBookingForLiveCare: false, isBookingForLiveCare: false,
onSuccess: (dynamic respData) async { onSuccess: (dynamic respData) async {
LoaderBottomSheet.hideLoader(); LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
title: LocaleKeys.pickADate.tr(), title: LocaleKeys.pickADate.tr(context: context),
context, context,
child: AppointmentCalendar(), child: AppointmentCalendar(),
isFullScreen: false, isFullScreen: false,
@ -841,14 +841,14 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
case 0: case 0:
break; break;
case 10: case 10:
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.confirmingAppointmentPleaseWait.tr()); LoaderBottomSheet.showLoader(loadingText: LocaleKeys.confirmingAppointmentPleaseWait.tr(context: context));
await myAppointmentsViewModel.confirmAppointment( await myAppointmentsViewModel.confirmAppointment(
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
onSuccess: (apiResponse) { onSuccess: (apiResponse) {
LoaderBottomSheet.hideLoader(); LoaderBottomSheet.hideLoader();
myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true);
myAppointmentsViewModel.getPatientAppointments(true, false); myAppointmentsViewModel.getPatientAppointments(true, false);
showCommonBottomSheet(context, child: Utils.getSuccessWidget(loadingText: LocaleKeys.appointmentConfirmedSuccessfully.tr()), callBackFunc: (str) { showCommonBottomSheet(context, child: Utils.getSuccessWidget(loadingText: LocaleKeys.appointmentConfirmedSuccessfully.tr(context: context)), callBackFunc: (str) {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
title: "", title: "",
@ -869,10 +869,10 @@ class _AppointmentDetailsPageState extends State<AppointmentDetailsPage> {
), ),
); );
case 50: case 50:
// return LocaleKeys.confirmLiveCare.tr(); // return LocaleKeys.confirmLiveCare.tr(context: context);
case 90: case 90:
showCommonBottomSheetWithoutHeight(context, showCommonBottomSheetWithoutHeight(context,
title: LocaleKeys.onlineCheckIn.tr(), title: LocaleKeys.onlineCheckIn.tr(context: context),
child: AppointmentCheckinBottomSheet( child: AppointmentCheckinBottomSheet(
patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel,
myAppointmentsViewModel: myAppointmentsViewModel, myAppointmentsViewModel: myAppointmentsViewModel,

@ -90,7 +90,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
children: [ children: [
Expanded( Expanded(
child: CollapsingListView( child: CollapsingListView(
title: LocaleKeys.appointmentPayment.tr(), title: LocaleKeys.appointmentPayment.tr(context: context),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -248,7 +248,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
LocaleKeys.insuranceExpiredOrInactive.tr() LocaleKeys.insuranceExpiredOrInactive.tr(context: context)
.toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500) .toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500)
.paddingSymmetrical(24.h, 0.h), .paddingSymmetrical(24.h, 0.h),
CustomButton( CustomButton(
@ -274,12 +274,12 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
) )
: const SizedBox(), : const SizedBox(),
SizedBox(height: 24.h), SizedBox(height: 24.h),
LocaleKeys.totalAmountToPay.tr().toText18(isBold: true).paddingSymmetrical(24.h, 0.h), LocaleKeys.totalAmountToPay.tr(context: context).toText18(isBold: true).paddingSymmetrical(24.h, 0.h),
SizedBox(height: 17.h), SizedBox(height: 17.h),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
LocaleKeys.amountBeforeTax.tr().toText14(isBold: true), LocaleKeys.amountBeforeTax.tr(context: context).toText14(isBold: true),
Utils.getPaymentAmountWithSymbol( Utils.getPaymentAmountWithSymbol(
myAppointmentsVM.patientAppointmentShareResponseModel!.patientShare!.toString().toText16(isBold: true), myAppointmentsVM.patientAppointmentShareResponseModel!.patientShare!.toString().toText16(isBold: true),
AppColors.blackColor, AppColors.blackColor,
@ -380,7 +380,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
} }
void checkPaymentStatus() async { void checkPaymentStatus() async {
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingPaymentStatusPleaseWait.tr()); LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingPaymentStatusPleaseWait.tr(context: context));
if (selectedPaymentMethod == "TAMARA") { if (selectedPaymentMethod == "TAMARA") {
await payfortViewModel.checkTamaraPaymentStatus( await payfortViewModel.checkTamaraPaymentStatus(
transactionID: transID, transactionID: transID,
@ -438,7 +438,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
LoaderBottomSheet.hideLoader(); LoaderBottomSheet.hideLoader();
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
context, context,
child: Utils.getErrorWidget(loadingText: LocaleKeys.paymentFailedPleaseTryAgain.tr()), child: Utils.getErrorWidget(loadingText: LocaleKeys.paymentFailedPleaseTryAgain.tr(context: context)),
callBackFunc: () {}, callBackFunc: () {},
isFullScreen: false, isFullScreen: false,
isCloseButtonVisible: true, isCloseButtonVisible: true,
@ -519,7 +519,7 @@ class _AppointmentPaymentPageState extends State<AppointmentPaymentPage> {
} else { } else {
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
context, context,
child: Utils.getErrorWidget(loadingText: LocaleKeys.paymentFailedPleaseTryAgain.tr()), child: Utils.getErrorWidget(loadingText: LocaleKeys.paymentFailedPleaseTryAgain.tr(context: context)),
callBackFunc: () {}, callBackFunc: () {},
isFullScreen: false, isFullScreen: false,
isCloseButtonVisible: true, isCloseButtonVisible: true,

@ -155,7 +155,7 @@ class _MyAppointmentsPageState extends State<MyAppointmentsPage> {
isLoading: true, isLoading: true,
isFromHomePage: false, isFromHomePage: false,
), ),
).paddingSymmetrical(24.h, 0.h) )
: filteredAppointmentList.isNotEmpty : filteredAppointmentList.isNotEmpty
? AnimationConfiguration.staggeredList( ? AnimationConfiguration.staggeredList(
position: index, position: index,

@ -32,7 +32,7 @@ import '../../../emergency_services/call_ambulance/widgets/type_selection_widget
// crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
// children: [ // children: [
// Text( // Text(
// LocaleKeys.selectHospital.tr(), // LocaleKeys.selectHospital.tr(context: context),
// style: TextStyle( // style: TextStyle(
// fontSize: 21, // fontSize: 21,
// fontWeight: FontWeight.w600, // fontWeight: FontWeight.w600,
@ -40,7 +40,7 @@ import '../../../emergency_services/call_ambulance/widgets/type_selection_widget
// ), // ),
// ), // ),
// Text( // Text(
// LocaleKeys.selectHospitalSubTitle.tr(), // LocaleKeys.selectHospitalSubTitle.tr(context: context),
// style: TextStyle( // style: TextStyle(
// fontSize: 16, // fontSize: 16,
// fontWeight: FontWeight.w500, // fontWeight: FontWeight.w500,
@ -49,8 +49,8 @@ import '../../../emergency_services/call_ambulance/widgets/type_selection_widget
// ), // ),
// SizedBox(height: 16.h), // SizedBox(height: 16.h),
// TextInputWidget( // TextInputWidget(
// labelText: LocaleKeys.search.tr(), // labelText: LocaleKeys.search.tr(context: context),
// hintText: LocaleKeys.searchHospital.tr(), // hintText: LocaleKeys.searchHospital.tr(context: context),
// controller: searchText, // controller: searchText,
// onChange: (value) { // onChange: (value) {
// appointmentsViewModel.filterHospitalListByString( // appointmentsViewModel.filterHospitalListByString(
@ -135,8 +135,8 @@ class HospitalBottomSheetBody extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
TextInputWidget( TextInputWidget(
labelText: LocaleKeys.search.tr(), labelText: LocaleKeys.search.tr(context: context),
hintText: LocaleKeys.searchHospital.tr(), hintText: LocaleKeys.searchHospital.tr(context: context),
controller: searchText, controller: searchText,
onChange: (value) { onChange: (value) {
debouncer.run((){ debouncer.run((){

@ -71,10 +71,10 @@ class LoginScreenState extends State<LoginScreen> {
children: [ children: [
Utils.showLottie(context: context, assetPath: AppAnimations.login, width: 200.h, height: 200.h, repeat: true, fit: BoxFit.cover), Utils.showLottie(context: context, assetPath: AppAnimations.login, width: 200.h, height: 200.h, repeat: true, fit: BoxFit.cover),
SizedBox(height: 130.h), // Adjusted to sizer unit SizedBox(height: 130.h), // Adjusted to sizer unit
LocaleKeys.welcomeToDrSulaiman.tr().toText32(isBold: true, color: AppColors.textColor), LocaleKeys.welcomeToDrSulaiman.tr(context: context).toText32(isBold: true, color: AppColors.textColor),
SizedBox(height: 32.h), SizedBox(height: 32.h),
TextInputWidget( TextInputWidget(
labelText: "${LocaleKeys.nationalId.tr()} / ${LocaleKeys.fileNo.tr()}", labelText: "${LocaleKeys.nationalId.tr(context: context)} / ${LocaleKeys.fileNo.tr(context: context)}",
hintText: "xxxxxxxxx", hintText: "xxxxxxxxx",
controller: authVm.nationalIdController, controller: authVm.nationalIdController,
focusNode: _nationalIdFocusNode, focusNode: _nationalIdFocusNode,
@ -87,13 +87,13 @@ class LoginScreenState extends State<LoginScreen> {
isAllowLeadingIcon: true, isAllowLeadingIcon: true,
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 10.h), padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 10.h),
leadingIcon: AppAssets.student_card, leadingIcon: AppAssets.student_card,
errorMessage: LocaleKeys.enterValidIDorIqama.tr(), errorMessage: LocaleKeys.enterValidIDorIqama.tr(context: context),
hasError: false, hasError: false,
), ),
SizedBox(height: 16.h), SizedBox(height: 16.h),
CustomButton( CustomButton(
height: 50.h, height: 50.h,
text: LocaleKeys.login.tr(), text: LocaleKeys.login.tr(context: context),
icon: AppAssets.login1, icon: AppAssets.login1,
iconColor: Colors.white, iconColor: Colors.white,
onPressed: () { onPressed: () {
@ -116,10 +116,10 @@ class LoginScreenState extends State<LoginScreen> {
text: TextSpan( text: TextSpan(
style: context.dynamicTextStyle(color: Colors.black, fontSize: 14.f, height: 26 / 16, fontWeight: FontWeight.w500), style: context.dynamicTextStyle(color: Colors.black, fontSize: 14.f, height: 26 / 16, fontWeight: FontWeight.w500),
children: <TextSpan>[ children: <TextSpan>[
TextSpan(text: LocaleKeys.dontHaveAccount.tr(), style: context.dynamicTextStyle()), TextSpan(text: LocaleKeys.dontHaveAccount.tr(context: context), style: context.dynamicTextStyle()),
TextSpan(text: " "), TextSpan(text: " "),
TextSpan( TextSpan(
text: LocaleKeys.registernow.tr(), text: LocaleKeys.registernow.tr(context: context),
style: context.dynamicTextStyle( style: context.dynamicTextStyle(
color: AppColors.primaryRedColor, color: AppColors.primaryRedColor,
fontSize: 14.f, // Adjusted to sizer unit fontSize: 14.f, // Adjusted to sizer unit
@ -172,7 +172,7 @@ class LoginScreenState extends State<LoginScreen> {
Padding( Padding(
padding: EdgeInsets.only(bottom: 10.h), padding: EdgeInsets.only(bottom: 10.h),
child: CustomButton( child: CustomButton(
text: LocaleKeys.sendOTPSMS.tr(), text: LocaleKeys.sendOTPSMS.tr(context: context),
onPressed: () async { onPressed: () async {
if (ValidationUtils.isValidatePhone( if (ValidationUtils.isValidatePhone(
phoneNumber: phoneNumberController!.text, phoneNumber: phoneNumberController!.text,
@ -196,14 +196,14 @@ class LoginScreenState extends State<LoginScreen> {
children: [ children: [
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 8.h), padding: EdgeInsets.symmetric(horizontal: 8.h),
child: LocaleKeys.oR.tr().toText16(color: AppColors.textColor), child: LocaleKeys.oR.tr(context: context).toText16(color: AppColors.textColor),
), ),
], ],
), ),
Padding( Padding(
padding: EdgeInsets.only(bottom: 10.h, top: 10.h), padding: EdgeInsets.only(bottom: 10.h, top: 10.h),
child: CustomButton( child: CustomButton(
text: LocaleKeys.sendOTPWHATSAPP.tr(), text: LocaleKeys.sendOTPWHATSAPP.tr(context: context),
onPressed: () async { onPressed: () async {
if (ValidationUtils.isValidatePhone( if (ValidationUtils.isValidatePhone(
phoneNumber: phoneNumberController!.text, phoneNumber: phoneNumberController!.text,

@ -49,7 +49,7 @@ class QuickLoginState extends State<QuickLogin> {
], ],
), ),
Utils.showLottie(context: context, assetPath: AppAnimations.checkmark, width: 120, height: 120, repeat: true), Utils.showLottie(context: context, assetPath: AppAnimations.checkmark, width: 120, height: 120, repeat: true),
LocaleKeys.allSet.tr().toText16(textAlign: TextAlign.center, weight: FontWeight.w500) LocaleKeys.allSet.tr(context: context).toText16(textAlign: TextAlign.center, weight: FontWeight.w500)
// Text( // Text(
// ' TranslationBase.of(context).allSet', // ' TranslationBase.of(context).allSet',
// textAlign: TextAlign.center, // textAlign: TextAlign.center,
@ -67,7 +67,7 @@ class QuickLoginState extends State<QuickLogin> {
children: [ children: [
Image.asset(AppAssets.lockIcon, height: 100), Image.asset(AppAssets.lockIcon, height: 100),
SizedBox(height: 10.h), SizedBox(height: 10.h),
LocaleKeys.enableQuickLogin.tr().toText26(isBold: true), LocaleKeys.enableQuickLogin.tr(context: context).toText26(isBold: true),
// Text( // Text(
// ' TranslationBase.of(context).enableQuickLogin', // ' TranslationBase.of(context).enableQuickLogin',
// style: context.dynamicTextStyle( // style: context.dynamicTextStyle(
@ -77,7 +77,7 @@ class QuickLoginState extends State<QuickLogin> {
// ), // ),
// ), // ),
SizedBox(height: 5.h), SizedBox(height: 5.h),
LocaleKeys.enableQuickLogin.tr().toText16(color: AppColors.quickLoginColor), LocaleKeys.enableQuickLogin.tr(context: context).toText16(color: AppColors.quickLoginColor),
// Description // Description
// Text( // Text(
// 'TranslationBase.of(context).enableMsg', // 'TranslationBase.of(context).enableMsg',
@ -94,7 +94,7 @@ class QuickLoginState extends State<QuickLogin> {
children: [ children: [
Expanded( Expanded(
child: CustomButton( child: CustomButton(
text: LocaleKeys.enableQuickLogin.tr(), text: LocaleKeys.enableQuickLogin.tr(context: context),
onPressed: () { onPressed: () {
widget.onPressed(); widget.onPressed();
}, },
@ -114,7 +114,7 @@ class QuickLoginState extends State<QuickLogin> {
children: [ children: [
Expanded( Expanded(
child: CustomButton( child: CustomButton(
text: LocaleKeys.notNow.tr(), text: LocaleKeys.notNow.tr(context: context),
onPressed: () { onPressed: () {
cacheService.saveBool(key: CacheConst.quickLoginEnabled, value: false); cacheService.saveBool(key: CacheConst.quickLoginEnabled, value: false);
Navigator.pop(context, "true"); Navigator.pop(context, "true");

@ -80,7 +80,7 @@ class _RegisterNew extends State<RegisterNew> {
children: [ children: [
Utils.showLottie(context: context, assetPath: 'assets/animations/lottie/register.json', width: 200.w, height: 200.h, fit: BoxFit.cover, repeat: true), Utils.showLottie(context: context, assetPath: 'assets/animations/lottie/register.json', width: 200.w, height: 200.h, fit: BoxFit.cover, repeat: true),
SizedBox(height: 16.h), SizedBox(height: 16.h),
LocaleKeys.prepareToElevate.tr().toText32(isBold: true), LocaleKeys.prepareToElevate.tr(context: context).toText32(isBold: true),
SizedBox(height: 24.h), SizedBox(height: 24.h),
Directionality( Directionality(
textDirection: Directionality.of(context), textDirection: Directionality.of(context),
@ -96,7 +96,7 @@ class _RegisterNew extends State<RegisterNew> {
).withVerticalPadding(8.h), ).withVerticalPadding(8.h),
Divider(height: 1.h), Divider(height: 1.h),
TextInputWidget( TextInputWidget(
labelText: LocaleKeys.nationalIdNumber.tr(), labelText: LocaleKeys.nationalIdNumber.tr(context: context),
hintText: "xxxxxxxxx", hintText: "xxxxxxxxx",
controller: authVm.nationalIdController, controller: authVm.nationalIdController,
focusNode: _nationalIdFocusNode, focusNode: _nationalIdFocusNode,
@ -111,7 +111,7 @@ class _RegisterNew extends State<RegisterNew> {
).withVerticalPadding(8), ).withVerticalPadding(8),
Divider(height: 1), Divider(height: 1),
TextInputWidget( TextInputWidget(
labelText: LocaleKeys.dob.tr(), labelText: LocaleKeys.dob.tr(context: context),
hintText: "11 July, 1994", hintText: "11 July, 1994",
controller: authVm.dobController, controller: authVm.dobController,
focusNode: _dobFocusNode, focusNode: _dobFocusNode,
@ -156,7 +156,7 @@ class _RegisterNew extends State<RegisterNew> {
Row( Row(
children: [ children: [
Text( Text(
LocaleKeys.iAcceptThe.tr(), LocaleKeys.iAcceptThe.tr(context: context),
style: context.dynamicTextStyle(fontSize: 14.f, fontWeight: FontWeight.w500, color: Color(0xFF2E3039)), style: context.dynamicTextStyle(fontSize: 14.f, fontWeight: FontWeight.w500, color: Color(0xFF2E3039)),
), ),
GestureDetector( GestureDetector(
@ -165,7 +165,7 @@ class _RegisterNew extends State<RegisterNew> {
Navigator.of(context).pushNamed('/terms'); Navigator.of(context).pushNamed('/terms');
}, },
child: Text( child: Text(
LocaleKeys.termsConditoins.tr(), LocaleKeys.termsConditoins.tr(context: context),
style: context.dynamicTextStyle( style: context.dynamicTextStyle(
fontSize: 14.f, fontSize: 14.f,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
@ -179,7 +179,7 @@ class _RegisterNew extends State<RegisterNew> {
), ),
// Expanded( // Expanded(
// child: Text( // child: Text(
// LocaleKeys.iAcceptTermsConditions.tr().split("the").first, // LocaleKeys.iAcceptTermsConditions.tr(context: context).split("the").first,
// style: context.dynamicTextStyle(fontSize: 14.fSize, fontWeight: FontWeight.w500, color: Color(0xFF2E3039)), // style: context.dynamicTextStyle(fontSize: 14.fSize, fontWeight: FontWeight.w500, color: Color(0xFF2E3039)),
// ), // ),
// ), // ),
@ -188,7 +188,7 @@ class _RegisterNew extends State<RegisterNew> {
), ),
SizedBox(height: 25.h), SizedBox(height: 25.h),
CustomButton( CustomButton(
text: LocaleKeys.registernow.tr(), text: LocaleKeys.registernow.tr(context: context),
icon: AppAssets.note_edit, icon: AppAssets.note_edit,
onPressed: () { onPressed: () {
// Dismiss keyboard before proceeding // Dismiss keyboard before proceeding
@ -220,10 +220,10 @@ class _RegisterNew extends State<RegisterNew> {
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
children: <TextSpan>[ children: <TextSpan>[
TextSpan(text: LocaleKeys.alreadyHaveAccount.tr(), style: context.dynamicTextStyle()), TextSpan(text: LocaleKeys.alreadyHaveAccount.tr(context: context), style: context.dynamicTextStyle()),
TextSpan(text: " "), TextSpan(text: " "),
TextSpan( TextSpan(
text: LocaleKeys.loginNow.tr(), text: LocaleKeys.loginNow.tr(context: context),
style: context.dynamicTextStyle( style: context.dynamicTextStyle(
color: AppColors.primaryRedColor, color: AppColors.primaryRedColor,
fontSize: 16.f, fontSize: 16.f,
@ -271,7 +271,7 @@ class _RegisterNew extends State<RegisterNew> {
Padding( Padding(
padding: const EdgeInsets.only(bottom: 10), padding: const EdgeInsets.only(bottom: 10),
child: CustomButton( child: CustomButton(
text: LocaleKeys.sendOTPSMS.tr(), text: LocaleKeys.sendOTPSMS.tr(context: context),
onPressed: () async { onPressed: () async {
// Dismiss keyboard before validation // Dismiss keyboard before validation
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
@ -298,14 +298,14 @@ class _RegisterNew extends State<RegisterNew> {
children: [ children: [
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 8.h), padding: EdgeInsets.symmetric(horizontal: 8.h),
child: LocaleKeys.oR.tr().toText16(color: AppColors.textColor), child: LocaleKeys.oR.tr(context: context).toText16(color: AppColors.textColor),
), ),
], ],
), ),
Padding( Padding(
padding: EdgeInsets.only(bottom: 10.h, top: 10.h), padding: EdgeInsets.only(bottom: 10.h, top: 10.h),
child: CustomButton( child: CustomButton(
text: LocaleKeys.sendOTPWHATSAPP.tr(), text: LocaleKeys.sendOTPWHATSAPP.tr(context: context),
onPressed: () async { onPressed: () async {
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
if (ValidationUtils.isValidatePhone( if (ValidationUtils.isValidatePhone(

@ -73,7 +73,7 @@ class _RegisterNew extends State<RegisterNewStep2> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
LocaleKeys.personalDetailsVerification.tr().toText26(color: AppColors.textColor, weight: FontWeight.w600, letterSpacing: -2), LocaleKeys.personalDetailsVerification.tr(context: context).toText26(color: AppColors.textColor, weight: FontWeight.w600, letterSpacing: -2),
SizedBox(height: 24.h), SizedBox(height: 24.h),
Container( Container(
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(24)), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(24)),
@ -81,8 +81,8 @@ class _RegisterNew extends State<RegisterNewStep2> {
child: Column( child: Column(
children: [ children: [
TextInputWidget( TextInputWidget(
labelText: authVM!.isUserFromUAE() ? LocaleKeys.fullName.tr() : LocaleKeys.name.tr(), labelText: authVM!.isUserFromUAE() ? LocaleKeys.fullName.tr(context: context) : LocaleKeys.name.tr(context: context),
hintText: authVM!.isUserFromUAE() ? LocaleKeys.enterNameHere.tr() : (name), hintText: authVM!.isUserFromUAE() ? LocaleKeys.enterNameHere.tr(context: context) : (name),
controller: authVM!.isUserFromUAE() ? authVM!.nameController : null, controller: authVM!.isUserFromUAE() ? authVM!.nameController : null,
isEnable: true, isEnable: true,
prefix: null, prefix: null,
@ -100,7 +100,7 @@ class _RegisterNew extends State<RegisterNewStep2> {
).paddingSymmetrical(0.h, 16.h), ).paddingSymmetrical(0.h, 16.h),
Divider(height: 1.h, color: AppColors.greyColor), Divider(height: 1.h, color: AppColors.greyColor),
TextInputWidget( TextInputWidget(
labelText: LocaleKeys.nationalIdNumber.tr(), labelText: LocaleKeys.nationalIdNumber.tr(context: context),
hintText: authVM!.isUserFromUAE() ? appState.getUserRegistrationPayload.patientIdentificationId.toString() : (appState.getNHICUserData.idNumber ?? ""), hintText: authVM!.isUserFromUAE() ? appState.getUserRegistrationPayload.patientIdentificationId.toString() : (appState.getNHICUserData.idNumber ?? ""),
controller: null, controller: null,
isEnable: true, isEnable: true,
@ -120,8 +120,8 @@ class _RegisterNew extends State<RegisterNewStep2> {
builder: (context, genderType, child) { builder: (context, genderType, child) {
final authVM = context.read<AuthenticationViewModel>(); final authVM = context.read<AuthenticationViewModel>();
return DropdownWidget( return DropdownWidget(
labelText: LocaleKeys.gender.tr(), labelText: LocaleKeys.gender.tr(context: context),
hintText: LocaleKeys.malE.tr(), hintText: LocaleKeys.malE.tr(context: context),
isEnable: true, isEnable: true,
dropdownItems: GenderTypeEnum.values.map((e) => appState.isArabic() ? e.typeAr : e.type).toList(), dropdownItems: GenderTypeEnum.values.map((e) => appState.isArabic() ? e.typeAr : e.type).toList(),
selectedValue: genderType != null ? (appState.isArabic() ? genderType.typeAr : genderType.type) : "", selectedValue: genderType != null ? (appState.isArabic() ? genderType.typeAr : genderType.type) : "",
@ -136,7 +136,7 @@ class _RegisterNew extends State<RegisterNewStep2> {
).withVerticalPadding(8); ).withVerticalPadding(8);
}) })
: TextInputWidget( : TextInputWidget(
labelText: LocaleKeys.gender.tr(), labelText: LocaleKeys.gender.tr(context: context),
hintText: (appState.getNHICUserData.gender ?? ""), hintText: (appState.getNHICUserData.gender ?? ""),
controller: null, controller: null,
isEnable: true, isEnable: true,
@ -157,8 +157,8 @@ class _RegisterNew extends State<RegisterNewStep2> {
builder: (context, maritalStatus, child) { builder: (context, maritalStatus, child) {
final authVM = context.read<AuthenticationViewModel>(); // For onChange final authVM = context.read<AuthenticationViewModel>(); // For onChange
return DropdownWidget( return DropdownWidget(
labelText: LocaleKeys.maritalStatus.tr(), labelText: LocaleKeys.maritalStatus.tr(context: context),
hintText: LocaleKeys.married.tr(), hintText: LocaleKeys.married.tr(context: context),
isEnable: true, isEnable: true,
dropdownItems: MaritalStatusTypeEnum.values.map((e) => appState.isArabic() ? e.typeAr : e.type).toList(), dropdownItems: MaritalStatusTypeEnum.values.map((e) => appState.isArabic() ? e.typeAr : e.type).toList(),
selectedValue: maritalStatus != null ? (appState.isArabic() ? maritalStatus.typeAr : maritalStatus.type) : "", selectedValue: maritalStatus != null ? (appState.isArabic() ? maritalStatus.typeAr : maritalStatus.type) : "",
@ -174,7 +174,7 @@ class _RegisterNew extends State<RegisterNewStep2> {
}, },
) )
: TextInputWidget( : TextInputWidget(
labelText: LocaleKeys.maritalStatus.tr(), labelText: LocaleKeys.maritalStatus.tr(context: context),
hintText: appState.isArabic() hintText: appState.isArabic()
? (MaritalStatusTypeExtension.fromValue(appState.getNHICUserData.maritalStatusCode)!.typeAr) ? (MaritalStatusTypeExtension.fromValue(appState.getNHICUserData.maritalStatusCode)!.typeAr)
: (MaritalStatusTypeExtension.fromValue(appState.getNHICUserData.maritalStatusCode)!.type), : (MaritalStatusTypeExtension.fromValue(appState.getNHICUserData.maritalStatusCode)!.type),
@ -203,8 +203,8 @@ class _RegisterNew extends State<RegisterNewStep2> {
builder: (context, data, child) { builder: (context, data, child) {
final authVM = context.read<AuthenticationViewModel>(); final authVM = context.read<AuthenticationViewModel>();
return DropdownWidget( return DropdownWidget(
labelText: LocaleKeys.country.tr(), labelText: LocaleKeys.country.tr(context: context),
hintText: LocaleKeys.uae.tr(), hintText: LocaleKeys.uae.tr(context: context),
isEnable: true, isEnable: true,
dropdownItems: (data.countriesList ?? []).map((e) => data.isArabic ? e.nameN ?? "" : e.name ?? "").toList(), dropdownItems: (data.countriesList ?? []).map((e) => data.isArabic ? e.nameN ?? "" : e.name ?? "").toList(),
selectedValue: data.selectedCountry != null selectedValue: data.selectedCountry != null
@ -224,7 +224,7 @@ class _RegisterNew extends State<RegisterNewStep2> {
}, },
) )
: TextInputWidget( : TextInputWidget(
labelText: LocaleKeys.nationality.tr(), labelText: LocaleKeys.nationality.tr(context: context),
hintText: appState.isArabic() hintText: appState.isArabic()
? (authVM!.countriesList!.firstWhere((e) => e.id == (appState.getNHICUserData.nationalityCode ?? ""), orElse: () => NationalityCountries()).nameN ?? "") ? (authVM!.countriesList!.firstWhere((e) => e.id == (appState.getNHICUserData.nationalityCode ?? ""), orElse: () => NationalityCountries()).nameN ?? "")
: (authVM!.countriesList!.firstWhere((e) => e.id == (appState.getNHICUserData.nationalityCode ?? ""), orElse: () => NationalityCountries()).name ?? ""), : (authVM!.countriesList!.firstWhere((e) => e.id == (appState.getNHICUserData.nationalityCode ?? ""), orElse: () => NationalityCountries()).name ?? ""),
@ -243,7 +243,7 @@ class _RegisterNew extends State<RegisterNewStep2> {
color: AppColors.greyColor, color: AppColors.greyColor,
), ),
TextInputWidget( TextInputWidget(
labelText: LocaleKeys.mobileNumber.tr(), labelText: LocaleKeys.mobileNumber.tr(context: context),
hintText: (appState.getUserRegistrationPayload.patientMobileNumber.toString() ?? ""), hintText: (appState.getUserRegistrationPayload.patientMobileNumber.toString() ?? ""),
controller: null, controller: null,
isEnable: false, isEnable: false,
@ -260,7 +260,7 @@ class _RegisterNew extends State<RegisterNewStep2> {
color: AppColors.greyColor, color: AppColors.greyColor,
), ),
TextInputWidget( TextInputWidget(
labelText: LocaleKeys.dob.tr(), labelText: LocaleKeys.dob.tr(context: context),
hintText: authVM!.isUserFromUAE() ? appState.getUserRegistrationPayload.dob! : appState.getNHICUserData.dateOfBirth ?? "", hintText: authVM!.isUserFromUAE() ? appState.getUserRegistrationPayload.dob! : appState.getNHICUserData.dateOfBirth ?? "",
controller: authVM!.isUserFromUAE() ? authVM!.dobController : null, controller: authVM!.isUserFromUAE() ? authVM!.dobController : null,
isEnable: false, isEnable: false,
@ -280,7 +280,7 @@ class _RegisterNew extends State<RegisterNewStep2> {
children: [ children: [
Expanded( Expanded(
child: CustomButton( child: CustomButton(
text: LocaleKeys.cancel.tr(), text: LocaleKeys.cancel.tr(context: context),
icon: AppAssets.cancel, icon: AppAssets.cancel,
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
@ -298,7 +298,7 @@ class _RegisterNew extends State<RegisterNewStep2> {
backgroundColor: AppColors.primaryRedColor, backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedColor,
textColor: AppColors.whiteColor, textColor: AppColors.whiteColor,
text: LocaleKeys.confirm.tr(), text: LocaleKeys.confirm.tr(context: context),
icon: AppAssets.confirm, icon: AppAssets.confirm,
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,
onPressed: () { onPressed: () {
@ -345,7 +345,7 @@ class _RegisterNew extends State<RegisterNewStep2> {
Padding( Padding(
padding: const EdgeInsets.only(bottom: 10), padding: const EdgeInsets.only(bottom: 10),
child: CustomButton( child: CustomButton(
text: LocaleKeys.submit.tr(), text: LocaleKeys.submit.tr(context: context),
onPressed: () { onPressed: () {
if (ValidationUtils.isValidateEmail( if (ValidationUtils.isValidateEmail(
email: authVM!.emailController.text, email: authVM!.emailController.text,

@ -89,8 +89,8 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1),
initialIndex: bookAppointmentsVM.selectedTabIndex, initialIndex: bookAppointmentsVM.selectedTabIndex,
tabs: [ tabs: [
CustomTabBarModel(null, LocaleKeys.general.tr()), CustomTabBarModel(null, LocaleKeys.general.tr(context: context)),
CustomTabBarModel(null, LocaleKeys.liveCare.tr()), CustomTabBarModel(null, LocaleKeys.liveCare.tr(context: context)),
], ],
onTabChange: (index) { onTabChange: (index) {
bookAppointmentsVM.onTabChanged(index); bookAppointmentsVM.onTabChanged(index);
@ -121,7 +121,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (appState.isAuthenticated) ...[], if (appState.isAuthenticated) ...[],
LocaleKeys.recentVisits.tr().toText18(isBold: true).paddingSymmetrical(24.w, 0.h), LocaleKeys.recentVisits.tr(context: context).toText18(isBold: true).paddingSymmetrical(24.w, 0.h),
SizedBox(height: 16.h), SizedBox(height: 16.h),
SizedBox( SizedBox(
height: 110.h, height: 110.h,
@ -232,8 +232,8 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.searchByClinic.tr().toText14(color: AppColors.textColor, weight: FontWeight.w500), LocaleKeys.searchByClinic.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500),
LocaleKeys.tapToSelectClinic.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), LocaleKeys.tapToSelectClinic.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
], ],
), ),
], ],
@ -264,8 +264,8 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.searchByDoctor.tr().toText14(color: AppColors.textColor, weight: FontWeight.w500), LocaleKeys.searchByDoctor.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500),
LocaleKeys.tapToSelect.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), LocaleKeys.tapToSelect.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
], ],
), ),
], ],
@ -294,8 +294,8 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.searchByRegion.tr().toText14(color: AppColors.textColor, weight: FontWeight.w500), LocaleKeys.searchByRegion.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500),
LocaleKeys.centralRegion.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), LocaleKeys.centralRegion.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
], ],
), ),
], ],
@ -340,8 +340,8 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.immediateConsultation.tr().toText14(color: AppColors.textColor, weight: FontWeight.w500), LocaleKeys.immediateConsultation.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500),
LocaleKeys.tapToSelectClinic.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), LocaleKeys.tapToSelectClinic.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
], ],
), ),
], ],
@ -382,8 +382,8 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.scheduledConsultation.tr().toText14(color: AppColors.textColor, weight: FontWeight.w500), LocaleKeys.scheduledConsultation.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500),
LocaleKeys.tapToSelectClinic.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), LocaleKeys.tapToSelectClinic.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
], ],
), ),
], ],
@ -412,7 +412,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.pharmaLiveCare.tr().toText14(color: AppColors.textColor, weight: FontWeight.w500), LocaleKeys.pharmaLiveCare.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500),
"".toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), "".toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
], ],
), ),
@ -447,9 +447,9 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.notSureHelpMeChooseClinic.tr().toText16(weight: FontWeight.w600, color: AppColors.textColor), LocaleKeys.notSureHelpMeChooseClinic.tr(context: context).toText16(weight: FontWeight.w600, color: AppColors.textColor),
SizedBox(height: 8.h), SizedBox(height: 8.h),
LocaleKeys.mentionYourSymptomsAndFindDoctors.tr().toText12( LocaleKeys.mentionYourSymptomsAndFindDoctors.tr(context: context).toText12(
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: AppColors.greyTextColor, color: AppColors.greyTextColor,
), ),
@ -531,7 +531,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
getTitle(AppointmentViaRegionViewmodel data) { getTitle(AppointmentViaRegionViewmodel data) {
if (data.selectedRegionId == null) { if (data.selectedRegionId == null) {
return LocaleKeys.selectRegion.tr().toText20(weight: FontWeight.w600); return LocaleKeys.selectRegion.tr(context: context).toText20(weight: FontWeight.w600);
} else { } else {
return Transform.flip( return Transform.flip(
flipX: data.isArabic ? true : false, flipX: data.isArabic ? true : false,
@ -558,8 +558,8 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.immediateService.tr().toText18(color: AppColors.textColor, isBold: true), LocaleKeys.immediateService.tr(context: context).toText18(color: AppColors.textColor, isBold: true),
LocaleKeys.noNeedToWaitGetMedicalConsultation.tr().toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), LocaleKeys.noNeedToWaitGetMedicalConsultation.tr(context: context).toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
], ],
), ),
), ),
@ -574,7 +574,7 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.noVisitRequired.tr().toText18(color: AppColors.textColor, isBold: true), LocaleKeys.noVisitRequired.tr(context: context).toText18(color: AppColors.textColor, isBold: true),
LocaleKeys.livecarePoint5.tr(context: context).toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), LocaleKeys.livecarePoint5.tr(context: context).toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
], ],
), ),
@ -590,8 +590,8 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.doctorWillContact.tr().toText18(color: AppColors.textColor, isBold: true), LocaleKeys.doctorWillContact.tr(context: context).toText18(color: AppColors.textColor, isBold: true),
LocaleKeys.specialisedDoctorWillContactYou.tr().toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), LocaleKeys.specialisedDoctorWillContactYou.tr(context: context).toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
], ],
), ),
), ),
@ -606,8 +606,8 @@ class _BookAppointmentPageState extends State<BookAppointmentPage> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.freeMedicineDelivery.tr().toText18(color: AppColors.textColor, isBold: true), LocaleKeys.freeMedicineDelivery.tr(context: context).toText18(color: AppColors.textColor, isBold: true),
LocaleKeys.offersFreeMedicineDelivery.tr().toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), LocaleKeys.offersFreeMedicineDelivery.tr(context: context).toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
], ],
), ),
), ),

@ -79,7 +79,7 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, customBorder: BorderRadius.only(topLeft: Radius.circular(24.r), topRight: Radius.circular(24.r))), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, customBorder: BorderRadius.only(topLeft: Radius.circular(24.r), topRight: Radius.circular(24.r))),
padding: EdgeInsets.symmetric(vertical: 20.h, horizontal: 20.h), padding: EdgeInsets.symmetric(vertical: 20.h, horizontal: 20.h),
child: CustomButton( child: CustomButton(
text: LocaleKeys.bookAppo.tr(), text: LocaleKeys.bookAppo.tr(context: context),
onPressed: () { onPressed: () {
if (widget.calculatedResult["clinicId"] == null) { if (widget.calculatedResult["clinicId"] == null) {
bookAppointmentsViewModel.setIsDoctorsListLoading(true); bookAppointmentsViewModel.setIsDoctorsListLoading(true);
@ -1097,7 +1097,7 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
getTitle(AppointmentViaRegionViewmodel data) { getTitle(AppointmentViaRegionViewmodel data) {
if (data.selectedRegionId == null) { if (data.selectedRegionId == null) {
return LocaleKeys.selectRegion.tr().toText20(weight: FontWeight.w600); return LocaleKeys.selectRegion.tr(context: context).toText20(weight: FontWeight.w600);
} else { } else {
return Transform.flip( return Transform.flip(
flipX: data.isArabic ? true : false, flipX: data.isArabic ? true : false,
@ -1185,7 +1185,7 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
children: [ children: [
Expanded( Expanded(
child: CustomButton( child: CustomButton(
text: LocaleKeys.cancel.tr(), text: LocaleKeys.cancel.tr(context: context),
onPressed: () { onPressed: () {
bookAppointmentsViewModel.setIsContinueDentalPlan(false); bookAppointmentsViewModel.setIsContinueDentalPlan(false);
bookAppointmentsViewModel.setIsChiefComplaintsListLoading(true); bookAppointmentsViewModel.setIsChiefComplaintsListLoading(true);
@ -1206,7 +1206,7 @@ class _SelectClinicPageState extends State<SelectClinicPage> {
SizedBox(width: 8.h), SizedBox(width: 8.h),
Expanded( Expanded(
child: CustomButton( child: CustomButton(
text: LocaleKeys.confirm.tr(), text: LocaleKeys.confirm.tr(context: context),
onPressed: () async { onPressed: () async {
bookAppointmentsViewModel.setIsContinueDentalPlan(true); bookAppointmentsViewModel.setIsContinueDentalPlan(true);
Navigator.of(context).pop(); Navigator.of(context).pop();

@ -178,7 +178,7 @@ class _SelectDoctorPageState extends State<SelectDoctorPage> {
children: [ children: [
LocaleKeys.nearestAppo.tr(context: context).toText13(isBold: true), LocaleKeys.nearestAppo.tr(context: context).toText13(isBold: true),
SizedBox(height: 4.h), SizedBox(height: 4.h),
LocaleKeys.viewNearestAppos.toText11(color: AppColors.textColorLight, weight: FontWeight.w500), LocaleKeys.viewNearestAppos.tr(context: context).toText11(color: AppColors.textColorLight, weight: FontWeight.w500),
], ],
), ),
const Spacer(), const Spacer(),

@ -204,13 +204,13 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
children: [ children: [
Lottie.asset(AppAnimations.errorAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), Lottie.asset(AppAnimations.errorAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill),
SizedBox(height: 8.h), SizedBox(height: 8.h),
(LocaleKeys.loginToUseService.tr()).toText16(color: AppColors.blackColor), (LocaleKeys.loginToUseService.tr(context: context)).toText16(color: AppColors.blackColor),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: CustomButton( child: CustomButton(
text: LocaleKeys.cancel.tr(), text: LocaleKeys.cancel.tr(context: context),
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
@ -224,7 +224,7 @@ class _AppointmentCalendarState extends State<AppointmentCalendar> {
SizedBox(width: 8.h), SizedBox(width: 8.h),
Expanded( Expanded(
child: CustomButton( child: CustomButton(
text: LocaleKeys.confirm.tr(), text: LocaleKeys.confirm.tr(context: context),
onPressed: () async { onPressed: () async {
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.pushAndRemoveUntil( Navigator.pushAndRemoveUntil(

@ -1,4 +1,6 @@
import 'package:easy_localization/easy_localization.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/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/home/data/service_card_data.dart'; import 'package:hmg_patient_app_new/presentation/home/data/service_card_data.dart';
import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/theme/colors.dart';
@ -7,8 +9,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "emergency", serviceName: "emergency",
icon: AppAssets.emergency_services_icon, icon: AppAssets.emergency_services_icon,
title: "Emergency", title: LocaleKeys.emergency,
subtitle: "Services", subtitle: LocaleKeys.services2,
backgroundColor: AppColors.primaryRedColor, backgroundColor: AppColors.primaryRedColor,
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,
textColor: AppColors.whiteColor, textColor: AppColors.whiteColor,
@ -17,8 +19,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "indoor_navigation", serviceName: "indoor_navigation",
icon: AppAssets.indoor_nav_icon, icon: AppAssets.indoor_nav_icon,
title: "Indoor", title: LocaleKeys.indoor,
subtitle: "Navigation", subtitle: LocaleKeys.navigation,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -27,8 +29,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "search_doctor", serviceName: "search_doctor",
icon: AppAssets.search_doctor_icon, icon: AppAssets.search_doctor_icon,
title: "Search", title: LocaleKeys.search,
subtitle: "Doctor", subtitle: LocaleKeys.doctor,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -37,8 +39,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "health_calculators_and_converts", serviceName: "health_calculators_and_converts",
icon: AppAssets.health_calculators_icon, icon: AppAssets.health_calculators_icon,
title: "Health", title: LocaleKeys.health,
subtitle: "Calculators", subtitle: LocaleKeys.calculators,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -47,8 +49,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "health_converters", serviceName: "health_converters",
icon: AppAssets.health_converters_icon, icon: AppAssets.health_converters_icon,
title: "Health", title: LocaleKeys.health,
subtitle: "Converters", subtitle: LocaleKeys.converters,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -57,8 +59,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "parking_guide", serviceName: "parking_guide",
icon: AppAssets.car_parking_icon, icon: AppAssets.car_parking_icon,
title: "Parking", title: LocaleKeys.parking,
subtitle: "Guide", subtitle: LocaleKeys.guide,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -70,8 +72,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "emergency", serviceName: "emergency",
icon: AppAssets.emergency_services_icon, icon: AppAssets.emergency_services_icon,
title: "Emergency", title: LocaleKeys.emergency,
subtitle: "Services", subtitle: LocaleKeys.services2,
backgroundColor: AppColors.primaryRedColor, backgroundColor: AppColors.primaryRedColor,
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,
textColor: AppColors.whiteColor, textColor: AppColors.whiteColor,
@ -80,8 +82,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "lab_results", serviceName: "lab_results",
icon: AppAssets.home_lab_result_icon, icon: AppAssets.home_lab_result_icon,
title: "Lab", title: LocaleKeys.lab,
subtitle: "Results", subtitle: LocaleKeys.labSubtitle,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -90,8 +92,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "radiology_results", serviceName: "radiology_results",
icon: AppAssets.my_radiology_icon, icon: AppAssets.my_radiology_icon,
title: "Radiology", title: LocaleKeys.radiology,
subtitle: "Results", subtitle: LocaleKeys.radiologySubtitle,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -100,8 +102,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "prescriptions", serviceName: "prescriptions",
icon: AppAssets.my_prescription_icon, icon: AppAssets.my_prescription_icon,
title: "Prescriptions", title: LocaleKeys.medicinesSubtitle,
subtitle: "Details", subtitle: LocaleKeys.details,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -110,8 +112,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "insurance_update", serviceName: "insurance_update",
icon: AppAssets.insurance_update_icon, icon: AppAssets.insurance_update_icon,
title: "Insurance", title: LocaleKeys.insurance,
subtitle: "Details", subtitle: LocaleKeys.details,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -130,8 +132,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "sick_leaves", serviceName: "sick_leaves",
icon: AppAssets.my_sick_leave_icon, icon: AppAssets.my_sick_leave_icon,
title: "Sick", title: LocaleKeys.sick,
subtitle: "Leaves", subtitle: LocaleKeys.sickSubtitle,
backgroundColor: AppColors.whiteColor, backgroundColor: AppColors.whiteColor,
iconColor: AppColors.blackColor, iconColor: AppColors.blackColor,
textColor: AppColors.blackColor, textColor: AppColors.blackColor,
@ -143,8 +145,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "livecare", serviceName: "livecare",
icon: AppAssets.small_livecare_icon, icon: AppAssets.small_livecare_icon,
title: "LiveCare", title: LocaleKeys.liveCare,
subtitle: "Explore our app, View our services and offers", subtitle: LocaleKeys.liveCareServiceDesc,
largeCardIcon: AppAssets.liveCareService, largeCardIcon: AppAssets.liveCareService,
backgroundColor: AppColors.successColor, backgroundColor: AppColors.successColor,
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,
@ -161,8 +163,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "home_health_care", serviceName: "home_health_care",
icon: AppAssets.homeBottom, icon: AppAssets.homeBottom,
title: "Home Health Care", title: LocaleKeys.homeHealthCare,
subtitle: "Explore our app, View our services and offers", subtitle: LocaleKeys.liveCareServiceDesc,
largeCardIcon: AppAssets.homeHealthCareService, largeCardIcon: AppAssets.homeHealthCareService,
backgroundColor: AppColors.primaryRedColor, backgroundColor: AppColors.primaryRedColor,
iconColor: AppColors.whiteColor, iconColor: AppColors.whiteColor,
@ -171,8 +173,8 @@ class LandingPageData {
ServiceCardData( ServiceCardData(
serviceName: "pharmacy", serviceName: "pharmacy",
icon: AppAssets.pharmacy_icon, //359846 icon: AppAssets.pharmacy_icon, //359846
title: "Pharmacy", title: LocaleKeys.hmgPharmacy,
subtitle: "Explore our app, View our services and offers", subtitle: LocaleKeys.liveCareServiceDesc,
largeCardIcon: AppAssets.pharmacyService, largeCardIcon: AppAssets.pharmacyService,
backgroundColor: AppColors.pharmacyBGColor, backgroundColor: AppColors.pharmacyBGColor,
iconColor: null, iconColor: null,

@ -195,10 +195,11 @@ class _LandingPageState extends State<LandingPage> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
spacing: 12.h, spacing: 12.h,
children: [ children: [
Stack(children: [ appState.isAuthenticated
Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 18.h, width: 18.h).onPress(() async { ? Stack(children: [
if (appState.isAuthenticated) { Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 18.h, width: 18.h).onPress(() async {
notificationsViewModel.setNotificationStatusID(2); if (appState.isAuthenticated) {
notificationsViewModel.setNotificationStatusID(2);
notificationsViewModel.getAllNotifications(); notificationsViewModel.getAllNotifications();
Navigator.of(context).push( Navigator.of(context).push(
CustomPageRoute( CustomPageRoute(
@ -233,7 +234,8 @@ class _LandingPageState extends State<LandingPage> {
), ),
) )
: SizedBox.shrink(), : SizedBox.shrink(),
]), ])
: SizedBox.shrink(),
Utils.buildSvgWithAssets(icon: AppAssets.indoor_nav_icon, height: 18.h, width: 18.h).onPress(() { Utils.buildSvgWithAssets(icon: AppAssets.indoor_nav_icon, height: 18.h, width: 18.h).onPress(() {
openIndoorNavigationBottomSheet(context); openIndoorNavigationBottomSheet(context);
}), }),
@ -246,6 +248,11 @@ class _LandingPageState extends State<LandingPage> {
isFullScreen: false, isFullScreen: false,
); );
}), }),
!appState.isAuthenticated
? Utils.buildSvgWithAssets(icon: appState.isArabic() ? AppAssets.enLangIcon : AppAssets.arLangIcon, height: 18.h, width: 18.h).onPress(() {
context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA'));
})
: SizedBox.shrink()
], ],
); );
}), }),
@ -302,7 +309,7 @@ class _LandingPageState extends State<LandingPage> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
"Appointments & Visits".toText16(isBold: true), LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(isBold: true),
Row( Row(
children: [ children: [
LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor), LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor),
@ -463,7 +470,7 @@ class _LandingPageState extends State<LandingPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
AppCustomChipWidget( AppCustomChipWidget(
labelText: "ER Online Check-In Request", labelText: LocaleKeys.erOnlineCheckInRequest.tr(context: context),
backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.10), backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.10),
textColor: AppColors.primaryRedColor, textColor: AppColors.primaryRedColor,
), ),
@ -599,10 +606,10 @@ class _LandingPageState extends State<LandingPage> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
"Services".toText16(isBold: true), LocaleKeys.services2.tr(context: context).toText16(isBold: true),
Row( Row(
children: [ children: [
"View all services".toText12(color: AppColors.primaryRedColor), LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor),
SizedBox(width: 2.h), SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
], ],
@ -855,7 +862,7 @@ class _LandingPageState extends State<LandingPage> {
hasShadow: true, hasShadow: true,
), ),
child: AppointmentCard( child: AppointmentCard(
patientAppointmentHistoryResponseModel: myAppointmentsViewModel.patientUpcomingAppointmentsHistoryList.first, patientAppointmentHistoryResponseModel: myAppointmentsViewModel.patientAppointmentsHistoryList.first,
myAppointmentsViewModel: myAppointmentsViewModel, myAppointmentsViewModel: myAppointmentsViewModel,
bookAppointmentsViewModel: bookAppointmentsViewModel, bookAppointmentsViewModel: bookAppointmentsViewModel,
isLoading: false, isLoading: false,
@ -901,7 +908,7 @@ class _LandingPageState extends State<LandingPage> {
} }
} else if (index == 2) { } else if (index == 2) {
if ((myAppointmentsViewModel.isPatientHasQueueAppointment || immediateLiveCareViewModel.patientHasPendingLiveCareRequest) && if ((myAppointmentsViewModel.isPatientHasQueueAppointment || immediateLiveCareViewModel.patientHasPendingLiveCareRequest) &&
myAppointmentsViewModel.patientUpcomingAppointmentsHistoryList.isNotEmpty) { todoSectionViewModel.patientAncillaryOrdersList.isNotEmpty) {
return AncillaryOrderCard( return AncillaryOrderCard(
order: todoSectionViewModel.patientAncillaryOrdersList.first, order: todoSectionViewModel.patientAncillaryOrdersList.first,
isLoading: false, isLoading: false,

@ -23,10 +23,10 @@ class HabibWalletCard extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
"My Balance".toText16(isBold: true), LocaleKeys.myBalance.tr(context: context).toText16(isBold: true),
Row( Row(
children: [ children: [
"View all services".toText12(color: AppColors.primaryRedColor), LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor),
SizedBox(width: 2.h), SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
], ],
@ -54,7 +54,7 @@ class HabibWalletCard extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
"Habib Wallet".toText15(isBold: true), LocaleKeys.habibWallet.tr(context: context).toText15(isBold: true),
Container( Container(
height: 40.h, height: 40.h,
width: 40.h, width: 40.h,
@ -94,7 +94,7 @@ class HabibWalletCard extends StatelessWidget {
padding: EdgeInsets.symmetric(horizontal: 50.h), padding: EdgeInsets.symmetric(horizontal: 50.h),
child: Row( child: Row(
children: [ children: [
"View details".toText12(color: AppColors.primaryRedColor), LocaleKeys.viewDetails.tr(context: context).toText12(color: AppColors.primaryRedColor),
SizedBox(width: 2.h), SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
], ],

@ -89,16 +89,15 @@ class LargeServiceCard extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
serviceCardData.title.toText14(isBold: true, color: AppColors.textColor), serviceCardData.title.tr(context: context).toText14(isBold: true, color: AppColors.textColor),
SizedBox(width: 6.h), serviceCardData.subtitle.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight),
serviceCardData.subtitle.toText14(weight: FontWeight.w500, color: AppColors.textColorLight),
], ],
), ),
), ),
], ],
).paddingSymmetrical(16.w, 20.h), ).paddingSymmetrical(12.w, 24.h),
CustomButton( CustomButton(
text: serviceCardData.isBold ? LocaleKeys.visitPharmacyOnline.tr() : LocaleKeys.bookNow.tr(context: context), text: serviceCardData.isBold ? LocaleKeys.visitPharmacyOnline.tr(context: context) : LocaleKeys.bookNow.tr(context: context),
onPressed: () { onPressed: () {
handleOnTap(); handleOnTap();
}, },

@ -65,8 +65,8 @@ class SmallServiceCard extends StatelessWidget {
children: [ children: [
Utils.buildSvgWithAssets(icon: icon, iconColor: iconColor, width: 32.h, height: 32.h), Utils.buildSvgWithAssets(icon: icon, iconColor: iconColor, width: 32.h, height: 32.h),
SizedBox(height: 6.h), SizedBox(height: 6.h),
title.toText11(color: textColor, isBold: isBold, isCenter: true), title.tr(context: context).toText11(color: textColor, isBold: isBold, isCenter: true),
subtitle.toText11(color: textColor, isBold: isBold, isCenter: true), subtitle.tr(context: context).toText11(color: textColor, isBold: isBold, isCenter: true),
], ],
), ),
), ),
@ -173,7 +173,7 @@ class SmallServiceCard extends StatelessWidget {
void openIndoorNavigationBottomSheet(BuildContext context) { void openIndoorNavigationBottomSheet(BuildContext context) {
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
title: LocaleKeys.selectHospital.tr(), title: LocaleKeys.selectHospital.tr(context: context),
context, context,
child: ChangeNotifierProvider( child: ChangeNotifierProvider(
create: (context) => HospitalSelectionBottomSheetViewModel(getIt()), create: (context) => HospitalSelectionBottomSheetViewModel(getIt()),

File diff suppressed because one or more lines are too long

@ -74,7 +74,7 @@ class LabResultDetails extends StatelessWidget {
.getSeverityText( .getSeverityText(
recentLabResult.calculatedResultFlag ?? "", recentLabResult.calculatedResultFlag ?? "",
) )
.tr() .tr(context: context)
.toText10(weight: FontWeight.w500, color: AppColors.greyTextColor), .toText10(weight: FontWeight.w500, color: AppColors.greyTextColor),
Utils.buildSvgWithAssets( Utils.buildSvgWithAssets(
icon: AppAssets.lab_result_indicator, icon: AppAssets.lab_result_indicator,
@ -151,8 +151,8 @@ class LabResultDetails extends StatelessWidget {
children: [ children: [
Text( Text(
labmodel.isGraphVisible labmodel.isGraphVisible
? LocaleKeys.historyFlowchart.tr() ? LocaleKeys.historyFlowchart.tr(context: context)
: LocaleKeys.history.tr(), : LocaleKeys.history.tr(context: context),
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontFamily: 'Poppins', fontFamily: 'Poppins',
@ -181,7 +181,7 @@ class LabResultDetails extends StatelessWidget {
height: 24) height: 24)
.onPress(() { .onPress(() {
showCommonBottomSheetWithoutHeight( showCommonBottomSheetWithoutHeight(
title: LocaleKeys.setTheDateRange.tr(), title: LocaleKeys.setTheDateRange.tr(context: context),
context, context,
child: DateRangeSelector( child: DateRangeSelector(
onRangeSelected: (start, end) { onRangeSelected: (start, end) {

@ -192,7 +192,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
SizedBox(width: 4.h), SizedBox(width: 4.h),
Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, height: 22.h, width: 22.w) Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, height: 22.h, width: 22.w)
], ],
).withHorizontalPadding(24.w).onPress(() { ).onPress(() {
DialogService dialogService = getIt.get<DialogService>(); DialogService dialogService = getIt.get<DialogService>();
dialogService.showFamilyBottomSheetWithoutH( dialogService.showFamilyBottomSheetWithoutH(
label: LocaleKeys.familyTitle.tr(context: context), label: LocaleKeys.familyTitle.tr(context: context),
@ -276,12 +276,12 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
runSpacing: 4.h, runSpacing: 4.h,
children: [ children: [
AppCustomChipWidget( AppCustomChipWidget(
labelText: "${appState.getAuthenticatedUser()!.age} Years Old", labelText: LocaleKeys.ageYearsOld.tr(namedArgs: {'age': '${appState.getAuthenticatedUser()!.age}', 'yearsOld': LocaleKeys.yearsOld.tr(context: context)}, context: context),
labelPadding: EdgeInsetsDirectional.only(start: 8.w, end: 8.w), labelPadding: EdgeInsetsDirectional.only(start: 8.w, end: 8.w),
), ),
AppCustomChipWidget( AppCustomChipWidget(
icon: AppAssets.blood_icon, icon: AppAssets.blood_icon,
labelText: "Blood: ${appState.getUserBloodGroup.isEmpty ? "N/A" : appState.getUserBloodGroup}", labelText: LocaleKeys.bloodGroup.tr(namedArgs: {'bloodType': appState.getUserBloodGroup.isEmpty ? "N/A" : appState.getUserBloodGroup}, context: context),
iconColor: AppColors.primaryRedColor, iconColor: AppColors.primaryRedColor,
labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w),
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
@ -319,7 +319,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
LocaleKeys.vitalSigns.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2), LocaleKeys.vitalSigns.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2),
Row( Row(
children: [ children: [
LocaleKeys.viewAll.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
SizedBox(width: 2.h), SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
], ],
@ -359,7 +359,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
children: [ children: [
Utils.buildSvgWithAssets(icon: AppAssets.call_for_vitals, width: 32.h, height: 32.h), Utils.buildSvgWithAssets(icon: AppAssets.call_for_vitals, width: 32.h, height: 32.h),
SizedBox(height: 12.h), SizedBox(height: 12.h),
LocaleKeys.noVitalSignsRecordedYet.tr().toText12(isCenter: true), LocaleKeys.noVitalSignsRecordedYet.tr(context: context).toText12(isCenter: true),
], ],
), ),
), ),
@ -439,14 +439,14 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
itemPadding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 14.h), itemPadding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 14.h),
items: [ items: [
ExpandableListItem( ExpandableListItem(
title: "Medical Services".toText18(weight: FontWeight.w600), title: LocaleKeys.medicalServices.tr(context: context).toText18(weight: FontWeight.w600),
children: [ children: [
SizedBox(height: 10.h), SizedBox(height: 10.h),
getSelectedTabData(0), getSelectedTabData(0),
], ],
), ),
ExpandableListItem( ExpandableListItem(
title: "Medical Reports".toText18( title: LocaleKeys.medicalReports.tr(context: context).toText18(
weight: FontWeight.w600, weight: FontWeight.w600,
), ),
expandedBackgroundColor: Colors.transparent, expandedBackgroundColor: Colors.transparent,
@ -455,7 +455,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
getSelectedTabData(2), getSelectedTabData(2),
]), ]),
ExpandableListItem( ExpandableListItem(
title: "Insurance & Payments".toText18(weight: FontWeight.w600), title: LocaleKeys.insuranceAndPayments.tr(context: context).toText18(weight: FontWeight.w600),
expandedBackgroundColor: Colors.transparent, expandedBackgroundColor: Colors.transparent,
children: [ children: [
SizedBox(height: 10.h), SizedBox(height: 10.h),
@ -463,7 +463,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
], ],
), ),
ExpandableListItem( ExpandableListItem(
title: "Tracker & Others".toText18(weight: FontWeight.w600), title: LocaleKeys.trackerAndOthers.tr(context: context).toText18(weight: FontWeight.w600),
expandedBackgroundColor: Colors.transparent, expandedBackgroundColor: Colors.transparent,
children: [ children: [
SizedBox(height: 10.h), SizedBox(height: 10.h),
@ -577,10 +577,10 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
LocaleKeys.appointmentsAndVisits.tr().toText16(weight: FontWeight.w500, letterSpacing: -0.2), LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2),
Row( Row(
children: [ children: [
LocaleKeys.viewAll.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
SizedBox(width: 2.h), SizedBox(width: 2.h),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
], ],
@ -645,6 +645,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
shrinkWrap: true, shrinkWrap: true,
itemCount: myAppointmentsVM.patientAppointmentsHistoryList.length, itemCount: myAppointmentsVM.patientAppointmentsHistoryList.length,
padding: EdgeInsets.zero,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return AnimationConfiguration.staggeredList( return AnimationConfiguration.staggeredList(
position: index, position: index,
@ -699,12 +700,12 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
), ),
)); ));
}, },
separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 12.h), separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 12.w),
), ),
).paddingSymmetrical(0.w, 0.h); );
}), }),
SizedBox(height: 10.h), SizedBox(height: 10.h),
LocaleKeys.labAndRadiology.tr().toText16(weight: FontWeight.w500, letterSpacing: -0.2), LocaleKeys.labAndRadiology.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Row( Row(
children: [ children: [
@ -743,7 +744,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
], ],
).paddingSymmetrical(0.w, 0.h), ).paddingSymmetrical(0.w, 0.h),
SizedBox(height: 24.h), SizedBox(height: 24.h),
LocaleKeys.activeMedicationsAndPrescriptions.tr().toText16(weight: FontWeight.w500, letterSpacing: -0.2), LocaleKeys.activeMedicationsAndPrescriptions.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2),
SizedBox(height: 16.h), SizedBox(height: 16.h),
Consumer<PrescriptionsViewModel>(builder: (context, prescriptionVM, child) { Consumer<PrescriptionsViewModel>(builder: (context, prescriptionVM, child) {
return prescriptionVM.isPrescriptionsOrdersLoading return prescriptionVM.isPrescriptionsOrdersLoading
@ -901,7 +902,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
LocaleKeys.myDoctor.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2), LocaleKeys.myDoctor.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2),
Row( Row(
children: [ children: [
LocaleKeys.viewAll.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500),
SizedBox(width: 2.w), SizedBox(width: 2.w),
Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h),
], ],
@ -1351,7 +1352,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
SizedBox(height: 16.h), SizedBox(height: 16.h),
Row( Row(
children: [ children: [
LocaleKeys.others.tr().toText16(weight: FontWeight.w500, color: AppColors.textColor), LocaleKeys.others.tr(context: context).toText16(weight: FontWeight.w500, color: AppColors.textColor),
], ],
), ),
SizedBox(height: 16.h), SizedBox(height: 16.h),
@ -1484,7 +1485,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
Expanded( Expanded(
child: _buildVitalSignCard( child: _buildVitalSignCard(
icon: AppAssets.bmiVital, icon: AppAssets.bmiVital,
label: "BMI", label: LocaleKeys.bmi.tr(context: context),
value: vitalSign.bodyMassIndex?.toString() ?? '--', value: vitalSign.bodyMassIndex?.toString() ?? '--',
unit: '', unit: '',
status: vitalSign.bodyMassIndex != null ? _getBMIStatus(vitalSign.bodyMassIndex) : null, status: vitalSign.bodyMassIndex != null ? _getBMIStatus(vitalSign.bodyMassIndex) : null,
@ -1495,7 +1496,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
Expanded( Expanded(
child: _buildVitalSignCard( child: _buildVitalSignCard(
icon: AppAssets.heightVital, icon: AppAssets.heightVital,
label: "Height", label: LocaleKeys.height.tr(context: context),
value: vitalSign.heightCm?.toString() ?? '--', value: vitalSign.heightCm?.toString() ?? '--',
unit: 'cm', unit: 'cm',
status: null, status: null,
@ -1511,7 +1512,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
Expanded( Expanded(
child: _buildVitalSignCard( child: _buildVitalSignCard(
icon: AppAssets.weightVital, icon: AppAssets.weightVital,
label: "Weight", label: LocaleKeys.weight.tr(context: context),
value: vitalSign.weightKg?.toString() ?? '--', value: vitalSign.weightKg?.toString() ?? '--',
unit: 'kg', unit: 'kg',
status: vitalSign.weightKg != null ? "Normal" : null, status: vitalSign.weightKg != null ? "Normal" : null,
@ -1522,7 +1523,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
Expanded( Expanded(
child: _buildVitalSignCard( child: _buildVitalSignCard(
icon: AppAssets.bloodPressure, icon: AppAssets.bloodPressure,
label: "Blood Pressure", label: LocaleKeys.bloodPressure.tr(context: context),
value: vitalSign.bloodPressureLower != null && vitalSign.bloodPressureHigher != null value: vitalSign.bloodPressureLower != null && vitalSign.bloodPressureHigher != null
? "${vitalSign.bloodPressureHigher}/${vitalSign.bloodPressureLower}" ? "${vitalSign.bloodPressureHigher}/${vitalSign.bloodPressureLower}"
: '--', : '--',

@ -114,8 +114,8 @@ class ProfileSettingsState extends State<ProfileSettings> {
onAddFamilyMemberPress: () { onAddFamilyMemberPress: () {
DialogService dialogService = getIt.get<DialogService>(); DialogService dialogService = getIt.get<DialogService>();
dialogService.showAddFamilyFileSheet( dialogService.showAddFamilyFileSheet(
label: LocaleKeys.addFamilyMember.tr(), label: LocaleKeys.addFamilyMember.tr(context: context),
message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(), message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(context: context),
onVerificationPress: () { onVerificationPress: () {
medicalVm.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); medicalVm.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms);
}); });
@ -197,19 +197,18 @@ class ProfileSettingsState extends State<ProfileSettings> {
1.divider, 1.divider,
actionItem(AppAssets.bell, LocaleKeys.notificationsSettings.tr(context: context), () {}), actionItem(AppAssets.bell, LocaleKeys.notificationsSettings.tr(context: context), () {}),
1.divider, 1.divider,
actionItem(AppAssets.touch_face_id, LocaleKeys.touchIDFaceIDServices.tr(), () {}, switchValue: true), actionItem(AppAssets.touch_face_id, LocaleKeys.touchIDFaceIDServices.tr(context: context), () {}, switchValue: true),
], ],
), ),
), ),
LocaleKeys.personalInformation.tr().toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1) LocaleKeys.personalInformation.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w),
.paddingOnly(left: 24.w, right: 24.w),
Container( Container(
margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h), margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h),
padding: EdgeInsets.only(top: 4.h, bottom: 4.h), padding: EdgeInsets.only(top: 4.h, bottom: 4.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true),
child: Column( child: Column(
children: [ children: [
actionItem(AppAssets.email_transparent, LocaleKeys.updateEmailAddress.tr(), () {}), actionItem(AppAssets.email_transparent, LocaleKeys.updateEmailAddress.tr(context: context), () {}),
// 1.divider, // 1.divider,
// actionItem(AppAssets.smart_phone_fill, "Phone Number".needTranslation, () {}), // actionItem(AppAssets.smart_phone_fill, "Phone Number".needTranslation, () {}),
// 1.divider, // 1.divider,
@ -219,8 +218,7 @@ class ProfileSettingsState extends State<ProfileSettings> {
], ],
), ),
), ),
LocaleKeys.helpAndSupport.tr().toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1) LocaleKeys.helpAndSupport.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w),
.paddingOnly(left: 24.w, right: 24.w),
Container( Container(
margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h), margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h),
padding: EdgeInsets.only(top: 4.h, bottom: 4.h), padding: EdgeInsets.only(top: 4.h, bottom: 4.h),
@ -231,9 +229,9 @@ class ProfileSettingsState extends State<ProfileSettings> {
launchUrl(Uri.parse("tel://" + "+966 11 525 9999")); launchUrl(Uri.parse("tel://" + "+966 11 525 9999"));
}, trailingLabel: "011 525 9999"), }, trailingLabel: "011 525 9999"),
1.divider, 1.divider,
actionItem(AppAssets.permission, LocaleKeys.permissions.tr(), () {}, trailingLabel: "Location, Camera"), actionItem(AppAssets.permission, LocaleKeys.permissions.tr(context: context), () {}, trailingLabel: "Location, Camera"),
1.divider, 1.divider,
actionItem(AppAssets.rate, LocaleKeys.rateApp.tr(), () { actionItem(AppAssets.rate, LocaleKeys.rateApp.tr(context: context), () {
if (Platform.isAndroid) { if (Platform.isAndroid) {
Utils.openWebView( Utils.openWebView(
url: 'https://play.google.com/store/apps/details?id=com.ejada.hmg', url: 'https://play.google.com/store/apps/details?id=com.ejada.hmg',
@ -245,7 +243,7 @@ class ProfileSettingsState extends State<ProfileSettings> {
} }
}, isExternalLink: true), }, isExternalLink: true),
1.divider, 1.divider,
actionItem(AppAssets.privacy_terms, LocaleKeys.privacyPolicy.tr(), () { actionItem(AppAssets.privacy_terms, LocaleKeys.privacyPolicy.tr(context: context), () {
Utils.openWebView( Utils.openWebView(
url: 'https://hmg.com/en/Pages/Privacy.aspx', url: 'https://hmg.com/en/Pages/Privacy.aspx',
); );
@ -262,7 +260,7 @@ class ProfileSettingsState extends State<ProfileSettings> {
CustomButton( CustomButton(
height: 56.h, height: 56.h,
icon: AppAssets.minus, icon: AppAssets.minus,
text: LocaleKeys.deactivateAccount.tr(), text: LocaleKeys.deactivateAccount.tr(context: context),
onPressed: () {}, onPressed: () {},
).paddingAll(24.w), ).paddingAll(24.w),
], ],
@ -346,7 +344,8 @@ class FamilyCardWidget extends StatelessWidget {
), ),
], ],
).expanded, ).expanded,
Icon(Icons.qr_code, size: 56.h) // Icon(Icons.qr_code, size: 56.h)
Image.network("https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=${profile.responseId.toString()}", fit: BoxFit.contain, height: 56.h, width: 56.w)
], ],
), ),
SizedBox(height: 4.h), SizedBox(height: 4.h),
@ -421,7 +420,7 @@ class FamilyCardWidget extends StatelessWidget {
), ),
], ],
).paddingOnly(top: 16.h, right: 16.w, left: 16.w, bottom: 12.h), ).paddingOnly(top: 16.h, right: 16.w, left: 16.w, bottom: 12.h),
1.divider, 1.divider.paddingSymmetrical(16.w, 0.h),
_buildActionButton(appState), _buildActionButton(appState),
], ],
), ),
@ -445,7 +444,7 @@ class FamilyCardWidget extends StatelessWidget {
return CustomButton( return CustomButton(
icon: canSwitch ? AppAssets.switch_user : AppAssets.add_family, icon: canSwitch ? AppAssets.switch_user : AppAssets.add_family,
text: canSwitch ? LocaleKeys.switchFamilyFile.tr() : LocaleKeys.addANewFamilyMember.tr(), text: canSwitch ? LocaleKeys.switchAccount.tr() : LocaleKeys.addANewFamilyMember.tr(),
onPressed: canSwitch ? () => onFamilySwitchPress(profile) : onAddFamilyMemberPress, onPressed: canSwitch ? () => onFamilySwitchPress(profile) : onAddFamilyMemberPress,
backgroundColor: canSwitch ? AppColors.secondaryLightRedColor : AppColors.primaryRedColor, backgroundColor: canSwitch ? AppColors.secondaryLightRedColor : AppColors.primaryRedColor,
borderColor: canSwitch ? AppColors.secondaryLightRedColor : AppColors.primaryRedColor, borderColor: canSwitch ? AppColors.secondaryLightRedColor : AppColors.primaryRedColor,
@ -461,7 +460,7 @@ class FamilyCardWidget extends StatelessWidget {
return CustomButton( return CustomButton(
icon: AppAssets.switch_user, icon: AppAssets.switch_user,
text: canSwitchBack ? LocaleKeys.switchBackFamilyFile.tr() : LocaleKeys.switchLogin.tr(), text: canSwitchBack ? LocaleKeys.switchBackFamilyFile.tr() : LocaleKeys.switchAccount.tr(),
backgroundColor: canSwitchBack ? AppColors.primaryRedColor : Colors.grey.shade200, backgroundColor: canSwitchBack ? AppColors.primaryRedColor : Colors.grey.shade200,
borderColor: canSwitchBack ? AppColors.primaryRedColor : Colors.grey.shade200, borderColor: canSwitchBack ? AppColors.primaryRedColor : Colors.grey.shade200,
textColor: canSwitchBack ? AppColors.whiteColor : AppColors.greyTextColor, textColor: canSwitchBack ? AppColors.whiteColor : AppColors.greyTextColor,

@ -7,7 +7,6 @@ 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';
import 'package:hmg_patient_app_new/extensions/route_extensions.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/widget_extensions.dart'; 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';
@ -44,7 +43,9 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> {
); );
return; return;
} }
LoaderBottomSheet.showLoader(loadingText: LocaleKeys.pleaseWait.tr(context: context),); LoaderBottomSheet.showLoader(
loadingText: LocaleKeys.pleaseWait.tr(context: context),
);
final String userName = 'guest_user'; final String userName = 'guest_user';
final String password = '123456'; final String password = '123456';
@ -102,7 +103,7 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> {
width: 32.h, width: 32.h,
height: 32.h, height: 32.h,
), ),
padding: const EdgeInsets.only(left: 12), padding: EdgeInsetsDirectional.only(start: 12),
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
highlightColor: Colors.transparent, highlightColor: Colors.transparent,
), ),
@ -125,21 +126,32 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> {
} }
Widget _buildBodyViewer(SymptomsCheckerViewModel viewModel) { Widget _buildBodyViewer(SymptomsCheckerViewModel viewModel) {
return Padding( return GestureDetector(
padding: EdgeInsets.fromLTRB(16.h, 16.h, 16.h, 60.h), onHorizontalDragEnd: (details) {
child: AnimatedSwitcher( // Swipe left or right to toggle view
duration: const Duration(milliseconds: 600), if (details.primaryVelocity != null) {
transitionBuilder: (child, animation) => _build3DFlipTransition(child, animation), if (details.primaryVelocity! < -200 || details.primaryVelocity! > 200) {
switchInCurve: Curves.easeInOut, viewModel.toggleView();
switchOutCurve: Curves.easeInOut, }
child: InteractiveBodyWidget( }
key: ValueKey<BodyView>(viewModel.currentView), },
bodyImageAsset: viewModel.currentView == BodyView.front ? AppAssets.fullBodyFront : AppAssets.fullBodyBack, child: Padding(
organs: viewModel.currentOrgans, padding: EdgeInsets.fromLTRB(16.h, 16.h, 16.h, 60.h),
selectedOrganIds: viewModel.selectedOrganIds, child: AnimatedSwitcher(
onOrganTap: viewModel.toggleOrganSelection, duration: const Duration(milliseconds: 600),
isBodyHidden: viewModel.isBodyHidden, transitionBuilder: (child, animation) => _build3DFlipTransition(child, animation),
tooltipOrganId: viewModel.tooltipOrganId, switchInCurve: Curves.easeInOut,
switchOutCurve: Curves.easeInOut,
child: InteractiveBodyWidget(
key: ValueKey<BodyView>(viewModel.currentView),
bodyImageAsset: viewModel.currentView == BodyView.front ? AppAssets.fullBodyFront : AppAssets.fullBodyBack,
organs: viewModel.currentOrgans,
selectedOrganIds: viewModel.selectedOrganIds,
onOrganTap: viewModel.toggleOrganSelection,
isBodyHidden: viewModel.isBodyHidden,
tooltipOrganId: viewModel.tooltipOrganId,
isArabic: _appState.isArabic(),
),
), ),
), ),
); );
@ -169,8 +181,8 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> {
} }
Widget _buildViewToggleButtons(SymptomsCheckerViewModel viewModel) { Widget _buildViewToggleButtons(SymptomsCheckerViewModel viewModel) {
return Positioned( return PositionedDirectional(
left: 16.w, start: 16.w,
top: 36.h, top: 36.h,
child: Column( child: Column(
children: [ children: [
@ -275,6 +287,8 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> {
); );
} }
final isArabic = _appState.isArabic();
return ConstrainedBox( return ConstrainedBox(
constraints: BoxConstraints(maxHeight: 150.h), constraints: BoxConstraints(maxHeight: 150.h),
child: SingleChildScrollView( child: SingleChildScrollView(
@ -284,7 +298,7 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> {
runSpacing: 8.h, runSpacing: 8.h,
children: viewModel.selectedOrgans.map((organ) { children: viewModel.selectedOrgans.map((organ) {
return AppCustomChipWidget( return AppCustomChipWidget(
labelText: organ.description, labelText: organ.getLocalizedDescription(isArabic),
backgroundColor: AppColors.secondaryLightRedColor, backgroundColor: AppColors.secondaryLightRedColor,
textColor: AppColors.primaryRedColor, textColor: AppColors.primaryRedColor,
deleteIcon: AppAssets.cancel, deleteIcon: AppAssets.cancel,
@ -313,8 +327,8 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> {
} }
Widget _buildExpandCollapseButton(SymptomsCheckerViewModel viewModel) { Widget _buildExpandCollapseButton(SymptomsCheckerViewModel viewModel) {
return Positioned( return PositionedDirectional(
right: 24.w, end: 24.w,
top: -24.h, top: -24.h,
child: GestureDetector( child: GestureDetector(
onTap: viewModel.toggleBottomSheet, onTap: viewModel.toggleBottomSheet,
@ -331,13 +345,16 @@ class _OrganSelectorPageState extends State<OrganSelectorPage> {
borderRadius: 11.r, borderRadius: 11.r,
), ),
child: Center( child: Center(
child: AnimatedRotation( child: Transform.flip(
duration: const Duration(milliseconds: 300), flipX: _appState.isArabic(),
turns: viewModel.isBottomSheetExpanded ? 0.25 : -0.25, child: AnimatedRotation(
child: Utils.buildSvgWithAssets( duration: const Duration(milliseconds: 300),
icon: AppAssets.arrowRight, turns: viewModel.isBottomSheetExpanded ? 0.25 : -0.25,
width: 25.w, child: Utils.buildSvgWithAssets(
height: 25.h, icon: AppAssets.arrowRight,
width: 25.w,
height: 25.h,
),
), ),
), ),
), ),

@ -108,25 +108,25 @@ class PossibleConditionsPage extends StatelessWidget {
); );
} }
Widget _buildInfoTile({required PossibleConditionsSeverityEnum severityEnum}) { Widget _buildInfoTile({required PossibleConditionsSeverityEnum severityEnum, required BuildContext context}) {
String title; String title;
String description; String description;
Color dotColor; Color dotColor;
switch (severityEnum) { switch (severityEnum) {
case PossibleConditionsSeverityEnum.monitorOnly: case PossibleConditionsSeverityEnum.monitorOnly:
title = "Monitor".needTranslation; title = LocaleKeys.monitor.tr(context: context);
description = "No need to seek medical advice. Just keep healthy routine.".needTranslation; description = LocaleKeys.monitorDescription.tr(context: context);
dotColor = AppColors.chipColorMonitor; dotColor = AppColors.chipColorMonitor;
break; break;
case PossibleConditionsSeverityEnum.seekMedicalAdvice: case PossibleConditionsSeverityEnum.seekMedicalAdvice:
title = "Seek Medical Advice".needTranslation; title = LocaleKeys.seekMedicalAdvice.tr(context: context);
description = "Not emergency but better to monitor the symptoms.".needTranslation; description = LocaleKeys.seekMedicalAdviceDescription.tr(context: context);
dotColor = AppColors.chipColorSeekMedicalAdvice; dotColor = AppColors.chipColorSeekMedicalAdvice;
break; break;
case PossibleConditionsSeverityEnum.emergency: case PossibleConditionsSeverityEnum.emergency:
title = "Emergency".needTranslation; title = LocaleKeys.emergency.tr(context: context);
description = "Need to consult doctor as soon as possible before getting too late.".needTranslation; description = LocaleKeys.emergencyDescription.tr(context: context);
dotColor = AppColors.chipColorEmergency; dotColor = AppColors.chipColorEmergency;
break; break;
} }
@ -156,7 +156,7 @@ class PossibleConditionsPage extends StatelessWidget {
_buildSeverityDetailsBottomsheet({required BuildContext context}) { _buildSeverityDetailsBottomsheet({required BuildContext context}) {
return showCommonBottomSheetWithoutHeight( return showCommonBottomSheetWithoutHeight(
title: "Color Science".needTranslation, title: LocaleKeys.colorScience.tr(context: context),
context, context,
child: Container( child: Container(
padding: EdgeInsets.all(16.w), padding: EdgeInsets.all(16.w),
@ -164,11 +164,11 @@ class PossibleConditionsPage extends StatelessWidget {
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true),
child: Column( child: Column(
children: [ children: [
_buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.monitorOnly), _buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.monitorOnly, context: context),
Divider(color: AppColors.bottomNAVBorder, height: 24.h, thickness: 1), Divider(color: AppColors.bottomNAVBorder, height: 24.h, thickness: 1),
_buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.seekMedicalAdvice), _buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.seekMedicalAdvice, context: context),
Divider(color: AppColors.bottomNAVBorder, height: 24.h, thickness: 1), Divider(color: AppColors.bottomNAVBorder, height: 24.h, thickness: 1),
_buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.emergency), _buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.emergency, context: context),
], ],
), ),
), ),

@ -3,6 +3,7 @@ import 'package:flutter/gestures.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';
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/dependencies.dart'; import 'package:hmg_patient_app_new/core/dependencies.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/route_extensions.dart';
@ -25,11 +26,13 @@ class RiskFactorsScreen extends StatefulWidget {
class _RiskFactorsScreenState extends State<RiskFactorsScreen> { class _RiskFactorsScreenState extends State<RiskFactorsScreen> {
late DialogService dialogService; late DialogService dialogService;
late AppState _appState;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
dialogService = getIt<DialogService>(); dialogService = getIt<DialogService>();
_appState = getIt<AppState>();
// Fetch risk factors based on selected symptoms // Fetch risk factors based on selected symptoms
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
final viewModel = context.read<SymptomsCheckerViewModel>(); final viewModel = context.read<SymptomsCheckerViewModel>();
@ -90,6 +93,8 @@ class _RiskFactorsScreenState extends State<RiskFactorsScreen> {
} }
Widget _buildRiskFactorsList(SymptomsCheckerViewModel viewModel) { Widget _buildRiskFactorsList(SymptomsCheckerViewModel viewModel) {
final isArabic = _appState.isArabic();
return Container( return Container(
key: ValueKey<int>(viewModel.riskFactorsList.length), key: ValueKey<int>(viewModel.riskFactorsList.length),
width: double.infinity, width: double.infinity,
@ -100,7 +105,7 @@ class _RiskFactorsScreenState extends State<RiskFactorsScreen> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
...viewModel.riskFactorsList.map((factor) { ...viewModel.riskFactorsList.map((factor) {
return _buildRiskFactorItem(viewModel, factor.id ?? '', factor.getDisplayName()); return _buildRiskFactorItem(viewModel, factor.id ?? '', factor.getDisplayName(isArabic: isArabic));
}), }),
SizedBox(height: 12.w), SizedBox(height: 12.w),
Row( Row(

@ -2,6 +2,7 @@ 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';
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/dependencies.dart'; import 'package:hmg_patient_app_new/core/dependencies.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/route_extensions.dart';
@ -24,11 +25,13 @@ class SuggestionsScreen extends StatefulWidget {
class _SuggestionsScreenState extends State<SuggestionsScreen> { class _SuggestionsScreenState extends State<SuggestionsScreen> {
late DialogService dialogService; late DialogService dialogService;
late AppState _appState;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
dialogService = getIt<DialogService>(); dialogService = getIt<DialogService>();
_appState = getIt<AppState>();
// Initialize symptom groups based on selected organs // Initialize symptom groups based on selected organs
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
final viewModel = context.read<SymptomsCheckerViewModel>(); final viewModel = context.read<SymptomsCheckerViewModel>();
@ -92,6 +95,8 @@ class _SuggestionsScreenState extends State<SuggestionsScreen> {
} }
Widget _buildSuggestionsList(SymptomsCheckerViewModel viewModel) { Widget _buildSuggestionsList(SymptomsCheckerViewModel viewModel) {
final isArabic = _appState.isArabic();
return Container( return Container(
key: ValueKey<int>(viewModel.suggestionsList.length), key: ValueKey<int>(viewModel.suggestionsList.length),
width: double.infinity, width: double.infinity,
@ -102,7 +107,7 @@ class _SuggestionsScreenState extends State<SuggestionsScreen> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
...viewModel.suggestionsList.map((factor) { ...viewModel.suggestionsList.map((factor) {
return _buildSuggestionItem(viewModel, factor.id ?? '', factor.getDisplayName()); return _buildSuggestionItem(viewModel, factor.id ?? '', factor.getDisplayName(isArabic: isArabic));
}), }),
SizedBox(height: 12.w), SizedBox(height: 12.w),
Row( Row(
@ -115,7 +120,7 @@ class _SuggestionsScreenState extends State<SuggestionsScreen> {
), ),
SizedBox(width: 12.w), SizedBox(width: 12.w),
Expanded( Expanded(
child: "This is a list of symptoms suggested by our AI, based on the information gathered so far during the interview".toText12( child: LocaleKeys.suggestionAIListDescription.tr(context: context).toText12(
color: AppColors.greyInfoTextColor, color: AppColors.greyInfoTextColor,
), ),
) )

@ -1,6 +1,7 @@
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_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/dependencies.dart'; import 'package:hmg_patient_app_new/core/dependencies.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/route_extensions.dart';
@ -26,11 +27,13 @@ class SymptomsSelectorPage extends StatefulWidget {
class _SymptomsSelectorPageState extends State<SymptomsSelectorPage> { class _SymptomsSelectorPageState extends State<SymptomsSelectorPage> {
late DialogService dialogService; late DialogService dialogService;
late AppState _appState;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
dialogService = getIt<DialogService>(); dialogService = getIt<DialogService>();
_appState = getIt<AppState>();
// Initialize symptom groups based on selected organs // Initialize symptom groups based on selected organs
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
final viewModel = context.read<SymptomsCheckerViewModel>(); final viewModel = context.read<SymptomsCheckerViewModel>();
@ -100,10 +103,11 @@ class _SymptomsSelectorPageState extends State<SymptomsSelectorPage> {
// Find matching organ ID from selected organs // Find matching organ ID from selected organs
String? organId; String? organId;
String? organName; String? organName;
final isArabic = _appState.isArabic();
for (var organ in viewModel.selectedOrgans) { for (var organ in viewModel.selectedOrgans) {
if (organ.name == organResult.name) { if (organ.name == organResult.name) {
organId = organ.id; organId = organ.id;
organName = organ.description; organName = organ.getLocalizedDescription(isArabic);
break; break;
} }
} }
@ -141,6 +145,8 @@ class _SymptomsSelectorPageState extends State<SymptomsSelectorPage> {
String organName, String organName,
List<BodySymptom> symptoms, List<BodySymptom> symptoms,
) { ) {
final isArabic = _appState.isArabic();
return Container( return Container(
width: double.infinity, width: double.infinity,
margin: EdgeInsets.symmetric(horizontal: 24.w), margin: EdgeInsets.symmetric(horizontal: 24.w),
@ -154,7 +160,7 @@ class _SymptomsSelectorPageState extends State<SymptomsSelectorPage> {
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
'Possible symptoms related to "$organName"', '${LocaleKeys.possibleSymptomsRelatedTo.tr(context: context)} "$organName"',
style: TextStyle(fontSize: 18.f, fontWeight: FontWeight.w600, color: AppColors.textColor), style: TextStyle(fontSize: 18.f, fontWeight: FontWeight.w600, color: AppColors.textColor),
), ),
), ),
@ -166,7 +172,7 @@ class _SymptomsSelectorPageState extends State<SymptomsSelectorPage> {
spacing: 8.w, spacing: 8.w,
children: symptoms.map((symptom) { children: symptoms.map((symptom) {
final symptomId = symptom.id ?? ''; final symptomId = symptom.id ?? '';
final symptomLabel = symptom.getDisplayName(false); // Pass isArabic from AppState if needed final symptomLabel = symptom.getDisplayName(isArabic);
bool isSelected = viewModel.isSymptomSelected(organId, symptomId); bool isSelected = viewModel.isSymptomSelected(organId, symptomId);
return GestureDetector( return GestureDetector(
onTap: () => viewModel.toggleSymptomSelection(organId, symptomId), onTap: () => viewModel.toggleSymptomSelection(organId, symptomId),
@ -306,7 +312,7 @@ class _SymptomsSelectorPageState extends State<SymptomsSelectorPage> {
fontSize: 16.f, fontSize: 16.f,
), ),
), ),
], ],
), ),
SizedBox(height: 24.h), SizedBox(height: 24.h),
], ],

@ -4,6 +4,7 @@ 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';
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/dependencies.dart'; import 'package:hmg_patient_app_new/core/dependencies.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/route_extensions.dart';
@ -32,12 +33,14 @@ class TriagePage extends StatefulWidget {
class _TriagePageState extends State<TriagePage> { class _TriagePageState extends State<TriagePage> {
late SymptomsCheckerViewModel viewModel; late SymptomsCheckerViewModel viewModel;
late DialogService dialogService; late DialogService dialogService;
late AppState _appState;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
viewModel = context.read<SymptomsCheckerViewModel>(); viewModel = context.read<SymptomsCheckerViewModel>();
dialogService = getIt.get<DialogService>(); dialogService = getIt.get<DialogService>();
_appState = getIt.get<AppState>();
// Start triage process when screen loads // Start triage process when screen loads
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
@ -436,7 +439,8 @@ class _TriagePageState extends State<TriagePage> {
Widget _buildStickyBottomCard(BuildContext context, SymptomsCheckerViewModel viewModel) { Widget _buildStickyBottomCard(BuildContext context, SymptomsCheckerViewModel viewModel) {
// Get the top condition with highest probability // Get the top condition with highest probability
final conditions = viewModel.currentConditions ?? []; final conditions = viewModel.currentConditions ?? [];
String suggestedCondition = "Analyzing..."; final isArabic = _appState.isArabic();
String suggestedCondition = LocaleKeys.analyzing.tr(context: context);
double probability = 0.0; double probability = 0.0;
if (conditions.isNotEmpty) { if (conditions.isNotEmpty) {
@ -445,7 +449,7 @@ class _TriagePageState extends State<TriagePage> {
sortedConditions.sort((a, b) => (b.probability ?? 0.0).compareTo(a.probability ?? 0.0)); sortedConditions.sort((a, b) => (b.probability ?? 0.0).compareTo(a.probability ?? 0.0));
final topCondition = sortedConditions.first; final topCondition = sortedConditions.first;
suggestedCondition = topCondition.commonName ?? topCondition.name ?? "Unknown"; suggestedCondition = topCondition.getDisplayName(isArabic: isArabic);
probability = (topCondition.probability ?? 0.0) * 100; // Convert to percentage probability = (topCondition.probability ?? 0.0) * 100; // Convert to percentage
} }
// final bool isHighConfidence = probability >= 70.0; // final bool isHighConfidence = probability >= 70.0;

@ -43,13 +43,10 @@ class _UserInfoSelectionPageState extends State<UserInfoSelectionPage> {
if (user == null) return; if (user == null) return;
// Populate gender (gender is int: 1=Male, 2=Female) // Populate gender (gender is int: 1=Male, 2=Female)
// Use internal keys (male/female) for storage
if (user.gender != null) { if (user.gender != null) {
String genderStr = user.gender == 1 String genderKey = user.gender == 1 ? "male" : user.gender == 2 ? "female" : "other";
? "Male" viewModel.setGender(genderKey);
: user.gender == 2
? "Female"
: "Other";
viewModel.setGender(genderStr);
} }
if (user.dateofBirth != null && user.dateofBirth!.isNotEmpty) { if (user.dateofBirth != null && user.dateofBirth!.isNotEmpty) {
@ -84,12 +81,13 @@ class _UserInfoSelectionPageState extends State<UserInfoSelectionPage> {
child: Row( child: Row(
children: [ children: [
Container( Container(
height: 40.h, height: 40.h,
width: 40.h, width: 40.h,
margin: EdgeInsets.only(right: 10.h), margin: EdgeInsetsDirectional.only(end: 10.h),
padding: EdgeInsets.all(8.h), padding: EdgeInsets.all(8.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 12.r, color: AppColors.greyColor), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 12.r, color: AppColors.greyColor),
child: Utils.buildSvgWithAssets(icon: leadingIcon, iconColor: iconColor)), child: Utils.buildSvgWithAssets(icon: leadingIcon, iconColor: iconColor),
),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -112,6 +110,20 @@ class _UserInfoSelectionPageState extends State<UserInfoSelectionPage> {
).paddingSymmetrical(0, 8.h); ).paddingSymmetrical(0, 8.h);
} }
/// Convert internal gender key to localized display string
String _getLocalizedGender(String? genderKey, BuildContext context) {
if (genderKey == null) return LocaleKeys.notSet.tr(context: context);
final lowerKey = genderKey.toLowerCase();
if (lowerKey == "male") {
return LocaleKeys.malE.tr(context: context);
} else if (lowerKey == "female") {
return LocaleKeys.femaleGender.tr(context: context);
} else {
return genderKey; // Return as-is if not recognized
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
AppState appState = getIt.get<AppState>(); AppState appState = getIt.get<AppState>();
@ -151,7 +163,7 @@ class _UserInfoSelectionPageState extends State<UserInfoSelectionPage> {
viewModel.selectedWeight == null; viewModel.selectedWeight == null;
// Get display values // Get display values
String genderText = viewModel.selectedGender ?? LocaleKeys.notSet.tr(context: context); String genderText = _getLocalizedGender(viewModel.selectedGender, context);
// Show age calculated from DOB (prefer viewModel's age, fallback to calculated from user's DOB) // Show age calculated from DOB (prefer viewModel's age, fallback to calculated from user's DOB)
int? displayAge = viewModel.selectedAge ?? userAgeFromDOB; int? displayAge = viewModel.selectedAge ?? userAgeFromDOB;
String ageText = displayAge != null ? "$displayAge ${LocaleKeys.years.tr(context: context)}" : LocaleKeys.notSet.tr(context: context); String ageText = displayAge != null ? "$displayAge ${LocaleKeys.years.tr(context: context)}" : LocaleKeys.notSet.tr(context: context);

@ -15,12 +15,16 @@ class GenderSelectionPage extends StatelessWidget {
final String? selectedGender; final String? selectedGender;
final Function(String) onGenderSelected; final Function(String) onGenderSelected;
GenderSelectionPage({ const GenderSelectionPage({
super.key, super.key,
required this.selectedGender, required this.selectedGender,
required this.onGenderSelected, required this.onGenderSelected,
}); });
// Internal gender keys (constant, not localized)
static const String maleKey = "male";
static const String femaleKey = "female";
_buildGenderOption(String iconPng, String label, bool isSelected) { _buildGenderOption(String iconPng, String label, bool isSelected) {
return Container( return Container(
height: 160.h, height: 160.h,
@ -40,7 +44,27 @@ class GenderSelectionPage extends StatelessWidget {
); );
} }
final genders = ["Male", "Female"]; /// Check if the selected gender matches the given key
/// Handles both internal keys and localized strings
bool _isGenderSelected(String genderKey, String? currentSelection, BuildContext context) {
if (currentSelection == null) return false;
final lowerSelection = currentSelection.toLowerCase();
if (genderKey == maleKey) {
// Check against internal key, English, and Arabic
return lowerSelection == maleKey ||
lowerSelection == "male" ||
currentSelection == LocaleKeys.malE.tr(context: context) ||
currentSelection == "ذكر";
} else {
// Check against internal key, English, and Arabic
return lowerSelection == femaleKey ||
lowerSelection == "female" ||
currentSelection == LocaleKeys.femaleGender.tr(context: context) ||
currentSelection == "أنثى";
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -56,16 +80,25 @@ class GenderSelectionPage extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: InkWell( child: InkWell(
onTap: () => onGenderSelected(genders[0]), onTap: () => onGenderSelected(maleKey),
child: _buildGenderOption(AppAssets.maleIcon, LocaleKeys.malE.tr(context: context), symptomsViewModel.selectedGender == genders[0]), child: _buildGenderOption(
AppAssets.maleIcon,
LocaleKeys.malE.tr(context: context),
_isGenderSelected(maleKey, symptomsViewModel.selectedGender, context),
),
), ),
), ),
SizedBox(width: 16.w), SizedBox(width: 16.w),
Expanded( Expanded(
child: InkWell( child: InkWell(
onTap: () => onGenderSelected(genders[1]), onTap: () => onGenderSelected(femaleKey),
child: _buildGenderOption(AppAssets.femaleIcon, LocaleKeys.femaleGender.tr(context: context), symptomsViewModel.selectedGender == genders[1]), child: _buildGenderOption(
)) AppAssets.femaleIcon,
LocaleKeys.femaleGender.tr(context: context),
_isGenderSelected(femaleKey, symptomsViewModel.selectedGender, context),
),
),
)
], ],
), ),
], ],

@ -4,7 +4,6 @@ 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_export.dart'; import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/extensions/route_extensions.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/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/user_info_selection/pages/age_selection_page.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection/pages/age_selection_page.dart';
@ -29,13 +28,15 @@ class _UserInfoFlowManagerState extends State<UserInfoFlowManager> {
late PageController _pageController; late PageController _pageController;
late SymptomsCheckerViewModel _viewModel; late SymptomsCheckerViewModel _viewModel;
// Page titles // Get localized page titles
final List<String> _pageTitles = [ List<String> _getPageTitles(BuildContext context) {
"Your Gender", return [
"Your Birth Date", LocaleKeys.genderSymptoms.tr(context: context),
"Your Height", LocaleKeys.dateOfBirthSymptoms.tr(context: context),
"Your Weight", LocaleKeys.heightSymptoms.tr(context: context),
]; LocaleKeys.weightSymptoms.tr(context: context),
];
}
@override @override
void initState() { void initState() {
@ -187,9 +188,11 @@ class _UserInfoFlowManagerState extends State<UserInfoFlowManager> {
? // Single page edit mode - show only Save button ? // Single page edit mode - show only Save button
CustomButton( CustomButton(
text: LocaleKeys.save.tr(context: context), text: LocaleKeys.save.tr(context: context),
onPressed: _onNext, isDisabled: !(viewModel.isCurrentUserInfoPageValid),
backgroundColor: AppColors.primaryRedColor, onPressed: () => viewModel.isCurrentUserInfoPageValid ? _onNext() : () {},
borderColor: AppColors.primaryRedColor, backgroundColor:
viewModel.isCurrentUserInfoPageValid ? AppColors.primaryRedColor : AppColors.primaryRedColor.withValues(alpha: 0.5),
borderColor: viewModel.isCurrentUserInfoPageValid ? AppColors.primaryRedColor : AppColors.primaryRedColor.withValues(alpha: 0.5),
textColor: AppColors.whiteColor, textColor: AppColors.whiteColor,
fontSize: 16.f, fontSize: 16.f,
) )
@ -228,6 +231,8 @@ class _UserInfoFlowManagerState extends State<UserInfoFlowManager> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final pageTitles = _getPageTitles(context);
return Scaffold( return Scaffold(
backgroundColor: AppColors.bgScaffoldColor, backgroundColor: AppColors.bgScaffoldColor,
body: Column( body: Column(
@ -235,7 +240,7 @@ class _UserInfoFlowManagerState extends State<UserInfoFlowManager> {
Expanded( Expanded(
child: CollapsingListView( child: CollapsingListView(
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
title: _pageTitles[_viewModel.userInfoCurrentPage], title: pageTitles[_viewModel.userInfoCurrentPage],
isLeading: true, isLeading: true,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,

@ -2,6 +2,8 @@ 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';
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/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/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';
@ -24,8 +26,11 @@ class ConditionCard extends StatelessWidget {
this.onActionPressed, this.onActionPressed,
}); });
/// Get title from condition /// Get title from condition (localized)
String get title => condition.commonName ?? condition.name ?? ''; String get title {
final appState = getIt<AppState>();
return condition.getDisplayName(isArabic: appState.isArabic());
}
/// Get percentage from probability (0-1 to 0-100) /// Get percentage from probability (0-1 to 0-100)
int get percentage => ((condition.probability ?? 0) * 100).toInt(); int get percentage => ((condition.probability ?? 0) * 100).toInt();
@ -69,14 +74,14 @@ class ConditionCard extends StatelessWidget {
return LocaleKeys.emergency.tr(context: context); return LocaleKeys.emergency.tr(context: context);
case TriageLevelEnum.consultation24: case TriageLevelEnum.consultation24:
case TriageLevelEnum.consultation: case TriageLevelEnum.consultation:
return "Seek Medical Advice".needTranslation; return LocaleKeys.seekMedicalAdvice.tr(context: context);
case TriageLevelEnum.selfCare: case TriageLevelEnum.selfCare:
return LocaleKeys.monitor.tr(context: context); return LocaleKeys.monitor.tr(context: context);
} }
} }
// Default based on probability // Default based on probability
if (percentage >= 70) { if (percentage >= 70) {
return "Seek Medical Advice".needTranslation; return LocaleKeys.seekMedicalAdvice.tr(context: context);
} else { } else {
return LocaleKeys.monitor.tr(context: context); return LocaleKeys.monitor.tr(context: context);
} }
@ -85,7 +90,7 @@ class ConditionCard extends StatelessWidget {
/// Get monitor note if applicable /// Get monitor note if applicable
String? getMonitorNote(BuildContext context) { String? getMonitorNote(BuildContext context) {
if (severityEnum == PossibleConditionsSeverityEnum.monitorOnly) { if (severityEnum == PossibleConditionsSeverityEnum.monitorOnly) {
return "No need to visit doctor".needTranslation; return LocaleKeys.noNeedToVisitDoctor.tr(context: context);
} }
return null; return null;
} }
@ -236,7 +241,7 @@ class ConditionCard extends StatelessWidget {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Common Symptom".needTranslation.toText14(weight: FontWeight.w600, color: AppColors.textColor), LocaleKeys.commonSymptom.tr(context: context).toText14(weight: FontWeight.w600, color: AppColors.textColor),
_buildSymptomsRow(), _buildSymptomsRow(),
SizedBox(height: 16.h), SizedBox(height: 16.h),
LocaleKeys.description.tr(context: context).toText14(weight: FontWeight.bold, color: AppColors.textColor), LocaleKeys.description.tr(context: context).toText14(weight: FontWeight.bold, color: AppColors.textColor),
@ -244,7 +249,7 @@ class ConditionCard extends StatelessWidget {
description.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), description.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor),
if (severityEnum != PossibleConditionsSeverityEnum.monitorOnly) if (severityEnum != PossibleConditionsSeverityEnum.monitorOnly)
CustomButton( CustomButton(
text: "Book Appointment".needTranslation, text: LocaleKeys.bookAppointment.tr(context: context),
onPressed: () { onPressed: () {
if (onActionPressed != null) { if (onActionPressed != null) {
onActionPressed!(); onActionPressed!();

@ -13,6 +13,7 @@ class InteractiveBodyWidget extends StatefulWidget {
final bool isBodyHidden; final bool isBodyHidden;
final Function(String organId) onOrganTap; final Function(String organId) onOrganTap;
final String? tooltipOrganId; final String? tooltipOrganId;
final bool isArabic;
const InteractiveBodyWidget({ const InteractiveBodyWidget({
super.key, super.key,
@ -22,6 +23,7 @@ class InteractiveBodyWidget extends StatefulWidget {
required this.onOrganTap, required this.onOrganTap,
this.isBodyHidden = false, this.isBodyHidden = false,
this.tooltipOrganId, this.tooltipOrganId,
this.isArabic = false,
}); });
@override @override
@ -118,7 +120,10 @@ class _InteractiveBodyWidgetState extends State<InteractiveBodyWidget> {
(organ) { (organ) {
final centerX = organ.position.x * imageConstraints.maxWidth; final centerX = organ.position.x * imageConstraints.maxWidth;
final centerY = organ.position.y * imageConstraints.maxHeight; final centerY = organ.position.y * imageConstraints.maxHeight;
return OrganTooltipWidget(organName: organ.description, position: Offset(centerX, centerY)); return OrganTooltipWidget(
organName: organ.getLocalizedDescription(widget.isArabic),
position: Offset(centerX, centerY),
);
}, },
), ),
], ],

@ -145,7 +145,7 @@ class AncillaryOrderCard extends StatelessWidget {
if (!isLoading) ...[ if (!isLoading) ...[
Image.network( Image.network(
"https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png",
width: 63.w, width: 63.h,
height: 63.h, height: 63.h,
fit: BoxFit.cover, fit: BoxFit.cover,
).circle(100.r), ).circle(100.r),
@ -177,11 +177,11 @@ class AncillaryOrderCard extends StatelessWidget {
labelText: order.projectName ?? '-', labelText: order.projectName ?? '-',
).toShimmer2(isShow: isLoading), ).toShimmer2(isShow: isLoading),
// orderNo // orderNo
// if (order.orderNo != null || isLoading) if (order.orderNo != null || isLoading)
// AppCustomChipWidget( AppCustomChipWidget(
// // icon: AppAssets.calendar, // icon: AppAssets.calendar,
// labelText: "${"Order# :".needTranslation}${order.orderNo ?? '-'}", labelText: "${LocaleKeys.orderNumber.tr(context: context)}${order.orderNo ?? '-'}",
// ).toShimmer2(isShow: isLoading), ).toShimmer2(isShow: isLoading),
// Appointment Date // Appointment Date
if (order.appointmentDate != null || isLoading) if (order.appointmentDate != null || isLoading)

@ -1,5 +1,6 @@
import 'dart:ui'; import 'dart:ui';
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';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
@ -8,6 +9,7 @@ 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/hmg_services/hmg_services_view_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/vital_sign_respo_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/vital_sign_respo_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/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/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart';
@ -42,7 +44,7 @@ class _VitalSignPageState extends State<VitalSignPage> {
return Scaffold( return Scaffold(
backgroundColor: AppColors.bgScaffoldColor, backgroundColor: AppColors.bgScaffoldColor,
body: CollapsingListView( body: CollapsingListView(
title: 'Vital Signs', title: LocaleKeys.vitalSigns.tr(context: context),
child: Consumer<HmgServicesViewModel>( child: Consumer<HmgServicesViewModel>(
builder: (context, viewModel, child) { builder: (context, viewModel, child) {
@ -70,14 +72,14 @@ class _VitalSignPageState extends State<VitalSignPage> {
// BMI Card // BMI Card
_buildVitalSignCard( _buildVitalSignCard(
icon: AppAssets.bmiVital, icon: AppAssets.bmiVital,
label: 'BMI', label: LocaleKeys.bmi.tr(context: context),
value: latestVitalSign?.bodyMassIndex?.toString() ?? '--', value: latestVitalSign?.bodyMassIndex?.toString() ?? '--',
unit: '', unit: '',
status: VitalSignUiModel.bmiStatus(latestVitalSign?.bodyMassIndex), status: VitalSignUiModel.bmiStatus(latestVitalSign?.bodyMassIndex),
onTap: () => _openDetails( onTap: () => _openDetails(
const VitalSignDetailsArgs( VitalSignDetailsArgs(
metric: VitalSignMetric.bmi, metric: VitalSignMetric.bmi,
title: 'BMI', title: LocaleKeys.bmi.tr(context: context),
icon: AppAssets.bmiVital, icon: AppAssets.bmiVital,
unit: '', unit: '',
), ),
@ -88,14 +90,14 @@ class _VitalSignPageState extends State<VitalSignPage> {
// Height Card // Height Card
_buildVitalSignCard( _buildVitalSignCard(
icon: AppAssets.heightVital, icon: AppAssets.heightVital,
label: 'Height', label: LocaleKeys.height.tr(context: context),
value: latestVitalSign?.heightCm?.toString() ?? '--', value: latestVitalSign?.heightCm?.toString() ?? '--',
unit: 'cm', unit: 'cm',
status: null, status: null,
onTap: () => _openDetails( onTap: () => _openDetails(
const VitalSignDetailsArgs( VitalSignDetailsArgs(
metric: VitalSignMetric.height, metric: VitalSignMetric.height,
title: 'Height', title: LocaleKeys.height.tr(context: context),
icon: AppAssets.heightVital, icon: AppAssets.heightVital,
unit: 'cm', unit: 'cm',
), ),
@ -106,14 +108,14 @@ class _VitalSignPageState extends State<VitalSignPage> {
// Weight Card // Weight Card
_buildVitalSignCard( _buildVitalSignCard(
icon: AppAssets.weightVital, icon: AppAssets.weightVital,
label: 'Weight', label: LocaleKeys.weight.tr(context: context),
value: latestVitalSign?.weightKg?.toString() ?? '--', value: latestVitalSign?.weightKg?.toString() ?? '--',
unit: 'kg', unit: 'kg',
status: (latestVitalSign?.weightKg != null) ? 'Normal' : null, status: (latestVitalSign?.weightKg != null) ? 'Normal' : null,
onTap: () => _openDetails( onTap: () => _openDetails(
const VitalSignDetailsArgs( VitalSignDetailsArgs(
metric: VitalSignMetric.weight, metric: VitalSignMetric.weight,
title: 'Weight', title: LocaleKeys.height.tr(context: context),
icon: AppAssets.weightVital, icon: AppAssets.weightVital,
unit: 'kg', unit: 'kg',
), ),
@ -124,7 +126,7 @@ class _VitalSignPageState extends State<VitalSignPage> {
// Blood Pressure Card // Blood Pressure Card
_buildVitalSignCard( _buildVitalSignCard(
icon: AppAssets.bloodPressure, icon: AppAssets.bloodPressure,
label: 'Blood Pressure', label: LocaleKeys.bloodPressure.tr(context: context),
value: latestVitalSign != null && value: latestVitalSign != null &&
latestVitalSign.bloodPressureHigher != null && latestVitalSign.bloodPressureHigher != null &&
latestVitalSign.bloodPressureLower != null latestVitalSign.bloodPressureLower != null
@ -136,9 +138,9 @@ class _VitalSignPageState extends State<VitalSignPage> {
diastolic: latestVitalSign?.bloodPressureLower, diastolic: latestVitalSign?.bloodPressureLower,
), ),
onTap: () => _openDetails( onTap: () => _openDetails(
const VitalSignDetailsArgs( VitalSignDetailsArgs(
metric: VitalSignMetric.bloodPressure, metric: VitalSignMetric.bloodPressure,
title: 'Blood Pressure', title: LocaleKeys.bloodPressure.tr(context: context),
icon: AppAssets.bloodPressure, icon: AppAssets.bloodPressure,
unit: 'mmHg', unit: 'mmHg',
low: 90, low: 90,
@ -151,14 +153,14 @@ class _VitalSignPageState extends State<VitalSignPage> {
// Temperature Card // Temperature Card
_buildVitalSignCard( _buildVitalSignCard(
icon: AppAssets.temperature, icon: AppAssets.temperature,
label: 'Temperature', label: LocaleKeys.temperature.tr(context: context),
value: latestVitalSign?.temperatureCelcius?.toString() ?? '--', value: latestVitalSign?.temperatureCelcius?.toString() ?? '--',
unit: '°C', unit: '°C',
status: null, status: null,
onTap: () => _openDetails( onTap: () => _openDetails(
const VitalSignDetailsArgs( VitalSignDetailsArgs(
metric: VitalSignMetric.temperature, metric: VitalSignMetric.temperature,
title: 'Temperature', title: LocaleKeys.temperature.tr(context: context),
icon: AppAssets.temperature, icon: AppAssets.temperature,
unit: '°C', unit: '°C',
low: 36.1, low: 36.1,
@ -226,14 +228,14 @@ class _VitalSignPageState extends State<VitalSignPage> {
bottom: 12.h, bottom: 12.h,
child: _buildVitalSignCard( child: _buildVitalSignCard(
icon: AppAssets.heart, icon: AppAssets.heart,
label: 'Heart Rate', label: LocaleKeys.heart.tr(context: context),
value: latestVitalSign?.heartRate?.toString() ?? latestVitalSign?.pulseBeatPerMinute?.toString() ?? '--', value: latestVitalSign?.heartRate?.toString() ?? latestVitalSign?.pulseBeatPerMinute?.toString() ?? '--',
unit: 'bpm', unit: 'bpm',
status: 'Normal', status: 'Normal',
onTap: () => _openDetails( onTap: () => _openDetails(
const VitalSignDetailsArgs( VitalSignDetailsArgs(
metric: VitalSignMetric.heartRate, metric: VitalSignMetric.heartRate,
title: 'Heart Rate', title: LocaleKeys.heart.tr(context: context),
icon: AppAssets.heart, icon: AppAssets.heart,
unit: 'bpm', unit: 'bpm',
low: 60, low: 60,
@ -250,15 +252,15 @@ class _VitalSignPageState extends State<VitalSignPage> {
// Respiratory rate Card // Respiratory rate Card
_buildVitalSignCard( _buildVitalSignCard(
icon: AppAssets.respRate, icon: AppAssets.respRate,
label: 'Respiratory rate', label: LocaleKeys.respirationRate.tr(context: context),
value: latestVitalSign?.respirationBeatPerMinute?.toString() ?? '--', value: latestVitalSign?.respirationBeatPerMinute?.toString() ?? '--',
unit: 'bpm', unit: 'bpm',
status: 'Normal', status: 'Normal',
onTap: () => _openDetails( onTap: () => _openDetails(
const VitalSignDetailsArgs( VitalSignDetailsArgs(
metric: VitalSignMetric.respiratoryRate, metric: VitalSignMetric.respiratoryRate,
title: 'Respiratory rate', title: LocaleKeys.respirationRate.tr(context: context),
icon: AppAssets.respRate, icon: AppAssets.respRate,
unit: 'bpm', unit: 'bpm',
low: 12, low: 12,
high: 20, high: 20,

@ -212,7 +212,7 @@ Widget exceptionBottomSheetWidget(
children: [ children: [
Expanded( Expanded(
child: CustomButton( child: CustomButton(
text: LocaleKeys.cancel.tr(), text: LocaleKeys.cancel.tr(context: context),
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
@ -226,7 +226,7 @@ Widget exceptionBottomSheetWidget(
SizedBox(width: 10.h), SizedBox(width: 10.h),
Expanded( Expanded(
child: CustomButton( child: CustomButton(
text: LocaleKeys.confirm.tr(), text: LocaleKeys.confirm.tr(context: context),
onPressed: onOkPressed, onPressed: onOkPressed,
backgroundColor: AppColors.bgGreenColor, backgroundColor: AppColors.bgGreenColor,
borderColor: AppColors.bgGreenColor, borderColor: AppColors.bgGreenColor,
@ -240,7 +240,7 @@ Widget exceptionBottomSheetWidget(
Padding( Padding(
padding: EdgeInsets.only(bottom: 10.h), padding: EdgeInsets.only(bottom: 10.h),
child: CustomButton( child: CustomButton(
text: LocaleKeys.cancel.tr(), text: LocaleKeys.cancel.tr(context: context),
onPressed: (onCancelPressed == null) onPressed: (onCancelPressed == null)
? () { ? () {
context.pop(); context.pop();
@ -266,7 +266,7 @@ Widget showPhoneNumberPickerWidget(
Padding( Padding(
padding: EdgeInsets.only(bottom: 10.h), padding: EdgeInsets.only(bottom: 10.h),
child: CustomButton( child: CustomButton(
text: LocaleKeys.sendOTPSMS.tr(), text: LocaleKeys.sendOTPSMS.tr(context: context),
onPressed: onSMSPress, onPressed: onSMSPress,
backgroundColor: AppColors.primaryRedColor, backgroundColor: AppColors.primaryRedColor,
borderColor: AppColors.primaryRedBorderColor, borderColor: AppColors.primaryRedBorderColor,
@ -280,14 +280,14 @@ Widget showPhoneNumberPickerWidget(
children: [ children: [
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 8.h), padding: EdgeInsets.symmetric(horizontal: 8.h),
child: LocaleKeys.oR.tr().toText16(color: AppColors.textColor), child: LocaleKeys.oR.tr(context: context).toText16(color: AppColors.textColor),
), ),
], ],
), ),
Padding( Padding(
padding: EdgeInsets.only(bottom: 10.h, top: 10.h), padding: EdgeInsets.only(bottom: 10.h, top: 10.h),
child: CustomButton( child: CustomButton(
text: LocaleKeys.sendOTPWHATSAPP.tr(), text: LocaleKeys.sendOTPWHATSAPP.tr(context: context),
onPressed: onWhatsappPress, onPressed: onWhatsappPress,
backgroundColor: Colors.white, backgroundColor: Colors.white,
borderColor: AppColors.borderOnlyColor, borderColor: AppColors.borderOnlyColor,

@ -48,7 +48,7 @@ class _AppLanguageChangeState extends State<AppLanguageChange> {
), ),
), ),
CustomButton( CustomButton(
text: LocaleKeys.save.tr(), text: LocaleKeys.save.tr(context: context),
onPressed: () { onPressed: () {
context.setLocale(selectedValue == 'en' ? Locale('en', 'US') : Locale('ar', 'SA')).then((val) { context.setLocale(selectedValue == 'en' ? Locale('en', 'US') : Locale('ar', 'SA')).then((val) {
Navigator.pop(context); Navigator.pop(context);

@ -74,15 +74,18 @@ class CustomButton extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
if (icon != null) if (icon != null)
Padding( Flexible(
padding: text.isNotEmpty ? EdgeInsets.only(right: 8.w, left: 8.w) : EdgeInsets.zero, child: Padding(
child: Utils.buildSvgWithAssets(icon: icon!, iconColor: iconColor, isDisabled: isDisabled, width: iconS, height: iconS), padding: text.isNotEmpty ? EdgeInsets.only(right: 4.w, left: 4.w) : EdgeInsets.zero,
child: Utils.buildSvgWithAssets(icon: icon!, iconColor: iconColor, isDisabled: isDisabled, width: iconS, height: iconS),
),
), ),
Visibility( if (text.isNotEmpty)
visible: text.isNotEmpty, Text(
child: Text(
text, text,
overflow: textOverflow, overflow: textOverflow ?? TextOverflow.ellipsis,
maxLines: 1,
textAlign: TextAlign.center,
style: context.dynamicTextStyle( style: context.dynamicTextStyle(
fontSize: fontS, fontSize: fontS,
color: isDisabled ? AppColors.greyTextColor : textColor, color: isDisabled ? AppColors.greyTextColor : textColor,
@ -90,7 +93,6 @@ class CustomButton extends StatelessWidget {
fontWeight: fontWeight, fontWeight: fontWeight,
), ),
), ),
),
], ],
), ),
)); ));

@ -42,13 +42,13 @@ class BottomSheetUtils{
Future<void> _showReminderBottomSheet(BuildContext providedContext, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted, Future<void> _showReminderBottomSheet(BuildContext providedContext, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted,
{required Function onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool? isMultiAllowed}) async { {required Function onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool? isMultiAllowed}) async {
showCommonBottomSheetWithoutHeight(providedContext, title: LocaleKeys.setTimerOfReminder.tr(), child: PrescriptionReminderView( showCommonBottomSheetWithoutHeight(providedContext, title: LocaleKeys.setTimerOfReminder.tr(context: providedContext), child: PrescriptionReminderView(
setReminder: (int value) async { setReminder: (int value) async {
if (!isMultiAllowed!) { if (!isMultiAllowed!) {
if (onMultiDateSuccess == null) { if (onMultiDateSuccess == null) {
CalenderUtilsNew calendarUtils = CalenderUtilsNew.instance; CalenderUtilsNew calendarUtils = CalenderUtilsNew.instance;
await calendarUtils.createOrUpdateEvent( await calendarUtils.createOrUpdateEvent(
title: title ?? LocaleKeys.youHaveAppointmentWithDr.tr() + doctorName, title: title ?? LocaleKeys.youHaveAppointmentWithDr.tr(context: providedContext) + doctorName,
description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted, description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted,
scheduleDateTime: dateTime, scheduleDateTime: dateTime,
eventId: eventId, eventId: eventId,

@ -282,9 +282,9 @@ class ExpandableListTheme {
dividerColor: dividerColor ?? Colors.grey.shade300, dividerColor: dividerColor ?? Colors.grey.shade300,
defaultTrailingIcon: defaultTrailingIcon ?? defaultTrailingIcon: defaultTrailingIcon ??
Icon(Icons.keyboard_arrow_down, color: Colors.black, size: 24), Icon(Icons.keyboard_arrow_down, color: Colors.black, size: 24),
itemPadding: itemPadding ?? const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), itemPadding: itemPadding ?? EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
contentPadding: contentPadding ?? const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 16.0), contentPadding: contentPadding ?? EdgeInsets.only(left: 16.w, right: 16.w, bottom: 16.h),
leadingSpacing: leadingSpacing ?? 12.0, leadingSpacing: leadingSpacing ?? 12.w,
); );
} }
} }

@ -153,10 +153,18 @@ class TextInputWidget extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
_buildLabelText(labelColor).paddingOnly(right: (appState.getLanguageCode() == "ar" ? 10 : 0)), _buildLabelText(labelColor).paddingOnly(
right: (appState.getLanguageCode() == "ar" ? 10 : 0),
left: (appState.getLanguageCode() == "en" ? 10 : 0),
),
Row( Row(
children: [ children: [
Expanded(child: _buildTextField(context)), Expanded(
child: _buildTextField(context).paddingOnly(
right: (appState.getLanguageCode() == "ar" ? 10 : 0),
left: (appState.getLanguageCode() == "en" ? 10 : 0),
),
)
], ],
), ),
], ],
@ -191,7 +199,7 @@ class TextInputWidget extends StatelessWidget {
return Container( return Container(
height: 40.h, height: 40.h,
width: 40.h, width: 40.h,
margin: EdgeInsets.only(right: 10.h), // margin: EdgeInsets.symmetric(horizontal: 10.w),
padding: EdgeInsets.all(8.h), padding: EdgeInsets.all(8.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
borderRadius: 12.r, borderRadius: 12.r,
@ -204,7 +212,7 @@ class TextInputWidget extends StatelessWidget {
final AppState appState = getIt.get<AppState>(); final AppState appState = getIt.get<AppState>();
return Container( return Container(
height: 40.h, height: 40.h,
width: 40.h, width: 40.w,
margin: EdgeInsets.zero, margin: EdgeInsets.zero,
padding: EdgeInsets.all(8.h), padding: EdgeInsets.all(8.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 12.r, color: AppColors.whiteColor), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 12.r, color: AppColors.whiteColor),

Loading…
Cancel
Save