From 3fc1302eaf369a71c36bbfb04fdd8a5bb5059ab6 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 18 Jan 2026 11:52:41 +0300 Subject: [PATCH 01/10] New Flutter App param added --- lib/core/api/api_client.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 722a45e..66aa34a 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -189,6 +189,8 @@ class ApiClientImp implements ApiClient { // body['SessionID'] = "45786230487560q"; } + body['IsNewFlutterApp'] = true; + body.removeWhere((key, value) => value == null); } From 9ef70a250d639dfeeee948faf0f641049cb750be Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 18 Jan 2026 13:34:24 +0300 Subject: [PATCH 02/10] translation updates --- assets/langs/ar-SA.json | 10 +++- assets/langs/en-US.json | 9 ++- lib/core/api_consts.dart | 2 +- lib/generated/locale_keys.g.dart | 7 +++ .../home/data/landing_page_data.dart | 56 ++++++++++--------- lib/presentation/home/landing_page.dart | 8 +-- .../home/widgets/habib_wallet_card.dart | 8 +-- .../widgets/ancillary_orders_list.dart | 12 ++-- 8 files changed, 68 insertions(+), 44 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 9c1c962..6f25fb5 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1499,5 +1499,13 @@ "selectTime": "حدد الوقت", "pleaseWaitYouWillBeCalledForVitalSigns": "يرجى الانتظار! سيتم استدعاؤك لقياس العلامات الحيوية", "pleaseVisitRoomForVitalSigns": "يرجى زيارة الغرفة {roomNumber} لقياس العلامات الحيوية", - "pleaseVisitRoomToTheDoctor": "يرجى زيارة الغرفة {roomNumber} لمقابلة الطبيب" + "pleaseVisitRoomToTheDoctor": "يرجى زيارة الغرفة {roomNumber} لمقابلة الطبيب", + + "erOnlineCheckInRequest": "ER Online Check-In Request", + "indoor": "داخلي", + "navigation": "الملاحة", + "health": "الصحة", + "calculators": "الحاسبات", + "converters": "المحولات", + "guide": "الدليل" } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 5f356ba..cec6bf3 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1490,5 +1490,12 @@ "selectTime": "Select Time", "pleaseWaitYouWillBeCalledForVitalSigns": "Please wait! you will be called 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" } diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index efefee1..720fda7 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -680,7 +680,7 @@ const DASHBOARD = 'Services/Patients.svc/REST/PatientDashboard'; class ApiConsts { 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 diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index b3b2edf..3ab0ee4 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1488,5 +1488,12 @@ abstract class LocaleKeys { static const pleaseWaitYouWillBeCalledForVitalSigns = 'pleaseWaitYouWillBeCalledForVitalSigns'; static const pleaseVisitRoomForVitalSigns = 'pleaseVisitRoomForVitalSigns'; 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'; } diff --git a/lib/presentation/home/data/landing_page_data.dart b/lib/presentation/home/data/landing_page_data.dart index ef2832b..74fd096 100644 --- a/lib/presentation/home/data/landing_page_data.dart +++ b/lib/presentation/home/data/landing_page_data.dart @@ -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/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/home/data/service_card_data.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; @@ -7,8 +9,8 @@ class LandingPageData { ServiceCardData( serviceName: "emergency", icon: AppAssets.emergency_services_icon, - title: "Emergency", - subtitle: "Services", + title: LocaleKeys.emergency.tr(), + subtitle: LocaleKeys.services2.tr(), backgroundColor: AppColors.primaryRedColor, iconColor: AppColors.whiteColor, textColor: AppColors.whiteColor, @@ -17,8 +19,8 @@ class LandingPageData { ServiceCardData( serviceName: "indoor_navigation", icon: AppAssets.indoor_nav_icon, - title: "Indoor", - subtitle: "Navigation", + title: LocaleKeys.indoor.tr(), + subtitle: LocaleKeys.navigation.tr(), backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -27,8 +29,8 @@ class LandingPageData { ServiceCardData( serviceName: "search_doctor", icon: AppAssets.search_doctor_icon, - title: "Search", - subtitle: "Doctor", + title: LocaleKeys.search.tr(), + subtitle: LocaleKeys.doctor.tr(), backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -37,8 +39,8 @@ class LandingPageData { ServiceCardData( serviceName: "health_calculators_and_converts", icon: AppAssets.health_calculators_icon, - title: "Health", - subtitle: "Calculators", + title: LocaleKeys.health.tr(), + subtitle: LocaleKeys.calculators.tr(), backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -47,8 +49,8 @@ class LandingPageData { ServiceCardData( serviceName: "health_converters", icon: AppAssets.health_converters_icon, - title: "Health", - subtitle: "Converters", + title: LocaleKeys.health.tr(), + subtitle: LocaleKeys.converters.tr(), backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -57,8 +59,8 @@ class LandingPageData { ServiceCardData( serviceName: "parking_guide", icon: AppAssets.car_parking_icon, - title: "Parking", - subtitle: "Guide", + title: LocaleKeys.parking.tr(), + subtitle: LocaleKeys.guide.tr(), backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -70,8 +72,8 @@ class LandingPageData { ServiceCardData( serviceName: "emergency", icon: AppAssets.emergency_services_icon, - title: "Emergency", - subtitle: "Services", + title: LocaleKeys.emergency.tr(), + subtitle: LocaleKeys.services2.tr(), backgroundColor: AppColors.primaryRedColor, iconColor: AppColors.whiteColor, textColor: AppColors.whiteColor, @@ -80,8 +82,8 @@ class LandingPageData { ServiceCardData( serviceName: "lab_results", icon: AppAssets.home_lab_result_icon, - title: "Lab", - subtitle: "Results", + title: LocaleKeys.lab.tr(), + subtitle: LocaleKeys.labSubtitle.tr(), backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -90,8 +92,8 @@ class LandingPageData { ServiceCardData( serviceName: "radiology_results", icon: AppAssets.my_radiology_icon, - title: "Radiology", - subtitle: "Results", + title: LocaleKeys.radiology.tr(), + subtitle: LocaleKeys.radiologySubtitle.tr(), backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -100,8 +102,8 @@ class LandingPageData { ServiceCardData( serviceName: "prescriptions", icon: AppAssets.my_prescription_icon, - title: "Prescriptions", - subtitle: "Details", + title: LocaleKeys.medicinesSubtitle.tr(), + subtitle: LocaleKeys.details.tr(), backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -110,8 +112,8 @@ class LandingPageData { ServiceCardData( serviceName: "insurance_update", icon: AppAssets.insurance_update_icon, - title: "Insurance", - subtitle: "Details", + title: LocaleKeys.insurance.tr(), + subtitle: LocaleKeys.details.tr(), backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -130,8 +132,8 @@ class LandingPageData { ServiceCardData( serviceName: "sick_leaves", icon: AppAssets.my_sick_leave_icon, - title: "Sick", - subtitle: "Leaves", + title: LocaleKeys.sick.tr(), + subtitle: LocaleKeys.sickSubtitle.tr(), backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -143,7 +145,7 @@ class LandingPageData { ServiceCardData( serviceName: "livecare", icon: AppAssets.small_livecare_icon, - title: "LiveCare", + title: LocaleKeys.liveCare.tr(), subtitle: "Explore our app, View our services and offers", largeCardIcon: AppAssets.liveCareService, backgroundColor: AppColors.successColor, @@ -161,7 +163,7 @@ class LandingPageData { ServiceCardData( serviceName: "home_health_care", icon: AppAssets.homeBottom, - title: "Home Health Care", + title: LocaleKeys.homeHealthCare.tr(), subtitle: "Explore our app, View our services and offers", largeCardIcon: AppAssets.homeHealthCareService, backgroundColor: AppColors.primaryRedColor, @@ -171,7 +173,7 @@ class LandingPageData { ServiceCardData( serviceName: "pharmacy", icon: AppAssets.pharmacy_icon, //359846 - title: "Pharmacy", + title: LocaleKeys.hmgPharmacy.tr(), subtitle: "Explore our app, View our services and offers", largeCardIcon: AppAssets.pharmacyService, backgroundColor: AppColors.pharmacyBGColor, diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index fc400c4..f8cd159 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -305,7 +305,7 @@ class _LandingPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "Appointments & Visits".toText16(isBold: true), + LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(isBold: true), Row( children: [ LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor), @@ -465,7 +465,7 @@ class _LandingPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppCustomChipWidget( - labelText: "ER Online Check-In Request", + labelText: LocaleKeys.erOnlineCheckInRequest.tr(context: context), backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.10), textColor: AppColors.primaryRedColor, ), @@ -597,10 +597,10 @@ class _LandingPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "Services".toText16(isBold: true), + LocaleKeys.services2.tr(context: context).toText16(isBold: true), Row( children: [ - "View all services".toText12(color: AppColors.primaryRedColor), + LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor), SizedBox(width: 2.h), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), ], diff --git a/lib/presentation/home/widgets/habib_wallet_card.dart b/lib/presentation/home/widgets/habib_wallet_card.dart index 9058c8f..fb04baf 100644 --- a/lib/presentation/home/widgets/habib_wallet_card.dart +++ b/lib/presentation/home/widgets/habib_wallet_card.dart @@ -23,10 +23,10 @@ class HabibWalletCard extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "My Balance".toText16(isBold: true), + LocaleKeys.myBalance.tr(context: context).toText16(isBold: true), Row( children: [ - "View all services".toText12(color: AppColors.primaryRedColor), + LocaleKeys.viewAllServices.tr(context: context).toText12(color: AppColors.primaryRedColor), SizedBox(width: 2.h), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), ], @@ -54,7 +54,7 @@ class HabibWalletCard extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "Habib Wallet".toText15(isBold: true), + LocaleKeys.habibWallet.tr(context: context).toText15(isBold: true), Container( height: 40.h, width: 40.h, @@ -94,7 +94,7 @@ class HabibWalletCard extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 50.h), child: Row( children: [ - "View details".toText12(color: AppColors.primaryRedColor), + LocaleKeys.viewDetails.tr(context: context).toText12(color: AppColors.primaryRedColor), SizedBox(width: 2.h), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), ], diff --git a/lib/presentation/todo_section/widgets/ancillary_orders_list.dart b/lib/presentation/todo_section/widgets/ancillary_orders_list.dart index aa4d0ba..71d2cf0 100644 --- a/lib/presentation/todo_section/widgets/ancillary_orders_list.dart +++ b/lib/presentation/todo_section/widgets/ancillary_orders_list.dart @@ -145,7 +145,7 @@ class AncillaryOrderCard extends StatelessWidget { if (!isLoading) ...[ Image.network( "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown.png", - width: 63.w, + width: 63.h, height: 63.h, fit: BoxFit.cover, ).circle(100.r), @@ -177,11 +177,11 @@ class AncillaryOrderCard extends StatelessWidget { labelText: order.projectName ?? '-', ).toShimmer2(isShow: isLoading), // orderNo - // if (order.orderNo != null || isLoading) - // AppCustomChipWidget( - // // icon: AppAssets.calendar, - // labelText: "${"Order# :".needTranslation}${order.orderNo ?? '-'}", - // ).toShimmer2(isShow: isLoading), + if (order.orderNo != null || isLoading) + AppCustomChipWidget( + // icon: AppAssets.calendar, + labelText: "${LocaleKeys.orderNumber.tr(context: context)}${order.orderNo ?? '-'}", + ).toShimmer2(isShow: isLoading), // Appointment Date if (order.appointmentDate != null || isLoading) From 3bdc4e246faae9c605da34de75caf948e3ff09d2 Mon Sep 17 00:00:00 2001 From: faizatflutter Date: Sun, 18 Jan 2026 15:20:04 +0300 Subject: [PATCH 03/10] refactor --- .../hmg_services/services_page.dart | 148 +- pubspec.lock | 1985 ----------------- 2 files changed, 84 insertions(+), 2049 deletions(-) delete mode 100644 pubspec.lock diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index 5c028db..384990a 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -50,7 +50,14 @@ class ServicesPage extends StatelessWidget { late MedicalFileViewModel medicalFileViewModel; late final List hmgServices = [ - HmgServicesComponentModel(11, "Emergency Services".needTranslation, "".needTranslation, AppAssets.emergency_services_icon, bgColor: AppColors.primaryRedColor, true, route: null, onTap: () async { + HmgServicesComponentModel( + 11, + "Emergency Services".needTranslation, + "".needTranslation, + AppAssets.emergency_services_icon, + bgColor: AppColors.primaryRedColor, + true, + route: null, onTap: () async { if (getIt.get().isAuthenticated) { getIt.get().flushData(); getIt.get().getTransportationOrders( @@ -78,7 +85,14 @@ class ServicesPage extends StatelessWidget { true, route: AppRoutes.bookAppointmentPage, ), - HmgServicesComponentModel(5, "Complete Checkup".needTranslation, "".needTranslation, AppAssets.comprehensiveCheckup, bgColor: AppColors.bgGreenColor, true, route: null, onTap: () async { + HmgServicesComponentModel( + 5, + "Complete Checkup".needTranslation, + "".needTranslation, + AppAssets.comprehensiveCheckup, + bgColor: AppColors.bgGreenColor, + true, + route: null, onTap: () async { if (getIt.get().isAuthenticated) { getIt.get().pushPageRoute(AppRoutes.comprehensiveCheckupPage); } else { @@ -131,7 +145,13 @@ class ServicesPage extends StatelessWidget { }, ), HmgServicesComponentModel( - 11, "E-Referral Services".needTranslation, "".needTranslation, AppAssets.eReferral, bgColor: AppColors.eReferralCardColor, true, route: null, onTap: () async { + 11, + "E-Referral Services".needTranslation, + "".needTranslation, + AppAssets.eReferral, + bgColor: AppColors.eReferralCardColor, + true, + route: null, onTap: () async { if (getIt.get().isAuthenticated) { getIt.get().pushPageRoute(AppRoutes.eReferralPage); } else { @@ -393,19 +413,19 @@ class ServicesPage extends StatelessWidget { ? CustomButton( height: 40.h, icon: AppAssets.recharge_icon, - iconSize: 16.w, - iconColor: AppColors.infoColor, - textColor: AppColors.infoColor, - text: "Recharge".needTranslation, - borderWidth: 0.w, - fontWeight: FontWeight.w500, - borderColor: Colors.transparent, - backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), - padding: EdgeInsets.all(8.w), - fontSize: 12.f, - onPressed: () { - Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); - }, + iconSize: 16.w, + iconColor: AppColors.infoColor, + textColor: AppColors.infoColor, + text: "Recharge".needTranslation, + borderWidth: 0.w, + fontWeight: FontWeight.w500, + borderColor: Colors.transparent, + backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), + padding: EdgeInsets.all(8.w), + fontSize: 12.f, + onPressed: () { + Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); + }, ) : SizedBox.shrink(), ], @@ -444,60 +464,60 @@ class ServicesPage extends StatelessWidget { getIt.get().isAuthenticated ? Wrap( spacing: -8.h, - // runSpacing: 0.h, - children: [ - Utils.buildImgWithAssets( - icon: AppAssets.babyGirlImg, - height: 28.h, - width: 28.w, - border: 1, - fit: BoxFit.contain, - borderRadius: 50.r, - ), - Utils.buildImgWithAssets( - icon: AppAssets.femaleImg, - height: 28.h, - width: 28.w, - border: 1, - borderRadius: 50.r, - fit: BoxFit.contain, - ), - Utils.buildImgWithAssets( - icon: AppAssets.maleImg, - height: 28.h, - width: 28.w, - border: 1, - borderRadius: 50.r, - fit: BoxFit.contain, - ), - ], + // runSpacing: 0.h, + children: [ + Utils.buildImgWithAssets( + icon: AppAssets.babyGirlImg, + height: 28.h, + width: 28.w, + border: 1, + fit: BoxFit.contain, + borderRadius: 50.r, + ), + Utils.buildImgWithAssets( + icon: AppAssets.femaleImg, + height: 28.h, + width: 28.w, + border: 1, + borderRadius: 50.r, + fit: BoxFit.contain, + ), + Utils.buildImgWithAssets( + icon: AppAssets.maleImg, + height: 28.h, + width: 28.w, + border: 1, + borderRadius: 50.r, + fit: BoxFit.contain, + ), + ], ) : "Login to view your medical file".needTranslation.toText12(fontWeight: FontWeight.w500, maxLine: 2), Spacer(), getIt.get().isAuthenticated ? CustomButton( height: 40.h, - icon: AppAssets.add_icon, - iconSize: 16.w, - iconColor: AppColors.primaryRedColor, - textColor: AppColors.primaryRedColor, - text: "Add Member".needTranslation, - borderWidth: 0.w, - fontWeight: FontWeight.w500, - borderColor: Colors.transparent, - backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08), - padding: EdgeInsets.all(8.w), - fontSize: 12.f, - onPressed: () { - DialogService dialogService = getIt.get(); - medicalFileViewModel.clearAuthValues(); - dialogService.showAddFamilyFileSheet( - label: "Add Family Member".needTranslation, - message: "Please fill the below field to add a new family member to your profile".needTranslation, - onVerificationPress: () { - medicalFileViewModel.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); - }); - }, + icon: AppAssets.add_icon, + iconSize: 16.w, + iconColor: AppColors.primaryRedColor, + textColor: AppColors.primaryRedColor, + text: "Add Member".needTranslation, + borderWidth: 0.w, + fontWeight: FontWeight.w500, + borderColor: Colors.transparent, + backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08), + padding: EdgeInsets.all(8.w), + fontSize: 12.f, + onPressed: () { + DialogService dialogService = getIt.get(); + medicalFileViewModel.clearAuthValues(); + dialogService.showAddFamilyFileSheet( + label: "Add Family Member".needTranslation, + message: "Please fill the below field to add a new family member to your profile".needTranslation, + onVerificationPress: () { + medicalFileViewModel.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); + }); + }, ) : SizedBox.shrink(), ], diff --git a/pubspec.lock b/pubspec.lock deleted file mode 100644 index 42b828d..0000000 --- a/pubspec.lock +++ /dev/null @@ -1,1985 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _flutterfire_internals: - dependency: transitive - description: - name: _flutterfire_internals - sha256: ff0a84a2734d9e1089f8aedd5c0af0061b82fb94e95260d943404e0ef2134b11 - url: "https://pub.dev" - source: hosted - version: "1.3.59" - amazon_payfort: - dependency: "direct main" - description: - name: amazon_payfort - sha256: "7732df0764aecbb814f910db36d0dca2f696e7e5ea380b49aa3ec62965768b33" - url: "https://pub.dev" - source: hosted - version: "1.1.4" - archive: - dependency: transitive - description: - name: archive - sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" - url: "https://pub.dev" - source: hosted - version: "4.0.7" - args: - dependency: transitive - description: - name: args - sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 - url: "https://pub.dev" - source: hosted - version: "2.7.0" - async: - dependency: transitive - description: - name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" - url: "https://pub.dev" - source: hosted - version: "2.13.0" - audio_session: - dependency: transitive - description: - name: audio_session - sha256: "8f96a7fecbb718cb093070f868b4cdcb8a9b1053dce342ff8ab2fde10eb9afb7" - url: "https://pub.dev" - source: hosted - version: "0.2.2" - auto_size_text: - dependency: "direct main" - description: - name: auto_size_text - sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599" - url: "https://pub.dev" - source: hosted - version: "3.0.0" - barcode_scan2: - dependency: "direct main" - description: - name: barcode_scan2 - sha256: "0f3eb7c0a0c80a0f65d3fa88737544fdb6d27127a4fad566e980e626f3fb76e1" - url: "https://pub.dev" - source: hosted - version: "4.5.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - cached_network_image: - dependency: "direct main" - description: - name: cached_network_image - sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916" - url: "https://pub.dev" - source: hosted - version: "3.4.1" - cached_network_image_platform_interface: - dependency: transitive - description: - name: cached_network_image_platform_interface - sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829" - url: "https://pub.dev" - source: hosted - version: "4.1.1" - cached_network_image_web: - dependency: transitive - description: - name: cached_network_image_web - sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - carp_serializable: - dependency: transitive - description: - name: carp_serializable - sha256: f039f8ea22e9437aef13fe7e9743c3761c76d401288dcb702eadd273c3e4dcef - url: "https://pub.dev" - source: hosted - version: "2.0.1" - characters: - dependency: transitive - description: - name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 - url: "https://pub.dev" - source: hosted - version: "1.4.0" - chewie: - dependency: transitive - description: - name: chewie - sha256: "44bcfc5f0dfd1de290c87c9d86a61308b3282a70b63435d5557cfd60f54a69ca" - url: "https://pub.dev" - source: hosted - version: "1.13.0" - clock: - dependency: transitive - description: - name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b - url: "https://pub.dev" - source: hosted - version: "1.1.2" - collection: - dependency: transitive - description: - name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" - url: "https://pub.dev" - source: hosted - version: "1.19.1" - connectivity_plus: - dependency: "direct main" - description: - name: connectivity_plus - sha256: b5e72753cf63becce2c61fd04dfe0f1c430cc5278b53a1342dc5ad839eab29ec - url: "https://pub.dev" - source: hosted - version: "6.1.5" - connectivity_plus_platform_interface: - dependency: transitive - description: - name: connectivity_plus_platform_interface - sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - convert: - dependency: transitive - description: - name: convert - sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 - url: "https://pub.dev" - source: hosted - version: "3.1.2" - cross_file: - dependency: transitive - description: - name: cross_file - sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" - url: "https://pub.dev" - source: hosted - version: "0.3.4+2" - crypto: - dependency: transitive - description: - name: crypto - sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" - url: "https://pub.dev" - source: hosted - version: "3.0.6" - csslib: - dependency: transitive - description: - name: csslib - sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" - url: "https://pub.dev" - source: hosted - version: "1.0.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 - url: "https://pub.dev" - source: hosted - version: "1.0.8" - dartz: - dependency: "direct main" - description: - name: dartz - sha256: e6acf34ad2e31b1eb00948692468c30ab48ac8250e0f0df661e29f12dd252168 - url: "https://pub.dev" - source: hosted - version: "0.10.1" - dbus: - dependency: transitive - description: - name: dbus - sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" - url: "https://pub.dev" - source: hosted - version: "0.7.11" - device_calendar: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: "5ea5ed9e2bb499c0633383b53103f2920b634755" - url: "https://github.com/bardram/device_calendar" - source: git - version: "4.3.1" - device_info_plus: - dependency: "direct main" - description: - name: device_info_plus - sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a" - url: "https://pub.dev" - source: hosted - version: "11.5.0" - device_info_plus_platform_interface: - dependency: transitive - description: - name: device_info_plus_platform_interface - sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f - url: "https://pub.dev" - source: hosted - version: "7.0.3" - dropdown_search: - dependency: "direct main" - description: - name: dropdown_search - sha256: c29b3e5147a82a06a4a08b3b574c51cb48cc17ad89893d53ee72a6f86643622e - url: "https://pub.dev" - source: hosted - version: "6.0.2" - easy_localization: - dependency: "direct main" - description: - name: easy_localization - sha256: "2ccdf9db8fe4d9c5a75c122e6275674508fd0f0d49c827354967b8afcc56bbed" - url: "https://pub.dev" - source: hosted - version: "3.0.8" - easy_logger: - dependency: transitive - description: - name: easy_logger - sha256: c764a6e024846f33405a2342caf91c62e357c24b02c04dbc712ef232bf30ffb7 - url: "https://pub.dev" - source: hosted - version: "0.0.2" - equatable: - dependency: "direct main" - description: - name: equatable - sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" - url: "https://pub.dev" - source: hosted - version: "2.0.7" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" - url: "https://pub.dev" - source: hosted - version: "1.3.3" - ffi: - dependency: transitive - description: - name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - file: - dependency: transitive - description: - name: file - sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://pub.dev" - source: hosted - version: "7.0.1" - file_picker: - dependency: "direct main" - description: - name: file_picker - sha256: f2d9f173c2c14635cc0e9b14c143c49ef30b4934e8d1d274d6206fcb0086a06f - url: "https://pub.dev" - source: hosted - version: "10.3.3" - file_selector_linux: - dependency: transitive - description: - name: file_selector_linux - sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33" - url: "https://pub.dev" - source: hosted - version: "0.9.3+2" - file_selector_macos: - dependency: transitive - description: - name: file_selector_macos - sha256: "19124ff4a3d8864fdc62072b6a2ef6c222d55a3404fe14893a3c02744907b60c" - url: "https://pub.dev" - source: hosted - version: "0.9.4+4" - file_selector_platform_interface: - dependency: transitive - description: - name: file_selector_platform_interface - sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b - url: "https://pub.dev" - source: hosted - version: "2.6.2" - file_selector_windows: - dependency: transitive - description: - name: file_selector_windows - sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b" - url: "https://pub.dev" - source: hosted - version: "0.9.3+4" - firebase_analytics: - dependency: "direct main" - description: - name: firebase_analytics - sha256: "4f85b161772e1d54a66893ef131c0a44bd9e552efa78b33d5f4f60d2caa5c8a3" - url: "https://pub.dev" - source: hosted - version: "11.6.0" - firebase_analytics_platform_interface: - dependency: transitive - description: - name: firebase_analytics_platform_interface - sha256: a44b6d1155ed5cae7641e3de7163111cfd9f6f6c954ca916dc6a3bdfa86bf845 - url: "https://pub.dev" - source: hosted - version: "4.4.3" - firebase_analytics_web: - dependency: transitive - description: - name: firebase_analytics_web - sha256: c7d1ed1f86ae64215757518af5576ff88341c8ce5741988c05cc3b2e07b0b273 - url: "https://pub.dev" - source: hosted - version: "0.5.10+16" - firebase_core: - dependency: "direct main" - description: - name: firebase_core - sha256: "7be63a3f841fc9663342f7f3a011a42aef6a61066943c90b1c434d79d5c995c5" - url: "https://pub.dev" - source: hosted - version: "3.15.2" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - sha256: "5873a370f0d232918e23a5a6137dbe4c2c47cf017301f4ea02d9d636e52f60f0" - url: "https://pub.dev" - source: hosted - version: "6.0.1" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - sha256: "0ed0dc292e8f9ac50992e2394e9d336a0275b6ae400d64163fdf0a8a8b556c37" - url: "https://pub.dev" - source: hosted - version: "2.24.1" - firebase_messaging: - dependency: "direct main" - description: - name: firebase_messaging - sha256: "60be38574f8b5658e2f22b7e311ff2064bea835c248424a383783464e8e02fcc" - url: "https://pub.dev" - source: hosted - version: "15.2.10" - firebase_messaging_platform_interface: - dependency: transitive - description: - name: firebase_messaging_platform_interface - sha256: "685e1771b3d1f9c8502771ccc9f91485b376ffe16d553533f335b9183ea99754" - url: "https://pub.dev" - source: hosted - version: "4.6.10" - firebase_messaging_web: - dependency: transitive - description: - name: firebase_messaging_web - sha256: "0d1be17bc89ed3ff5001789c92df678b2e963a51b6fa2bdb467532cc9dbed390" - url: "https://pub.dev" - source: hosted - version: "3.10.10" - fixnum: - dependency: transitive - description: - name: fixnum - sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be - url: "https://pub.dev" - source: hosted - version: "1.1.1" - fl_chart: - dependency: "direct main" - description: - name: fl_chart - sha256: "577aeac8ca414c25333334d7c4bb246775234c0e44b38b10a82b559dd4d764e7" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_cache_manager: - dependency: transitive - description: - name: flutter_cache_manager - sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" - url: "https://pub.dev" - source: hosted - version: "3.4.1" - flutter_hooks: - dependency: transitive - description: - name: flutter_hooks - sha256: cde36b12f7188c85286fba9b38cc5a902e7279f36dd676967106c041dc9dde70 - url: "https://pub.dev" - source: hosted - version: "0.20.5" - flutter_inappwebview: - dependency: "direct main" - description: - name: flutter_inappwebview - sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5" - url: "https://pub.dev" - source: hosted - version: "6.1.5" - flutter_inappwebview_android: - dependency: transitive - description: - name: flutter_inappwebview_android - sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba" - url: "https://pub.dev" - source: hosted - version: "1.1.3" - flutter_inappwebview_internal_annotations: - dependency: transitive - description: - name: flutter_inappwebview_internal_annotations - sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - flutter_inappwebview_ios: - dependency: transitive - description: - name: flutter_inappwebview_ios - sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d" - url: "https://pub.dev" - source: hosted - version: "1.1.2" - flutter_inappwebview_macos: - dependency: transitive - description: - name: flutter_inappwebview_macos - sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1 - url: "https://pub.dev" - source: hosted - version: "1.1.2" - flutter_inappwebview_platform_interface: - dependency: transitive - description: - name: flutter_inappwebview_platform_interface - sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500 - url: "https://pub.dev" - source: hosted - version: "1.3.0+1" - flutter_inappwebview_web: - dependency: transitive - description: - name: flutter_inappwebview_web - sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598" - url: "https://pub.dev" - source: hosted - version: "1.1.2" - flutter_inappwebview_windows: - dependency: transitive - description: - name: flutter_inappwebview_windows - sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055" - url: "https://pub.dev" - source: hosted - version: "0.6.0" - flutter_ios_voip_kit_karmm: - dependency: "direct main" - description: - name: flutter_ios_voip_kit_karmm - sha256: "31a445d78aacacdf128a0354efb9f4e424285dfe4c0af3ea872e64f03e6f6bfc" - url: "https://pub.dev" - source: hosted - version: "0.8.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" - url: "https://pub.dev" - source: hosted - version: "5.0.0" - flutter_local_notifications: - dependency: "direct main" - description: - name: flutter_local_notifications - sha256: "7ed76be64e8a7d01dfdf250b8434618e2a028c9dfa2a3c41dc9b531d4b3fc8a5" - url: "https://pub.dev" - source: hosted - version: "19.4.2" - flutter_local_notifications_linux: - dependency: transitive - description: - name: flutter_local_notifications_linux - sha256: e3c277b2daab8e36ac5a6820536668d07e83851aeeb79c446e525a70710770a5 - url: "https://pub.dev" - source: hosted - version: "6.0.0" - flutter_local_notifications_platform_interface: - dependency: transitive - description: - name: flutter_local_notifications_platform_interface - sha256: "277d25d960c15674ce78ca97f57d0bae2ee401c844b6ac80fcd972a9c99d09fe" - url: "https://pub.dev" - source: hosted - version: "9.1.0" - flutter_local_notifications_windows: - dependency: transitive - description: - name: flutter_local_notifications_windows - sha256: "8d658f0d367c48bd420e7cf2d26655e2d1130147bca1eea917e576ca76668aaf" - url: "https://pub.dev" - source: hosted - version: "1.0.3" - flutter_localizations: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_nfc_kit: - dependency: "direct main" - description: - name: flutter_nfc_kit - sha256: "3cc4059626fa672031261512299458dd274de4ccb57a7f0ee0951ddd70a048e5" - url: "https://pub.dev" - source: hosted - version: "3.6.0" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - sha256: b0694b7fb1689b0e6cc193b3f1fcac6423c4f93c74fb20b806c6b6f196db0c31 - url: "https://pub.dev" - source: hosted - version: "2.0.30" - flutter_rating_bar: - dependency: "direct main" - description: - name: flutter_rating_bar - sha256: d2af03469eac832c591a1eba47c91ecc871fe5708e69967073c043b2d775ed93 - url: "https://pub.dev" - source: hosted - version: "4.0.1" - flutter_staggered_animations: - dependency: "direct main" - description: - name: flutter_staggered_animations - sha256: "81d3c816c9bb0dca9e8a5d5454610e21ffb068aedb2bde49d2f8d04f75538351" - url: "https://pub.dev" - source: hosted - version: "1.1.1" - flutter_svg: - dependency: "direct main" - description: - name: flutter_svg - sha256: b9c2ad5872518a27507ab432d1fb97e8813b05f0fc693f9d40fad06d073e0678 - url: "https://pub.dev" - source: hosted - version: "2.2.1" - flutter_swiper_view: - dependency: "direct main" - description: - name: flutter_swiper_view - sha256: "2a165b259e8a4c49d4da5626b967ed42a73dac2d075bd9e266ad8d23b9f01879" - url: "https://pub.dev" - source: hosted - version: "1.1.8" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - flutter_widget_from_html: - dependency: "direct main" - description: - name: flutter_widget_from_html - sha256: "7f1daefcd3009c43c7e7fb37501e6bb752d79aa7bfad0085fb0444da14e89bd0" - url: "https://pub.dev" - source: hosted - version: "0.17.1" - flutter_widget_from_html_core: - dependency: transitive - description: - name: flutter_widget_from_html_core - sha256: "1120ee6ed3509ceff2d55aa6c6cbc7b6b1291434422de2411b5a59364dd6ff03" - url: "https://pub.dev" - source: hosted - version: "0.17.0" - flutter_zoom_videosdk: - dependency: "direct main" - description: - name: flutter_zoom_videosdk - sha256: "22731485fe48472a34ff0c7e787a382f5e1ec662fd89186e58e760974fc2a0cb" - url: "https://pub.dev" - source: hosted - version: "2.3.0" - fluttertoast: - dependency: "direct main" - description: - name: fluttertoast - sha256: "90778fe0497fe3a09166e8cf2e0867310ff434b794526589e77ec03cf08ba8e8" - url: "https://pub.dev" - source: hosted - version: "8.2.14" - fwfh_cached_network_image: - dependency: transitive - description: - name: fwfh_cached_network_image - sha256: "484cb5f8047f02cfac0654fca5832bfa91bb715fd7fc651c04eb7454187c4af8" - url: "https://pub.dev" - source: hosted - version: "0.16.1" - fwfh_chewie: - dependency: transitive - description: - name: fwfh_chewie - sha256: ae74fc26798b0e74f3983f7b851e74c63b9eeb2d3015ecd4b829096b2c3f8818 - url: "https://pub.dev" - source: hosted - version: "0.16.1" - fwfh_just_audio: - dependency: transitive - description: - name: fwfh_just_audio - sha256: dfd622a0dfe049ac647423a2a8afa7f057d9b2b93d92710b624e3d370b1ac69a - url: "https://pub.dev" - source: hosted - version: "0.17.0" - fwfh_svg: - dependency: transitive - description: - name: fwfh_svg - sha256: "2e6bb241179eeeb1a7941e05c8c923b05d332d36a9085233e7bf110ea7deb915" - url: "https://pub.dev" - source: hosted - version: "0.16.1" - fwfh_url_launcher: - dependency: transitive - description: - name: fwfh_url_launcher - sha256: c38aa8fb373fda3a89b951fa260b539f623f6edb45eee7874cb8b492471af881 - url: "https://pub.dev" - source: hosted - version: "0.16.1" - fwfh_webview: - dependency: transitive - description: - name: fwfh_webview - sha256: f71b0aa16e15d82f3c017f33560201ff5ae04e91e970cab5d12d3bcf970b870c - url: "https://pub.dev" - source: hosted - version: "0.15.6" - geoclue: - dependency: transitive - description: - name: geoclue - sha256: c2a998c77474fc57aa00c6baa2928e58f4b267649057a1c76738656e9dbd2a7f - url: "https://pub.dev" - source: hosted - version: "0.1.1" - geolocator: - dependency: "direct main" - description: - name: geolocator - sha256: "79939537046c9025be47ec645f35c8090ecadb6fe98eba146a0d25e8c1357516" - url: "https://pub.dev" - source: hosted - version: "14.0.2" - geolocator_android: - dependency: transitive - description: - name: geolocator_android - sha256: "179c3cb66dfa674fc9ccbf2be872a02658724d1c067634e2c427cf6df7df901a" - url: "https://pub.dev" - source: hosted - version: "5.0.2" - geolocator_apple: - dependency: transitive - description: - name: geolocator_apple - sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22 - url: "https://pub.dev" - source: hosted - version: "2.3.13" - geolocator_linux: - dependency: transitive - description: - name: geolocator_linux - sha256: c4e966f0a7a87e70049eac7a2617f9e16fd4c585a26e4330bdfc3a71e6a721f3 - url: "https://pub.dev" - source: hosted - version: "0.2.3" - geolocator_platform_interface: - dependency: transitive - description: - name: geolocator_platform_interface - sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67" - url: "https://pub.dev" - source: hosted - version: "4.2.6" - geolocator_web: - dependency: transitive - description: - name: geolocator_web - sha256: b1ae9bdfd90f861fde8fd4f209c37b953d65e92823cb73c7dee1fa021b06f172 - url: "https://pub.dev" - source: hosted - version: "4.1.3" - geolocator_windows: - dependency: transitive - description: - name: geolocator_windows - sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6" - url: "https://pub.dev" - source: hosted - version: "0.2.5" - get_it: - dependency: "direct main" - description: - name: get_it - sha256: a4292e7cf67193f8e7c1258203104eb2a51ec8b3a04baa14695f4064c144297b - url: "https://pub.dev" - source: hosted - version: "8.2.0" - gms_check: - dependency: "direct main" - description: - name: gms_check - sha256: b3fc08fd41da233f9761f9981303346aa9778b4802e90ce9bd8122674fcca6f0 - url: "https://pub.dev" - source: hosted - version: "1.0.4" - google_api_availability: - dependency: "direct main" - description: - name: google_api_availability - sha256: "2ffdc91e1e0cf4e7974fef6c2988a24cefa81f03526ff04b694df6dc0fcbca03" - url: "https://pub.dev" - source: hosted - version: "5.0.1" - google_api_availability_android: - dependency: transitive - description: - name: google_api_availability_android - sha256: "4794147f43a8f3eee6b514d3ae30dbe6f7b9048cae8cd2a74cb4055cd28d74a8" - url: "https://pub.dev" - source: hosted - version: "1.1.1" - google_api_availability_platform_interface: - dependency: transitive - description: - name: google_api_availability_platform_interface - sha256: "65b7da62fe5b582bb3d508628ad827d36d890710ea274766a992a56fa5420da6" - url: "https://pub.dev" - source: hosted - version: "1.0.1" - google_maps: - dependency: transitive - description: - name: google_maps - sha256: "5d410c32112d7c6eb7858d359275b2aa04778eed3e36c745aeae905fb2fa6468" - url: "https://pub.dev" - source: hosted - version: "8.2.0" - google_maps_flutter: - dependency: "direct main" - description: - name: google_maps_flutter - sha256: c389e16fafc04b37a4105e0757ecb9d59806026cee72f408f1ba68811d01bfe6 - url: "https://pub.dev" - source: hosted - version: "2.13.1" - google_maps_flutter_android: - dependency: transitive - description: - name: google_maps_flutter_android - sha256: a6c9d43f6a944ff4bae5c3deb34817970ac3d591dcd7f5bd2ea450ab9e9c514a - url: "https://pub.dev" - source: hosted - version: "2.18.2" - google_maps_flutter_ios: - dependency: transitive - description: - name: google_maps_flutter_ios - sha256: ca02463b19a9abc7d31fcaf22631d021d647107467f741b917a69fa26659fd75 - url: "https://pub.dev" - source: hosted - version: "2.15.5" - google_maps_flutter_platform_interface: - dependency: transitive - description: - name: google_maps_flutter_platform_interface - sha256: f4b9b44f7b12a1f6707ffc79d082738e0b7e194bf728ee61d2b3cdf5fdf16081 - url: "https://pub.dev" - source: hosted - version: "2.14.0" - google_maps_flutter_web: - dependency: transitive - description: - name: google_maps_flutter_web - sha256: "53e5dbf73ff04153acc55a038248706967c21d5b6ef6657a57fce2be73c2895a" - url: "https://pub.dev" - source: hosted - version: "0.5.14+2" - gsettings: - dependency: transitive - description: - name: gsettings - sha256: "1b0ce661f5436d2db1e51f3c4295a49849f03d304003a7ba177d01e3a858249c" - url: "https://pub.dev" - source: hosted - version: "0.2.8" - health: - dependency: "direct main" - description: - name: health - sha256: "320633022fb2423178baa66508001c4ca5aee5806ffa2c913e66488081e9fd47" - url: "https://pub.dev" - source: hosted - version: "13.1.4" - hijri_gregorian_calendar: - dependency: "direct main" - description: - name: hijri_gregorian_calendar - sha256: aecdbe3c9365fac55f17b5e1f24086a81999b1e5c9372cb08888bfbe61e07fa1 - url: "https://pub.dev" - source: hosted - version: "0.1.1" - html: - dependency: transitive - description: - name: html - sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" - url: "https://pub.dev" - source: hosted - version: "0.15.6" - http: - dependency: "direct main" - description: - name: http - sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 - url: "https://pub.dev" - source: hosted - version: "1.5.0" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" - url: "https://pub.dev" - source: hosted - version: "4.1.2" - huawei_location: - dependency: "direct main" - description: - name: huawei_location - sha256: "3100d6b2b11df56481b8deade71baa84970e0bae0ade6ec56407be2b036af355" - url: "https://pub.dev" - source: hosted - version: "6.14.2+301" - huawei_map: - dependency: "direct main" - description: - path: flutter-hms-map - ref: HEAD - resolved-ref: "9a16541e4016e3bf58a2571e6aa658a4751af399" - url: "https://github.com/fleoparra/hms-flutter-plugin.git" - source: git - version: "6.11.2+303" - image_picker: - dependency: "direct main" - description: - name: image_picker - sha256: "736eb56a911cf24d1859315ad09ddec0b66104bc41a7f8c5b96b4e2620cf5041" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - image_picker_android: - dependency: transitive - description: - name: image_picker_android - sha256: "8dfe08ea7fcf7467dbaf6889e72eebd5e0d6711caae201fdac780eb45232cd02" - url: "https://pub.dev" - source: hosted - version: "0.8.13+3" - image_picker_for_web: - dependency: transitive - description: - name: image_picker_for_web - sha256: "40c2a6a0da15556dc0f8e38a3246064a971a9f512386c3339b89f76db87269b6" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - image_picker_ios: - dependency: transitive - description: - name: image_picker_ios - sha256: eb06fe30bab4c4497bad449b66448f50edcc695f1c59408e78aa3a8059eb8f0e - url: "https://pub.dev" - source: hosted - version: "0.8.13" - image_picker_linux: - dependency: transitive - description: - name: image_picker_linux - sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4" - url: "https://pub.dev" - source: hosted - version: "0.2.2" - image_picker_macos: - dependency: transitive - description: - name: image_picker_macos - sha256: d58cd9d67793d52beefd6585b12050af0a7663c0c2a6ece0fb110a35d6955e04 - url: "https://pub.dev" - source: hosted - version: "0.2.2" - image_picker_platform_interface: - dependency: transitive - description: - name: image_picker_platform_interface - sha256: "9f143b0dba3e459553209e20cc425c9801af48e6dfa4f01a0fcf927be3f41665" - url: "https://pub.dev" - source: hosted - version: "2.11.0" - image_picker_windows: - dependency: transitive - description: - name: image_picker_windows - sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae - url: "https://pub.dev" - source: hosted - version: "0.2.2" - intl: - dependency: "direct main" - description: - name: intl - sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" - url: "https://pub.dev" - source: hosted - version: "0.20.2" - jiffy: - dependency: "direct main" - description: - name: jiffy - sha256: "9bafbfe6d97587048bf449165e050029e716a12438f54a3d39e7e3a256decdac" - url: "https://pub.dev" - source: hosted - version: "6.4.3" - json_annotation: - dependency: transitive - description: - name: json_annotation - sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" - url: "https://pub.dev" - source: hosted - version: "4.9.0" - just_audio: - dependency: "direct main" - description: - name: just_audio - sha256: "9694e4734f515f2a052493d1d7e0d6de219ee0427c7c29492e246ff32a219908" - url: "https://pub.dev" - source: hosted - version: "0.10.5" - just_audio_platform_interface: - dependency: transitive - description: - name: just_audio_platform_interface - sha256: "2532c8d6702528824445921c5ff10548b518b13f808c2e34c2fd54793b999a6a" - url: "https://pub.dev" - source: hosted - version: "4.6.0" - just_audio_web: - dependency: transitive - description: - name: just_audio_web - sha256: "6ba8a2a7e87d57d32f0f7b42856ade3d6a9fbe0f1a11fabae0a4f00bb73f0663" - url: "https://pub.dev" - source: hosted - version: "0.4.16" - keyboard_actions: - dependency: "direct main" - description: - name: keyboard_actions - sha256: "31e0ab2a706ac8f58887efa60efc1f19aecdf37d8ab0f665a0f156d1fbeab650" - url: "https://pub.dev" - source: hosted - version: "4.2.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" - url: "https://pub.dev" - source: hosted - version: "11.0.2" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" - url: "https://pub.dev" - source: hosted - version: "3.0.10" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - lints: - dependency: transitive - description: - name: lints - sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 - url: "https://pub.dev" - source: hosted - version: "5.1.1" - local_auth: - dependency: "direct main" - description: - name: local_auth - sha256: "434d854cf478f17f12ab29a76a02b3067f86a63a6d6c4eb8fbfdcfe4879c1b7b" - url: "https://pub.dev" - source: hosted - version: "2.3.0" - local_auth_android: - dependency: transitive - description: - name: local_auth_android - sha256: "1ee0e63fb8b5c6fa286796b5fb1570d256857c2f4a262127e728b36b80a570cf" - url: "https://pub.dev" - source: hosted - version: "1.0.53" - local_auth_darwin: - dependency: transitive - description: - name: local_auth_darwin - sha256: "699873970067a40ef2f2c09b4c72eb1cfef64224ef041b3df9fdc5c4c1f91f49" - url: "https://pub.dev" - source: hosted - version: "1.6.1" - local_auth_platform_interface: - dependency: transitive - description: - name: local_auth_platform_interface - sha256: "1b842ff177a7068442eae093b64abe3592f816afd2a533c0ebcdbe40f9d2075a" - url: "https://pub.dev" - source: hosted - version: "1.0.10" - local_auth_windows: - dependency: transitive - description: - name: local_auth_windows - sha256: bc4e66a29b0fdf751aafbec923b5bed7ad6ed3614875d8151afe2578520b2ab5 - url: "https://pub.dev" - source: hosted - version: "1.0.11" - location: - dependency: "direct main" - description: - name: location - sha256: b080053c181c7d152c43dd576eec6436c40e25f326933051c330da563ddd5333 - url: "https://pub.dev" - source: hosted - version: "8.0.1" - location_platform_interface: - dependency: transitive - description: - name: location_platform_interface - sha256: ca8700bb3f6b1e8b2afbd86bd78b2280d116c613ca7bfa1d4d7b64eba357d749 - url: "https://pub.dev" - source: hosted - version: "6.0.1" - location_web: - dependency: transitive - description: - name: location_web - sha256: b8e3add5efe0d65c5e692b7a135d80a4015c580d3ea646fa71973e97668dd868 - url: "https://pub.dev" - source: hosted - version: "6.0.1" - logger: - dependency: "direct main" - description: - name: logger - sha256: "55d6c23a6c15db14920e037fe7e0dc32e7cdaf3b64b4b25df2d541b5b6b81c0c" - url: "https://pub.dev" - source: hosted - version: "2.6.1" - logging: - dependency: transitive - description: - name: logging - sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 - url: "https://pub.dev" - source: hosted - version: "1.3.0" - lottie: - dependency: "direct main" - description: - name: lottie - sha256: "8ae0be46dbd9e19641791dc12ee480d34e1fd3f84c749adc05f3ad9342b71b95" - url: "https://pub.dev" - source: hosted - version: "3.3.2" - manage_calendar_events: - dependency: "direct main" - description: - name: manage_calendar_events - sha256: f17600fcb7dc7047120c185993045e493d686930237b4e3c2689c26a64513d66 - url: "https://pub.dev" - source: hosted - version: "2.0.3" - maps_launcher: - dependency: "direct main" - description: - name: maps_launcher - sha256: dac4c609720211fa6336b5903d917fe45e545c6b5665978efc3db2a3f436b1ae - url: "https://pub.dev" - source: hosted - version: "3.0.0+1" - matcher: - dependency: transitive - description: - name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 - url: "https://pub.dev" - source: hosted - version: "0.12.17" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" - source: hosted - version: "0.11.1" - meta: - dependency: transitive - description: - name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c - url: "https://pub.dev" - source: hosted - version: "1.16.0" - mime: - dependency: transitive - description: - name: mime - sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" - url: "https://pub.dev" - source: hosted - version: "2.0.0" - ndef: - dependency: transitive - description: - name: ndef - sha256: "5083507cff4bb823b2a198a27ea2c70c4d6bc27a97b66097d966a250e1615d54" - url: "https://pub.dev" - source: hosted - version: "0.3.4" - nested: - dependency: transitive - description: - name: nested - sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - network_info_plus: - dependency: "direct main" - description: - name: network_info_plus - sha256: f926b2ba86aa0086a0dfbb9e5072089bc213d854135c1712f1d29fc89ba3c877 - url: "https://pub.dev" - source: hosted - version: "6.1.4" - network_info_plus_platform_interface: - dependency: transitive - description: - name: network_info_plus_platform_interface - sha256: "7e7496a8a9d8136859b8881affc613c4a21304afeb6c324bcefc4bd0aff6b94b" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - nm: - dependency: transitive - description: - name: nm - sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" - url: "https://pub.dev" - source: hosted - version: "0.5.0" - octo_image: - dependency: transitive - description: - name: octo_image - sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - open_filex: - dependency: "direct main" - description: - name: open_filex - sha256: "9976da61b6a72302cf3b1efbce259200cd40232643a467aac7370addf94d6900" - url: "https://pub.dev" - source: hosted - version: "4.7.0" - package_info_plus: - dependency: transitive - description: - name: package_info_plus - sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968" - url: "https://pub.dev" - source: hosted - version: "8.3.1" - package_info_plus_platform_interface: - dependency: transitive - description: - name: package_info_plus_platform_interface - sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - path: - dependency: transitive - description: - name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://pub.dev" - source: hosted - version: "1.9.1" - path_parsing: - dependency: transitive - description: - name: path_parsing - sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - path_provider: - dependency: "direct main" - description: - name: path_provider - sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" - url: "https://pub.dev" - source: hosted - version: "2.1.5" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db" - url: "https://pub.dev" - source: hosted - version: "2.2.18" - path_provider_foundation: - dependency: transitive - description: - name: path_provider_foundation - sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd" - url: "https://pub.dev" - source: hosted - version: "2.4.2" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 - url: "https://pub.dev" - source: hosted - version: "2.2.1" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 - url: "https://pub.dev" - source: hosted - version: "2.3.0" - permission_handler: - dependency: "direct main" - description: - name: permission_handler - sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1 - url: "https://pub.dev" - source: hosted - version: "12.0.1" - permission_handler_android: - dependency: transitive - description: - name: permission_handler_android - sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6" - url: "https://pub.dev" - source: hosted - version: "13.0.1" - permission_handler_apple: - dependency: transitive - description: - name: permission_handler_apple - sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023 - url: "https://pub.dev" - source: hosted - version: "9.4.7" - permission_handler_html: - dependency: transitive - description: - name: permission_handler_html - sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" - url: "https://pub.dev" - source: hosted - version: "0.1.3+5" - permission_handler_platform_interface: - dependency: transitive - description: - name: permission_handler_platform_interface - sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 - url: "https://pub.dev" - source: hosted - version: "4.3.0" - permission_handler_windows: - dependency: transitive - description: - name: permission_handler_windows - sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" - url: "https://pub.dev" - source: hosted - version: "0.2.1" - petitparser: - dependency: transitive - description: - name: petitparser - sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" - url: "https://pub.dev" - source: hosted - version: "7.0.1" - platform: - dependency: transitive - description: - name: platform - sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" - url: "https://pub.dev" - source: hosted - version: "3.1.6" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.dev" - source: hosted - version: "2.1.8" - posix: - dependency: transitive - description: - name: posix - sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" - url: "https://pub.dev" - source: hosted - version: "6.0.3" - protobuf: - dependency: transitive - description: - name: protobuf - sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - provider: - dependency: "direct main" - description: - name: provider - sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" - url: "https://pub.dev" - source: hosted - version: "6.1.5+1" - quiver: - dependency: transitive - description: - name: quiver - sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 - url: "https://pub.dev" - source: hosted - version: "3.2.2" - rrule: - dependency: transitive - description: - name: rrule - sha256: b7425410c594d4b6717c9f17ec8ef83c9d1ff2e513c428a135b5924fc2e8e045 - url: "https://pub.dev" - source: hosted - version: "0.2.17" - rxdart: - dependency: transitive - description: - name: rxdart - sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" - url: "https://pub.dev" - source: hosted - version: "0.28.0" - sanitize_html: - dependency: transitive - description: - name: sanitize_html - sha256: "12669c4a913688a26555323fb9cec373d8f9fbe091f2d01c40c723b33caa8989" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - share_plus: - dependency: "direct main" - description: - name: share_plus - sha256: d7dc0630a923883c6328ca31b89aa682bacbf2f8304162d29f7c6aaff03a27a1 - url: "https://pub.dev" - source: hosted - version: "11.1.0" - share_plus_platform_interface: - dependency: transitive - description: - name: share_plus_platform_interface - sha256: "88023e53a13429bd65d8e85e11a9b484f49d4c190abbd96c7932b74d6927cc9a" - url: "https://pub.dev" - source: hosted - version: "6.1.0" - shared_preferences: - dependency: "direct main" - description: - name: shared_preferences - sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" - url: "https://pub.dev" - source: hosted - version: "2.5.3" - shared_preferences_android: - dependency: transitive - description: - name: shared_preferences_android - sha256: bd14436108211b0d4ee5038689a56d4ae3620fd72fd6036e113bf1345bc74d9e - url: "https://pub.dev" - source: hosted - version: "2.4.13" - shared_preferences_foundation: - dependency: transitive - description: - name: shared_preferences_foundation - sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" - url: "https://pub.dev" - source: hosted - version: "2.5.4" - shared_preferences_linux: - dependency: transitive - description: - name: shared_preferences_linux - sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 - url: "https://pub.dev" - source: hosted - version: "2.4.3" - shared_preferences_windows: - dependency: transitive - description: - name: shared_preferences_windows - sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - shimmer: - dependency: "direct main" - description: - name: shimmer - sha256: "5f88c883a22e9f9f299e5ba0e4f7e6054857224976a5d9f839d4ebdc94a14ac9" - url: "https://pub.dev" - source: hosted - version: "3.0.0" - sizer: - dependency: "direct main" - description: - name: sizer - sha256: "9963c89e4d30d7c2108de3eafc0a7e6a4a8009799376ea6be5ef0a9ad87cfbad" - url: "https://pub.dev" - source: hosted - version: "3.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - smooth_corner: - dependency: "direct main" - description: - name: smooth_corner - sha256: "112d7331f82ead81ec870c5d1eb0624f2e7e367eccd166c2fffe4c11d4f87c4f" - url: "https://pub.dev" - source: hosted - version: "1.1.1" - sms_otp_auto_verify: - dependency: "direct main" - description: - name: sms_otp_auto_verify - sha256: ee02af0d6b81d386ef70d7d0317a1929bc0b4a3a30a451284450bbcf6901ba1a - url: "https://pub.dev" - source: hosted - version: "2.2.0" - source_span: - dependency: transitive - description: - name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" - url: "https://pub.dev" - source: hosted - version: "1.10.1" - sprintf: - dependency: transitive - description: - name: sprintf - sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" - url: "https://pub.dev" - source: hosted - version: "7.0.0" - sqflite: - dependency: transitive - description: - name: sqflite - sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03 - url: "https://pub.dev" - source: hosted - version: "2.4.2" - sqflite_android: - dependency: transitive - description: - name: sqflite_android - sha256: ecd684501ebc2ae9a83536e8b15731642b9570dc8623e0073d227d0ee2bfea88 - url: "https://pub.dev" - source: hosted - version: "2.4.2+2" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6" - url: "https://pub.dev" - source: hosted - version: "2.5.6" - sqflite_darwin: - dependency: transitive - description: - name: sqflite_darwin - sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3" - url: "https://pub.dev" - source: hosted - version: "2.4.2" - sqflite_platform_interface: - dependency: transitive - description: - name: sqflite_platform_interface - sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920" - url: "https://pub.dev" - source: hosted - version: "2.4.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" - url: "https://pub.dev" - source: hosted - version: "1.12.1" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - stream_transform: - dependency: transitive - description: - name: stream_transform - sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 - url: "https://pub.dev" - source: hosted - version: "2.1.1" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" - url: "https://pub.dev" - source: hosted - version: "1.4.1" - syncfusion_flutter_calendar: - dependency: "direct main" - description: - name: syncfusion_flutter_calendar - sha256: "8e8a4eef01d6a82ae2c17e76d497ff289ded274de014c9f471ffabc12d1e2e71" - url: "https://pub.dev" - source: hosted - version: "30.2.7" - syncfusion_flutter_core: - dependency: transitive - description: - name: syncfusion_flutter_core - sha256: bfd026c0f9822b49ff26fed11cd3334519acb6a6ad4b0c81d9cd18df6af1c4c0 - url: "https://pub.dev" - source: hosted - version: "30.2.7" - syncfusion_flutter_datepicker: - dependency: transitive - description: - name: syncfusion_flutter_datepicker - sha256: b5f35cc808e91b229d41613efe71dadab1549a35bfd493f922fc06ccc2fe908c - url: "https://pub.dev" - source: hosted - version: "30.2.7" - syncfusion_localizations: - dependency: transitive - description: - name: syncfusion_localizations - sha256: bb32b07879b4c1dee5d4c8ad1c57343a4fdae55d65a87f492727c11b68f23164 - url: "https://pub.dev" - source: hosted - version: "30.2.7" - synchronized: - dependency: transitive - description: - name: synchronized - sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 - url: "https://pub.dev" - source: hosted - version: "3.4.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" - url: "https://pub.dev" - source: hosted - version: "1.2.2" - test_api: - dependency: transitive - description: - name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" - url: "https://pub.dev" - source: hosted - version: "0.7.6" - time: - dependency: transitive - description: - name: time - sha256: "370572cf5d1e58adcb3e354c47515da3f7469dac3a95b447117e728e7be6f461" - url: "https://pub.dev" - source: hosted - version: "2.1.5" - timezone: - dependency: transitive - description: - name: timezone - sha256: dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1 - url: "https://pub.dev" - source: hosted - version: "0.10.1" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://pub.dev" - source: hosted - version: "1.4.0" - url_launcher: - dependency: "direct main" - description: - name: url_launcher - sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 - url: "https://pub.dev" - source: hosted - version: "6.3.2" - url_launcher_android: - dependency: transitive - description: - name: url_launcher_android - sha256: "199bc33e746088546a39cc5f36bac5a278c5e53b40cb3196f99e7345fdcfae6b" - url: "https://pub.dev" - source: hosted - version: "6.3.22" - url_launcher_ios: - dependency: transitive - description: - name: url_launcher_ios - sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7 - url: "https://pub.dev" - source: hosted - version: "6.3.4" - url_launcher_linux: - dependency: transitive - description: - name: url_launcher_linux - sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - url_launcher_macos: - dependency: transitive - description: - name: url_launcher_macos - sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f - url: "https://pub.dev" - source: hosted - version: "3.2.3" - url_launcher_platform_interface: - dependency: transitive - description: - name: url_launcher_platform_interface - sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" - url: "https://pub.dev" - source: hosted - version: "2.3.2" - url_launcher_web: - dependency: transitive - description: - name: url_launcher_web - sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - url_launcher_windows: - dependency: transitive - description: - name: url_launcher_windows - sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" - url: "https://pub.dev" - source: hosted - version: "3.1.4" - uuid: - dependency: "direct main" - description: - name: uuid - sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff - url: "https://pub.dev" - source: hosted - version: "4.5.1" - vector_graphics: - dependency: transitive - description: - name: vector_graphics - sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6 - url: "https://pub.dev" - source: hosted - version: "1.1.19" - vector_graphics_codec: - dependency: transitive - description: - name: vector_graphics_codec - sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146" - url: "https://pub.dev" - source: hosted - version: "1.1.13" - vector_graphics_compiler: - dependency: transitive - description: - name: vector_graphics_compiler - sha256: d354a7ec6931e6047785f4db12a1f61ec3d43b207fc0790f863818543f8ff0dc - url: "https://pub.dev" - source: hosted - version: "1.1.19" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b - url: "https://pub.dev" - source: hosted - version: "2.2.0" - video_player: - dependency: transitive - description: - name: video_player - sha256: "0d55b1f1a31e5ad4c4967bfaa8ade0240b07d20ee4af1dfef5f531056512961a" - url: "https://pub.dev" - source: hosted - version: "2.10.0" - video_player_android: - dependency: transitive - description: - name: video_player_android - sha256: "6cfe0b1e102522eda1e139b82bf00602181c5844fd2885340f595fb213d74842" - url: "https://pub.dev" - source: hosted - version: "2.8.14" - video_player_avfoundation: - dependency: transitive - description: - name: video_player_avfoundation - sha256: f9a780aac57802b2892f93787e5ea53b5f43cc57dc107bee9436458365be71cd - url: "https://pub.dev" - source: hosted - version: "2.8.4" - video_player_platform_interface: - dependency: transitive - description: - name: video_player_platform_interface - sha256: cf2a1d29a284db648fd66cbd18aacc157f9862d77d2cc790f6f9678a46c1db5a - url: "https://pub.dev" - source: hosted - version: "6.4.0" - video_player_web: - dependency: transitive - description: - name: video_player_web - sha256: "9f3c00be2ef9b76a95d94ac5119fb843dca6f2c69e6c9968f6f2b6c9e7afbdeb" - url: "https://pub.dev" - source: hosted - version: "2.4.0" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" - url: "https://pub.dev" - source: hosted - version: "15.0.2" - wakelock_plus: - dependency: transitive - description: - name: wakelock_plus - sha256: "61713aa82b7f85c21c9f4cd0a148abd75f38a74ec645fcb1e446f882c82fd09b" - url: "https://pub.dev" - source: hosted - version: "1.3.3" - wakelock_plus_platform_interface: - dependency: transitive - description: - name: wakelock_plus_platform_interface - sha256: "036deb14cd62f558ca3b73006d52ce049fabcdcb2eddfe0bf0fe4e8a943b5cf2" - url: "https://pub.dev" - source: hosted - version: "1.3.0" - web: - dependency: "direct main" - description: - name: web - sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" - url: "https://pub.dev" - source: hosted - version: "1.1.1" - webview_flutter: - dependency: transitive - description: - name: webview_flutter - sha256: c3e4fe614b1c814950ad07186007eff2f2e5dd2935eba7b9a9a1af8e5885f1ba - url: "https://pub.dev" - source: hosted - version: "4.13.0" - webview_flutter_android: - dependency: transitive - description: - name: webview_flutter_android - sha256: "21507ea5a326ceeba4d29dea19e37d92d53d9959cfc746317b9f9f7a57418d87" - url: "https://pub.dev" - source: hosted - version: "4.10.3" - webview_flutter_platform_interface: - dependency: transitive - description: - name: webview_flutter_platform_interface - sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0" - url: "https://pub.dev" - source: hosted - version: "2.14.0" - webview_flutter_wkwebview: - dependency: transitive - description: - name: webview_flutter_wkwebview - sha256: fea63576b3b7e02b2df8b78ba92b48ed66caec2bb041e9a0b1cbd586d5d80bfd - url: "https://pub.dev" - source: hosted - version: "3.23.1" - win32: - dependency: transitive - description: - name: win32 - sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" - url: "https://pub.dev" - source: hosted - version: "5.14.0" - win32_registry: - dependency: transitive - description: - name: win32_registry - sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - xml: - dependency: transitive - description: - name: xml - sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" - url: "https://pub.dev" - source: hosted - version: "6.6.1" -sdks: - dart: ">=3.9.0 <4.0.0" - flutter: ">=3.35.0" From 99282f34e330460fcaf4f93efe68f45253d878bc Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 20 Jan 2026 10:55:23 +0300 Subject: [PATCH 04/10] Added language change option in landing page --- assets/images/svg/ar_lang_icon.svg | 3 +++ assets/images/svg/en_lang_icon.svg | 3 +++ lib/core/app_assets.dart | 3 +++ .../authentication_view_model.dart | 4 ++-- .../appointments/my_appointments_page.dart | 2 +- .../book_appointment/select_doctor_page.dart | 2 +- lib/presentation/home/landing_page.dart | 17 ++++++++++++----- 7 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 assets/images/svg/ar_lang_icon.svg create mode 100644 assets/images/svg/en_lang_icon.svg diff --git a/assets/images/svg/ar_lang_icon.svg b/assets/images/svg/ar_lang_icon.svg new file mode 100644 index 0000000..d1c2be0 --- /dev/null +++ b/assets/images/svg/ar_lang_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/en_lang_icon.svg b/assets/images/svg/en_lang_icon.svg new file mode 100644 index 0000000..fa1c143 --- /dev/null +++ b/assets/images/svg/en_lang_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index 26da9fa..f6fd88a 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -305,6 +305,9 @@ class AppAssets { static const String bloodPressure = '$svgBasePath/blood_pressure.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 // static const String hmgLogo = '$pngBasePath/hmg_logo.png'; static const String liveCareService = '$pngBasePath/livecare_service.png'; diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index 6379456..0c4ba09 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -571,7 +571,7 @@ class AuthenticationViewModel extends ChangeNotifier { MedicalFileViewModel medicalVm = getIt(); if (!_appState.getIsChildLoggedIn) { await medicalVm.getFamilyFiles(status: 0); - await medicalVm.getAllPendingRecordsByResponseId(); + // await medicalVm.getAllPendingRecordsByResponseId(); _navigationService.replaceAllRoutesAndNavigateToLanding(); } } else { @@ -610,7 +610,7 @@ class AuthenticationViewModel extends ChangeNotifier { MedicalFileViewModel medicalVm = getIt(); insertPatientIMEIData(loginTypeEnum.toInt); medicalVm.getFamilyFiles(status: 0); //TODO: Remove status: 1 by Aamir Need to Discuss With Sultan - medicalVm.getAllPendingRecordsByResponseId(); + // medicalVm.getAllPendingRecordsByResponseId(); } await clearDefaultInputValues(); if (isUserAgreedBefore) { diff --git a/lib/presentation/appointments/my_appointments_page.dart b/lib/presentation/appointments/my_appointments_page.dart index 1209467..c9e7048 100644 --- a/lib/presentation/appointments/my_appointments_page.dart +++ b/lib/presentation/appointments/my_appointments_page.dart @@ -155,7 +155,7 @@ class _MyAppointmentsPageState extends State { isLoading: true, isFromHomePage: false, ), - ).paddingSymmetrical(24.h, 0.h) + ) : filteredAppointmentList.isNotEmpty ? AnimationConfiguration.staggeredList( position: index, diff --git a/lib/presentation/book_appointment/select_doctor_page.dart b/lib/presentation/book_appointment/select_doctor_page.dart index e57ed51..3723bee 100644 --- a/lib/presentation/book_appointment/select_doctor_page.dart +++ b/lib/presentation/book_appointment/select_doctor_page.dart @@ -178,7 +178,7 @@ class _SelectDoctorPageState extends State { children: [ LocaleKeys.nearestAppo.tr(context: context).toText13(isBold: true), 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(), diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index f8cd159..8267990 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -198,10 +198,11 @@ class _LandingPageState extends State { mainAxisSize: MainAxisSize.min, spacing: 12.h, children: [ - Stack(children: [ - Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 18.h, width: 18.h).onPress(() async { - if (appState.isAuthenticated) { - notificationsViewModel.setNotificationStatusID(2); + appState.isAuthenticated + ? Stack(children: [ + Utils.buildSvgWithAssets(icon: AppAssets.bell, height: 18.h, width: 18.h).onPress(() async { + if (appState.isAuthenticated) { + notificationsViewModel.setNotificationStatusID(2); notificationsViewModel.getAllNotifications(); Navigator.of(context).push( CustomPageRoute( @@ -236,7 +237,8 @@ class _LandingPageState extends State { ), ) : SizedBox.shrink(), - ]), + ]) + : SizedBox.shrink(), Utils.buildSvgWithAssets(icon: AppAssets.indoor_nav_icon, height: 18.h, width: 18.h).onPress(() { openIndoorNavigationBottomSheet(context); }), @@ -249,6 +251,11 @@ class _LandingPageState extends State { 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() ], ); }), From 6faca94b89558c2d793d95174ed92b6675e50c33 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 20 Jan 2026 15:15:31 +0300 Subject: [PATCH 05/10] updates --- assets/langs/ar-SA.json | 13 +++- assets/langs/en-US.json | 10 +++- .../immediate_livecare_view_model.dart | 6 +- .../my_appointments_view_model.dart | 2 + lib/generated/locale_keys.g.dart | 6 ++ .../home/data/landing_page_data.dart | 60 +++++++++---------- lib/presentation/home/landing_page.dart | 4 +- .../home/widgets/large_service_card.dart | 7 +-- .../home/widgets/small_service_card.dart | 4 +- .../medical_file/medical_file_page.dart | 27 +++++---- .../vital_sign/vital_sign_page.dart | 52 ++++++++-------- lib/widgets/buttons/custom_button.dart | 2 +- lib/widgets/expandable_list_widget.dart | 6 +- lib/widgets/input_widget.dart | 4 +- 14 files changed, 115 insertions(+), 88 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 6f25fb5..e0b0d8a 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1500,12 +1500,19 @@ "pleaseWaitYouWillBeCalledForVitalSigns": "يرجى الانتظار! سيتم استدعاؤك لقياس العلامات الحيوية", "pleaseVisitRoomForVitalSigns": "يرجى زيارة الغرفة {roomNumber} لقياس العلامات الحيوية", "pleaseVisitRoomToTheDoctor": "يرجى زيارة الغرفة {roomNumber} لمقابلة الطبيب", - - "erOnlineCheckInRequest": "ER Online Check-In Request", + "erOnlineCheckInRequest": "طلب تسجيل الوصول عبر الإنترنت لقسم الطوارئ", "indoor": "داخلي", "navigation": "الملاحة", "health": "الصحة", "calculators": "الحاسبات", "converters": "المحولات", - "guide": "الدليل" + "guide": "الدليل", + "liveCareServiceDesc": "احصل على استشارة طبية من طبيب متخصص عبر مكالمة فيديو", + "bloodGroup": "فصيلة الدم: {bloodType}", + "medicalServices": "الخدمات الطبية", + "insuranceAndPayments": "التأمين والمدفوعات", + "trackerAndOthers": "المتتبع وأخرى", + "bmi": "مؤشر كتلة الجسم" + + } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index cec6bf3..fa59b19 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1497,5 +1497,13 @@ "health": "Health", "calculators": "Calculators", "converters": "Converters", - "guide": "Guide" + "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" + + } diff --git a/lib/features/immediate_livecare/immediate_livecare_view_model.dart b/lib/features/immediate_livecare/immediate_livecare_view_model.dart index 1baa81b..ffa0b00 100644 --- a/lib/features/immediate_livecare/immediate_livecare_view_model.dart +++ b/lib/features/immediate_livecare/immediate_livecare_view_model.dart @@ -45,9 +45,7 @@ class ImmediateLiveCareViewModel extends ChangeNotifier { initImmediateLiveCare() { _appState = getIt(); immediateLiveCareClinicsList = []; - patientLiveCareHistoryList = []; isImmediateLiveCareClinicsLoading = true; - patientHasPendingLiveCareRequest = false; liveCareSelectedCallType = 0; // 1- Video, 2- Audio, 3- Phone immediateLiveCareSelectedClinic = GetLiveCareClinicListResponseModel(); liveCareImmediateAppointmentFeesList = LiveCareImmediateAppointmentFeesList(); @@ -136,6 +134,10 @@ class ImmediateLiveCareViewModel extends ChangeNotifier { } Future getPatientLiveCareHistory({Function(dynamic)? onSuccess, Function(String)? onError}) async { + patientLiveCareHistoryList = []; + patientHasPendingLiveCareRequest = false; + notifyListeners(); + final result = await immediateLiveCareRepo.getPatientLiveCareHistory(); result.fold( diff --git a/lib/features/my_appointments/my_appointments_view_model.dart b/lib/features/my_appointments/my_appointments_view_model.dart index 96340a7..f287803 100644 --- a/lib/features/my_appointments/my_appointments_view_model.dart +++ b/lib/features/my_appointments/my_appointments_view_model.dart @@ -220,6 +220,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { } Future getPatientAppointments(bool isActiveAppointment, bool isArrivedAppointments, {Function(dynamic)? onSuccess, Function(String)? onError}) async { + isPatientHasQueueAppointment = false; if (!isAppointmentDataToBeLoaded) return; filteredAppointmentList.clear(); @@ -727,6 +728,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { Future getPatientAppointmentQueueDetails({Function(dynamic)? onSuccess, Function(String)? onError}) async { //TODO: Discuss With Haroon, Is the User Has no data it return No Element Bad State; + isPatientHasQueueAppointment = false; isAppointmentQueueDetailsLoading = true; notifyListeners(); final result = await myAppointmentsRepo.getPatientAppointmentQueueDetails( diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 3ab0ee4..d6f2d23 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1495,5 +1495,11 @@ abstract class LocaleKeys { 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'; } diff --git a/lib/presentation/home/data/landing_page_data.dart b/lib/presentation/home/data/landing_page_data.dart index 74fd096..c52d5e1 100644 --- a/lib/presentation/home/data/landing_page_data.dart +++ b/lib/presentation/home/data/landing_page_data.dart @@ -9,8 +9,8 @@ class LandingPageData { ServiceCardData( serviceName: "emergency", icon: AppAssets.emergency_services_icon, - title: LocaleKeys.emergency.tr(), - subtitle: LocaleKeys.services2.tr(), + title: LocaleKeys.emergency, + subtitle: LocaleKeys.services2, backgroundColor: AppColors.primaryRedColor, iconColor: AppColors.whiteColor, textColor: AppColors.whiteColor, @@ -19,8 +19,8 @@ class LandingPageData { ServiceCardData( serviceName: "indoor_navigation", icon: AppAssets.indoor_nav_icon, - title: LocaleKeys.indoor.tr(), - subtitle: LocaleKeys.navigation.tr(), + title: LocaleKeys.indoor, + subtitle: LocaleKeys.navigation, backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -29,8 +29,8 @@ class LandingPageData { ServiceCardData( serviceName: "search_doctor", icon: AppAssets.search_doctor_icon, - title: LocaleKeys.search.tr(), - subtitle: LocaleKeys.doctor.tr(), + title: LocaleKeys.search, + subtitle: LocaleKeys.doctor, backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -39,8 +39,8 @@ class LandingPageData { ServiceCardData( serviceName: "health_calculators_and_converts", icon: AppAssets.health_calculators_icon, - title: LocaleKeys.health.tr(), - subtitle: LocaleKeys.calculators.tr(), + title: LocaleKeys.health, + subtitle: LocaleKeys.calculators, backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -49,8 +49,8 @@ class LandingPageData { ServiceCardData( serviceName: "health_converters", icon: AppAssets.health_converters_icon, - title: LocaleKeys.health.tr(), - subtitle: LocaleKeys.converters.tr(), + title: LocaleKeys.health, + subtitle: LocaleKeys.converters, backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -59,8 +59,8 @@ class LandingPageData { ServiceCardData( serviceName: "parking_guide", icon: AppAssets.car_parking_icon, - title: LocaleKeys.parking.tr(), - subtitle: LocaleKeys.guide.tr(), + title: LocaleKeys.parking, + subtitle: LocaleKeys.guide, backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -72,8 +72,8 @@ class LandingPageData { ServiceCardData( serviceName: "emergency", icon: AppAssets.emergency_services_icon, - title: LocaleKeys.emergency.tr(), - subtitle: LocaleKeys.services2.tr(), + title: LocaleKeys.emergency, + subtitle: LocaleKeys.services2, backgroundColor: AppColors.primaryRedColor, iconColor: AppColors.whiteColor, textColor: AppColors.whiteColor, @@ -82,8 +82,8 @@ class LandingPageData { ServiceCardData( serviceName: "lab_results", icon: AppAssets.home_lab_result_icon, - title: LocaleKeys.lab.tr(), - subtitle: LocaleKeys.labSubtitle.tr(), + title: LocaleKeys.lab, + subtitle: LocaleKeys.labSubtitle, backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -92,8 +92,8 @@ class LandingPageData { ServiceCardData( serviceName: "radiology_results", icon: AppAssets.my_radiology_icon, - title: LocaleKeys.radiology.tr(), - subtitle: LocaleKeys.radiologySubtitle.tr(), + title: LocaleKeys.radiology, + subtitle: LocaleKeys.radiologySubtitle, backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -102,8 +102,8 @@ class LandingPageData { ServiceCardData( serviceName: "prescriptions", icon: AppAssets.my_prescription_icon, - title: LocaleKeys.medicinesSubtitle.tr(), - subtitle: LocaleKeys.details.tr(), + title: LocaleKeys.medicinesSubtitle, + subtitle: LocaleKeys.details, backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -112,8 +112,8 @@ class LandingPageData { ServiceCardData( serviceName: "insurance_update", icon: AppAssets.insurance_update_icon, - title: LocaleKeys.insurance.tr(), - subtitle: LocaleKeys.details.tr(), + title: LocaleKeys.insurance, + subtitle: LocaleKeys.details, backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -132,8 +132,8 @@ class LandingPageData { ServiceCardData( serviceName: "sick_leaves", icon: AppAssets.my_sick_leave_icon, - title: LocaleKeys.sick.tr(), - subtitle: LocaleKeys.sickSubtitle.tr(), + title: LocaleKeys.sick, + subtitle: LocaleKeys.sickSubtitle, backgroundColor: AppColors.whiteColor, iconColor: AppColors.blackColor, textColor: AppColors.blackColor, @@ -145,8 +145,8 @@ class LandingPageData { ServiceCardData( serviceName: "livecare", icon: AppAssets.small_livecare_icon, - title: LocaleKeys.liveCare.tr(), - subtitle: "Explore our app, View our services and offers", + title: LocaleKeys.liveCare, + subtitle: LocaleKeys.liveCareServiceDesc, largeCardIcon: AppAssets.liveCareService, backgroundColor: AppColors.successColor, iconColor: AppColors.whiteColor, @@ -163,8 +163,8 @@ class LandingPageData { ServiceCardData( serviceName: "home_health_care", icon: AppAssets.homeBottom, - title: LocaleKeys.homeHealthCare.tr(), - subtitle: "Explore our app, View our services and offers", + title: LocaleKeys.homeHealthCare, + subtitle: LocaleKeys.liveCareServiceDesc, largeCardIcon: AppAssets.homeHealthCareService, backgroundColor: AppColors.primaryRedColor, iconColor: AppColors.whiteColor, @@ -173,8 +173,8 @@ class LandingPageData { ServiceCardData( serviceName: "pharmacy", icon: AppAssets.pharmacy_icon, //359846 - title: LocaleKeys.hmgPharmacy.tr(), - subtitle: "Explore our app, View our services and offers", + title: LocaleKeys.hmgPharmacy, + subtitle: LocaleKeys.liveCareServiceDesc, largeCardIcon: AppAssets.pharmacyService, backgroundColor: AppColors.pharmacyBGColor, iconColor: null, diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 8267990..51470c6 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -847,7 +847,7 @@ class _LandingPageState extends State { hasShadow: true, ), child: AppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsViewModel.patientUpcomingAppointmentsHistoryList.first, + patientAppointmentHistoryResponseModel: myAppointmentsViewModel.patientAppointmentsHistoryList.first, myAppointmentsViewModel: myAppointmentsViewModel, bookAppointmentsViewModel: bookAppointmentsViewModel, isLoading: false, @@ -893,7 +893,7 @@ class _LandingPageState extends State { } } else if (index == 2) { if ((myAppointmentsViewModel.isPatientHasQueueAppointment || immediateLiveCareViewModel.patientHasPendingLiveCareRequest) && - myAppointmentsViewModel.patientUpcomingAppointmentsHistoryList.isNotEmpty) { + todoSectionViewModel.patientAncillaryOrdersList.isNotEmpty) { return AncillaryOrderCard( order: todoSectionViewModel.patientAncillaryOrdersList.first, isLoading: false, diff --git a/lib/presentation/home/widgets/large_service_card.dart b/lib/presentation/home/widgets/large_service_card.dart index 6025ba8..5df415d 100644 --- a/lib/presentation/home/widgets/large_service_card.dart +++ b/lib/presentation/home/widgets/large_service_card.dart @@ -89,14 +89,13 @@ class LargeServiceCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - serviceCardData.title.toText14(isBold: true, color: AppColors.textColor), - SizedBox(width: 6.h), - serviceCardData.subtitle.toText14(weight: FontWeight.w500, color: AppColors.textColorLight), + serviceCardData.title.tr(context: context).toText14(isBold: true, color: AppColors.textColor), + serviceCardData.subtitle.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), ], ), ), ], - ).paddingSymmetrical(16.w, 20.h), + ).paddingSymmetrical(12.w, 24.h), CustomButton( text: serviceCardData.isBold ? LocaleKeys.visitPharmacyOnline.tr() : LocaleKeys.bookNow.tr(context: context), onPressed: () { diff --git a/lib/presentation/home/widgets/small_service_card.dart b/lib/presentation/home/widgets/small_service_card.dart index 49db8bf..2ccf21c 100644 --- a/lib/presentation/home/widgets/small_service_card.dart +++ b/lib/presentation/home/widgets/small_service_card.dart @@ -65,8 +65,8 @@ class SmallServiceCard extends StatelessWidget { children: [ Utils.buildSvgWithAssets(icon: icon, iconColor: iconColor, width: 32.h, height: 32.h), SizedBox(height: 6.h), - title.toText11(color: textColor, isBold: isBold, isCenter: true), - subtitle.toText11(color: textColor, isBold: isBold, isCenter: true), + title.tr(context: context).toText11(color: textColor, isBold: isBold, isCenter: true), + subtitle.tr(context: context).toText11(color: textColor, isBold: isBold, isCenter: true), ], ), ), diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index ad2461f..fc49000 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -192,7 +192,7 @@ class _MedicalFilePageState extends State { SizedBox(width: 4.h), Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, height: 22.h, width: 22.w) ], - ).withHorizontalPadding(24.w).onPress(() { + ).onPress(() { DialogService dialogService = getIt.get(); dialogService.showFamilyBottomSheetWithoutH( label: LocaleKeys.familyTitle.tr(context: context), @@ -276,12 +276,12 @@ class _MedicalFilePageState extends State { runSpacing: 4.h, children: [ 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), ), AppCustomChipWidget( 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, labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), padding: EdgeInsets.zero, @@ -439,14 +439,14 @@ class _MedicalFilePageState extends State { itemPadding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 14.h), items: [ ExpandableListItem( - title: "Medical Services".toText18(weight: FontWeight.w600), + title: LocaleKeys.medicalServices.tr(context: context).toText18(weight: FontWeight.w600), children: [ SizedBox(height: 10.h), getSelectedTabData(0), ], ), ExpandableListItem( - title: "Medical Reports".toText18( + title: LocaleKeys.medicalReports.tr(context: context).toText18( weight: FontWeight.w600, ), expandedBackgroundColor: Colors.transparent, @@ -455,7 +455,7 @@ class _MedicalFilePageState extends State { getSelectedTabData(2), ]), ExpandableListItem( - title: "Insurance & Payments".toText18(weight: FontWeight.w600), + title: LocaleKeys.insuranceAndPayments.tr(context: context).toText18(weight: FontWeight.w600), expandedBackgroundColor: Colors.transparent, children: [ SizedBox(height: 10.h), @@ -463,7 +463,7 @@ class _MedicalFilePageState extends State { ], ), ExpandableListItem( - title: "Tracker & Others".toText18(weight: FontWeight.w600), + title: LocaleKeys.trackerAndOthers.tr(context: context).toText18(weight: FontWeight.w600), expandedBackgroundColor: Colors.transparent, children: [ SizedBox(height: 10.h), @@ -645,6 +645,7 @@ class _MedicalFilePageState extends State { scrollDirection: Axis.horizontal, shrinkWrap: true, itemCount: myAppointmentsVM.patientAppointmentsHistoryList.length, + padding: EdgeInsets.zero, itemBuilder: (context, index) { return AnimationConfiguration.staggeredList( position: index, @@ -699,9 +700,9 @@ class _MedicalFilePageState extends State { ), )); }, - 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), LocaleKeys.labAndRadiology.tr().toText16(weight: FontWeight.w500, letterSpacing: -0.2), @@ -1484,7 +1485,7 @@ class _MedicalFilePageState extends State { Expanded( child: _buildVitalSignCard( icon: AppAssets.bmiVital, - label: "BMI", + label: LocaleKeys.bmi.tr(context: context), value: vitalSign.bodyMassIndex?.toString() ?? '--', unit: '', status: vitalSign.bodyMassIndex != null ? _getBMIStatus(vitalSign.bodyMassIndex) : null, @@ -1495,7 +1496,7 @@ class _MedicalFilePageState extends State { Expanded( child: _buildVitalSignCard( icon: AppAssets.heightVital, - label: "Height", + label: LocaleKeys.height.tr(context: context), value: vitalSign.heightCm?.toString() ?? '--', unit: 'cm', status: null, @@ -1511,7 +1512,7 @@ class _MedicalFilePageState extends State { Expanded( child: _buildVitalSignCard( icon: AppAssets.weightVital, - label: "Weight", + label: LocaleKeys.weight.tr(context: context), value: vitalSign.weightKg?.toString() ?? '--', unit: 'kg', status: vitalSign.weightKg != null ? "Normal" : null, @@ -1522,7 +1523,7 @@ class _MedicalFilePageState extends State { Expanded( child: _buildVitalSignCard( icon: AppAssets.bloodPressure, - label: "Blood Pressure", + label: LocaleKeys.bloodPressure.tr(context: context), value: vitalSign.bloodPressureLower != null && vitalSign.bloodPressureHigher != null ? "${vitalSign.bloodPressureHigher}/${vitalSign.bloodPressureLower}" : '--', diff --git a/lib/presentation/vital_sign/vital_sign_page.dart b/lib/presentation/vital_sign/vital_sign_page.dart index fbf9fc6..e457023 100644 --- a/lib/presentation/vital_sign/vital_sign_page.dart +++ b/lib/presentation/vital_sign/vital_sign_page.dart @@ -1,5 +1,6 @@ import 'dart:ui'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.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/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/generated/locale_keys.g.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/chip/app_custom_chip_widget.dart'; @@ -42,7 +44,7 @@ class _VitalSignPageState extends State { return Scaffold( backgroundColor: AppColors.bgScaffoldColor, body: CollapsingListView( - title: 'Vital Signs', + title: LocaleKeys.vitalSigns.tr(context: context), child: Consumer( builder: (context, viewModel, child) { @@ -70,14 +72,14 @@ class _VitalSignPageState extends State { // BMI Card _buildVitalSignCard( icon: AppAssets.bmiVital, - label: 'BMI', + label: LocaleKeys.bmi.tr(context: context), value: latestVitalSign?.bodyMassIndex?.toString() ?? '--', unit: '', status: VitalSignUiModel.bmiStatus(latestVitalSign?.bodyMassIndex), onTap: () => _openDetails( - const VitalSignDetailsArgs( + VitalSignDetailsArgs( metric: VitalSignMetric.bmi, - title: 'BMI', + title: LocaleKeys.bmi.tr(context: context), icon: AppAssets.bmiVital, unit: '', ), @@ -88,14 +90,14 @@ class _VitalSignPageState extends State { // Height Card _buildVitalSignCard( icon: AppAssets.heightVital, - label: 'Height', + label: LocaleKeys.height.tr(context: context), value: latestVitalSign?.heightCm?.toString() ?? '--', unit: 'cm', status: null, onTap: () => _openDetails( - const VitalSignDetailsArgs( + VitalSignDetailsArgs( metric: VitalSignMetric.height, - title: 'Height', + title: LocaleKeys.height.tr(context: context), icon: AppAssets.heightVital, unit: 'cm', ), @@ -106,14 +108,14 @@ class _VitalSignPageState extends State { // Weight Card _buildVitalSignCard( icon: AppAssets.weightVital, - label: 'Weight', + label: LocaleKeys.weight.tr(context: context), value: latestVitalSign?.weightKg?.toString() ?? '--', unit: 'kg', status: (latestVitalSign?.weightKg != null) ? 'Normal' : null, onTap: () => _openDetails( - const VitalSignDetailsArgs( + VitalSignDetailsArgs( metric: VitalSignMetric.weight, - title: 'Weight', + title: LocaleKeys.height.tr(context: context), icon: AppAssets.weightVital, unit: 'kg', ), @@ -124,7 +126,7 @@ class _VitalSignPageState extends State { // Blood Pressure Card _buildVitalSignCard( icon: AppAssets.bloodPressure, - label: 'Blood Pressure', + label: LocaleKeys.bloodPressure.tr(context: context), value: latestVitalSign != null && latestVitalSign.bloodPressureHigher != null && latestVitalSign.bloodPressureLower != null @@ -136,9 +138,9 @@ class _VitalSignPageState extends State { diastolic: latestVitalSign?.bloodPressureLower, ), onTap: () => _openDetails( - const VitalSignDetailsArgs( + VitalSignDetailsArgs( metric: VitalSignMetric.bloodPressure, - title: 'Blood Pressure', + title: LocaleKeys.bloodPressure.tr(context: context), icon: AppAssets.bloodPressure, unit: 'mmHg', low: 90, @@ -151,14 +153,14 @@ class _VitalSignPageState extends State { // Temperature Card _buildVitalSignCard( icon: AppAssets.temperature, - label: 'Temperature', + label: LocaleKeys.temperature.tr(context: context), value: latestVitalSign?.temperatureCelcius?.toString() ?? '--', unit: '°C', status: null, onTap: () => _openDetails( - const VitalSignDetailsArgs( + VitalSignDetailsArgs( metric: VitalSignMetric.temperature, - title: 'Temperature', + title: LocaleKeys.temperature.tr(context: context), icon: AppAssets.temperature, unit: '°C', low: 36.1, @@ -226,14 +228,14 @@ class _VitalSignPageState extends State { bottom: 12.h, child: _buildVitalSignCard( icon: AppAssets.heart, - label: 'Heart Rate', + label: LocaleKeys.heart.tr(context: context), value: latestVitalSign?.heartRate?.toString() ?? latestVitalSign?.pulseBeatPerMinute?.toString() ?? '--', unit: 'bpm', status: 'Normal', onTap: () => _openDetails( - const VitalSignDetailsArgs( + VitalSignDetailsArgs( metric: VitalSignMetric.heartRate, - title: 'Heart Rate', + title: LocaleKeys.heart.tr(context: context), icon: AppAssets.heart, unit: 'bpm', low: 60, @@ -250,15 +252,15 @@ class _VitalSignPageState extends State { // Respiratory rate Card _buildVitalSignCard( icon: AppAssets.respRate, - label: 'Respiratory rate', - value: latestVitalSign?.respirationBeatPerMinute?.toString() ?? '--', + label: LocaleKeys.respirationRate.tr(context: context), + value: latestVitalSign?.respirationBeatPerMinute?.toString() ?? '--', unit: 'bpm', status: 'Normal', onTap: () => _openDetails( - const VitalSignDetailsArgs( - metric: VitalSignMetric.respiratoryRate, - title: 'Respiratory rate', - icon: AppAssets.respRate, + VitalSignDetailsArgs( + metric: VitalSignMetric.respiratoryRate, + title: LocaleKeys.respirationRate.tr(context: context), + icon: AppAssets.respRate, unit: 'bpm', low: 12, high: 20, diff --git a/lib/widgets/buttons/custom_button.dart b/lib/widgets/buttons/custom_button.dart index 08d281f..ad2a1d4 100644 --- a/lib/widgets/buttons/custom_button.dart +++ b/lib/widgets/buttons/custom_button.dart @@ -75,7 +75,7 @@ class CustomButton extends StatelessWidget { children: [ if (icon != null) Padding( - padding: text.isNotEmpty ? EdgeInsets.only(right: 8.w, left: 8.w) : EdgeInsets.zero, + 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( diff --git a/lib/widgets/expandable_list_widget.dart b/lib/widgets/expandable_list_widget.dart index b948299..db4e398 100644 --- a/lib/widgets/expandable_list_widget.dart +++ b/lib/widgets/expandable_list_widget.dart @@ -282,9 +282,9 @@ class ExpandableListTheme { dividerColor: dividerColor ?? Colors.grey.shade300, defaultTrailingIcon: defaultTrailingIcon ?? Icon(Icons.keyboard_arrow_down, color: Colors.black, size: 24), - itemPadding: itemPadding ?? const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), - contentPadding: contentPadding ?? const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 16.0), - leadingSpacing: leadingSpacing ?? 12.0, + itemPadding: itemPadding ?? EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h), + contentPadding: contentPadding ?? EdgeInsets.only(left: 16.w, right: 16.w, bottom: 16.h), + leadingSpacing: leadingSpacing ?? 12.w, ); } } diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index 9f101d4..d97b0f0 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -191,7 +191,7 @@ class TextInputWidget extends StatelessWidget { return Container( height: 40.h, width: 40.h, - margin: EdgeInsets.only(right: 10.h), + margin: EdgeInsets.only(right: 10.w, left: 10.w), padding: EdgeInsets.all(8.h), decoration: RoundedRectangleBorder().toSmoothCornerDecoration( borderRadius: 12.r, @@ -204,7 +204,7 @@ class TextInputWidget extends StatelessWidget { final AppState appState = getIt.get(); return Container( height: 40.h, - width: 40.h, + width: 40.w, margin: EdgeInsets.zero, padding: EdgeInsets.all(8.h), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 12.r, color: AppColors.whiteColor), From 07447e148bc1e7fd0143024ef14f4368f2a58c52 Mon Sep 17 00:00:00 2001 From: faizatflutter Date: Tue, 20 Jan 2026 17:28:13 +0300 Subject: [PATCH 06/10] Symptoms Checker flow is completed --- assets/images/svg/colored_dots_icon.svg | 5 + lib/core/api_consts.dart | 2 +- lib/core/app_assets.dart | 2 +- lib/core/enums.dart | 147 ++ .../models/conditions_model.dart | 194 +- .../resp_models/triage_response_model.dart | 80 +- .../symptoms_checker_repo.dart | 94 +- .../symptoms_checker_view_model.dart | 122 +- .../hmg_services/services_page.dart | 84 +- lib/presentation/home/landing_page.dart | 68 +- lib/presentation/home/navigation_screen.dart | 9 +- .../possible_conditions_screen.dart | 155 +- .../symptoms_checker/risk_factors_screen.dart | 2 +- .../symptoms_selector_screen.dart | 12 +- .../symptoms_checker/triage_screen.dart | 15 +- .../symptoms_checker/user_info_selection.dart | 24 +- .../widgets/condition_card.dart | 222 +- lib/routes/app_routes.dart | 45 +- lib/theme/colors.dart | 2 +- lib/widgets/buttons/custom_button.dart | 19 +- pubspec.lock | 2073 ----------------- 21 files changed, 805 insertions(+), 2571 deletions(-) create mode 100644 assets/images/svg/colored_dots_icon.svg delete mode 100644 pubspec.lock diff --git a/assets/images/svg/colored_dots_icon.svg b/assets/images/svg/colored_dots_icon.svg new file mode 100644 index 0000000..7f05dc5 --- /dev/null +++ b/assets/images/svg/colored_dots_icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index efefee1..7003aa7 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -841,7 +841,7 @@ class ApiConsts { static final String getRiskFactors = '$symptomsCheckerApi/GetRiskFactors'; static final String getSuggestions = '$symptomsCheckerApi/GetSuggestion'; static final String diagnosis = '$symptomsCheckerApi/GetDiagnosis'; - static final String explain = '$symptomsCheckerApi/explain'; + static final String explain = '$symptomsCheckerApi/ExplainDiagnosisResult'; //E-REFERRAL SERVICES static final getAllRelationshipTypes = "Services/Patients.svc/REST/GetAllRelationshipTypes"; diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index 26da9fa..4bf2117 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -253,6 +253,7 @@ class AppAssets { static const String homeBorderedIcon = '$svgBasePath/home_bordered.svg'; static const String symptomCheckerIcon = '$svgBasePath/symptom_checker_icon.svg'; static const String symptomCheckerBottomIcon = '$svgBasePath/symptom_bottom_icon.svg'; + static const String coloredDotsIcon = '$svgBasePath/colored_dots_icon.svg'; // Water Monitor static const String waterBottle = '$svgBasePath/water_bottle.svg'; @@ -352,4 +353,3 @@ class AppAnimations { static const String ambulanceAlert = '$lottieBasePath/ambulance_alert.json'; static const String rrtAmbulance = '$lottieBasePath/rrt_ambulance.json'; } - diff --git a/lib/core/enums.dart b/lib/core/enums.dart index 6dc3bf6..6613702 100644 --- a/lib/core/enums.dart +++ b/lib/core/enums.dart @@ -311,3 +311,150 @@ extension ServiceTypeEnumExt on ServiceTypeEnum { enum PossibleConditionsSeverityEnum { seekMedicalAdvice, monitorOnly, emergency } enum HealthTrackerTypeEnum { bloodSugar, bloodPressure, weightTracker } + +// Severity Enum +enum SeverityEnum { mild, moderate, severe } + +extension SeverityEnumExtension on SeverityEnum { + int get toInt { + switch (this) { + case SeverityEnum.mild: + return 0; + case SeverityEnum.moderate: + return 1; + case SeverityEnum.severe: + return 2; + } + } + + String get displayName { + AppState appState = getIt.get(); + bool isArabic = appState.getLanguageID() == 1 ? true : false; + switch (this) { + case SeverityEnum.mild: + return isArabic ? 'خفيف' : 'Mild'; + case SeverityEnum.moderate: + return isArabic ? 'متوسط' : 'Moderate'; + case SeverityEnum.severe: + return isArabic ? 'شديد' : 'Severe'; + } + } + + static SeverityEnum? fromInt(int value) { + switch (value) { + case 0: + return SeverityEnum.mild; + case 1: + return SeverityEnum.moderate; + case 2: + return SeverityEnum.severe; + default: + return null; + } + } +} + +// Triage Level Enum +enum TriageLevelEnum { emergencyAmbulance, emergency, consultation24, consultation, selfCare } + +extension TriageLevelEnumExtension on TriageLevelEnum { + int get toInt { + switch (this) { + case TriageLevelEnum.emergencyAmbulance: + return 0; + case TriageLevelEnum.emergency: + return 1; + case TriageLevelEnum.consultation24: + return 2; + case TriageLevelEnum.consultation: + return 3; + case TriageLevelEnum.selfCare: + return 4; + } + } + + String get displayName { + AppState appState = getIt.get(); + bool isArabic = appState.getLanguageID() == 1 ? true : false; + switch (this) { + case TriageLevelEnum.emergencyAmbulance: + return isArabic ? 'طوارئ - إسعاف' : 'Emergency - Ambulance'; + case TriageLevelEnum.emergency: + return isArabic ? 'طوارئ' : 'Emergency'; + case TriageLevelEnum.consultation24: + return isArabic ? 'استشارة خلال 24 ساعة' : 'Consultation within 24 hours'; + case TriageLevelEnum.consultation: + return isArabic ? 'استشارة' : 'Consultation'; + case TriageLevelEnum.selfCare: + return isArabic ? 'رعاية ذاتية' : 'Self Care'; + } + } + + static TriageLevelEnum? fromInt(int value) { + switch (value) { + case 0: + return TriageLevelEnum.emergencyAmbulance; + case 1: + return TriageLevelEnum.emergency; + case 2: + return TriageLevelEnum.consultation24; + case 3: + return TriageLevelEnum.consultation; + case 4: + return TriageLevelEnum.selfCare; + default: + return null; + } + } +} + +// Question Type Enum +enum QuestionTypeEnum { single, groupSingle, groupMultiple, duration } + +extension QuestionTypeEnumExtension on QuestionTypeEnum { + int get toInt { + switch (this) { + case QuestionTypeEnum.single: + return 0; + case QuestionTypeEnum.groupSingle: + return 1; + case QuestionTypeEnum.groupMultiple: + return 2; + case QuestionTypeEnum.duration: + return 3; + } + } + + String get displayName { + AppState appState = getIt.get(); + bool isArabic = appState.getLanguageID() == 1 ? true : false; + switch (this) { + case QuestionTypeEnum.single: + return isArabic ? 'سؤال واحد' : 'Single'; + case QuestionTypeEnum.groupSingle: + return isArabic ? 'مجموعة - اختيار واحد' : 'Group Single'; + case QuestionTypeEnum.groupMultiple: + return isArabic ? 'مجموعة - اختيار متعدد' : 'Group Multiple'; + case QuestionTypeEnum.duration: + return isArabic ? 'المدة' : 'Duration'; + } + } + + static QuestionTypeEnum? fromInt(int value) { + switch (value) { + case 0: + return QuestionTypeEnum.single; + case 1: + return QuestionTypeEnum.groupSingle; + case 2: + return QuestionTypeEnum.groupMultiple; + case 3: + return QuestionTypeEnum.duration; + default: + return null; + } + } +} + + + diff --git a/lib/features/symptoms_checker/models/conditions_model.dart b/lib/features/symptoms_checker/models/conditions_model.dart index 774d8c3..af66c21 100644 --- a/lib/features/symptoms_checker/models/conditions_model.dart +++ b/lib/features/symptoms_checker/models/conditions_model.dart @@ -1,97 +1,97 @@ -import 'package:flutter/material.dart'; -import 'package:hmg_patient_app_new/core/enums.dart'; - -class ConditionsModel { - final IconData icon; - final String title; - final int percentage; - final String tagText; - final String clinic; - final List symptoms; - final String description; - final String? monitorNote; - final String? appointmentLabel; - final PossibleConditionsSeverityEnum possibleConditionsSeverityEnum; - - ConditionsModel({ - required this.icon, - required this.title, - required this.percentage, - required this.tagText, - required this.clinic, - required this.symptoms, - required this.description, - required this.possibleConditionsSeverityEnum, - this.monitorNote, - this.appointmentLabel, - }); -} - -List dummyConditions = [ - ConditionsModel( - icon: Icons.psychology_alt, - possibleConditionsSeverityEnum: PossibleConditionsSeverityEnum.seekMedicalAdvice, - title: "Migraine", - percentage: 87, - tagText: "Seek Medical Advice", - clinic: "Internal Medicine Clinic", - symptoms: ["Headache", "Nausea", "Sensitivity to light"], - description: "A migraine is a type of headache that can cause severe throbbing pain, usually on one side of the head.", - appointmentLabel: "Book Appointment", - ), - ConditionsModel( - icon: Icons.deblur, - title: "Tension Headache", - percentage: 37, - tagText: "Monitor", - monitorNote: "No need to visit doctor", - clinic: "GP Clinic", - symptoms: ["Mild head pressure", "Scalp tenderness"], - description: "A tension-type headache is generally a mild to moderate pain that feels like a tight band around your head.", - possibleConditionsSeverityEnum: PossibleConditionsSeverityEnum.monitorOnly, - ), - ConditionsModel( - icon: Icons.medication_liquid, - title: "Meningitis", - percentage: 28, - tagText: "Emergency", - clinic: "Neurology Clinic", - symptoms: ["Mild head pressure", "Scalp tenderness"], - description: "A tension-type headache is generally a mild to moderate pain that feels like a tight band around your head.", - appointmentLabel: "Book Appointment", - possibleConditionsSeverityEnum: PossibleConditionsSeverityEnum.emergency, - ), - ConditionsModel( - icon: Icons.psychology_alt, - title: "Migraine", - percentage: 87, - tagText: "Seek Medical Advice", - clinic: "Internal Medicine Clinic", - symptoms: ["Headache", "Nausea", "Sensitivity to light"], - description: "A migraine is a type of headache that can cause severe throbbing pain, usually on one side of the head.", - appointmentLabel: "Book Appointment", - possibleConditionsSeverityEnum: PossibleConditionsSeverityEnum.seekMedicalAdvice, - ), - ConditionsModel( - icon: Icons.deblur, - title: "Tension Headache", - percentage: 37, - tagText: "Monitor", - monitorNote: "No need to visit doctor", - clinic: "GP Clinic", - symptoms: ["Mild head pressure", "Scalp tenderness"], - description: "A tension-type headache is generally a mild to moderate pain that feels like a tight band around your head.", - possibleConditionsSeverityEnum: PossibleConditionsSeverityEnum.monitorOnly, - ), - ConditionsModel( - icon: Icons.medication_liquid, - title: "Meningitis", - percentage: 28, - tagText: "Emergency", - clinic: "Neurology Clinic", - symptoms: ["Mild head pressure", "Scalp tenderness"], - description: "A tension-type headache is generally a mild to moderate pain that feels like a tight band around your head.", - appointmentLabel: "Book Appointment", - possibleConditionsSeverityEnum: PossibleConditionsSeverityEnum.emergency, - ), -]; +// import 'package:flutter/material.dart'; +// import 'package:hmg_patient_app_new/core/enums.dart'; +// +// class ConditionsModel { +// final IconData icon; +// final String title; +// final int percentage; +// final String tagText; +// final String clinic; +// final List symptoms; +// final String description; +// final String? monitorNote; +// final String? appointmentLabel; +// final PossibleConditionsSeverityEnum possibleConditionsSeverityEnum; +// +// ConditionsModel({ +// required this.icon, +// required this.title, +// required this.percentage, +// required this.tagText, +// required this.clinic, +// required this.symptoms, +// required this.description, +// required this.possibleConditionsSeverityEnum, +// this.monitorNote, +// this.appointmentLabel, +// }); +// } +// +// List dummyConditions = [ +// ConditionsModel( +// icon: Icons.psychology_alt, +// possibleConditionsSeverityEnum: PossibleConditionsSeverityEnum.seekMedicalAdvice, +// title: "Migraine", +// percentage: 87, +// tagText: "Seek Medical Advice", +// clinic: "Internal Medicine Clinic", +// symptoms: ["Headache", "Nausea", "Sensitivity to light"], +// description: "A migraine is a type of headache that can cause severe throbbing pain, usually on one side of the head.", +// appointmentLabel: "Book Appointment", +// ), +// ConditionsModel( +// icon: Icons.deblur, +// title: "Tension Headache", +// percentage: 37, +// tagText: "Monitor", +// monitorNote: "No need to visit doctor", +// clinic: "GP Clinic", +// symptoms: ["Mild head pressure", "Scalp tenderness"], +// description: "A tension-type headache is generally a mild to moderate pain that feels like a tight band around your head.", +// possibleConditionsSeverityEnum: PossibleConditionsSeverityEnum.monitorOnly, +// ), +// ConditionsModel( +// icon: Icons.medication_liquid, +// title: "Meningitis", +// percentage: 28, +// tagText: "Emergency", +// clinic: "Neurology Clinic", +// symptoms: ["Mild head pressure", "Scalp tenderness"], +// description: "A tension-type headache is generally a mild to moderate pain that feels like a tight band around your head.", +// appointmentLabel: "Book Appointment", +// possibleConditionsSeverityEnum: PossibleConditionsSeverityEnum.emergency, +// ), +// ConditionsModel( +// icon: Icons.psychology_alt, +// title: "Migraine", +// percentage: 87, +// tagText: "Seek Medical Advice", +// clinic: "Internal Medicine Clinic", +// symptoms: ["Headache", "Nausea", "Sensitivity to light"], +// description: "A migraine is a type of headache that can cause severe throbbing pain, usually on one side of the head.", +// appointmentLabel: "Book Appointment", +// possibleConditionsSeverityEnum: PossibleConditionsSeverityEnum.seekMedicalAdvice, +// ), +// ConditionsModel( +// icon: Icons.deblur, +// title: "Tension Headache", +// percentage: 37, +// tagText: "Monitor", +// monitorNote: "No need to visit doctor", +// clinic: "GP Clinic", +// symptoms: ["Mild head pressure", "Scalp tenderness"], +// description: "A tension-type headache is generally a mild to moderate pain that feels like a tight band around your head.", +// possibleConditionsSeverityEnum: PossibleConditionsSeverityEnum.monitorOnly, +// ), +// ConditionsModel( +// icon: Icons.medication_liquid, +// title: "Meningitis", +// percentage: 28, +// tagText: "Emergency", +// clinic: "Neurology Clinic", +// symptoms: ["Mild head pressure", "Scalp tenderness"], +// description: "A tension-type headache is generally a mild to moderate pain that feels like a tight band around your head.", +// appointmentLabel: "Book Appointment", +// possibleConditionsSeverityEnum: PossibleConditionsSeverityEnum.emergency, +// ), +// ]; diff --git a/lib/features/symptoms_checker/models/resp_models/triage_response_model.dart b/lib/features/symptoms_checker/models/resp_models/triage_response_model.dart index f0d7e90..60a3ad3 100644 --- a/lib/features/symptoms_checker/models/resp_models/triage_response_model.dart +++ b/lib/features/symptoms_checker/models/resp_models/triage_response_model.dart @@ -1,3 +1,5 @@ +import 'package:hmg_patient_app_new/core/enums.dart'; + class TriageDataDetails { final TriageQuestion? question; final List? conditions; @@ -171,7 +173,7 @@ class TriageCondition { final String? name; final String? commonName; final double? probability; - final dynamic conditionDetails; + final ConditionDetails? conditionDetails; TriageCondition({ this.id, @@ -187,7 +189,7 @@ class TriageCondition { name: json['name'], commonName: json['common_name'], probability: json['probability']?.toDouble(), - conditionDetails: json['condition_details'], + conditionDetails: json['condition_details'] != null ? ConditionDetails.fromJson(json['condition_details']) : null, ); } @@ -197,7 +199,7 @@ class TriageCondition { 'name': name, 'common_name': commonName, 'probability': probability, - 'condition_details': conditionDetails, + 'condition_details': conditionDetails?.toJson(), }; } @@ -207,3 +209,75 @@ class TriageCondition { return '${(probability! * 100).toStringAsFixed(1)}%'; } } + +class ConditionDetails { + final String? icd10Code; + final ConditionCategory? category; + final SeverityEnum? severity; + final TriageLevelEnum? triageLevel; + final String? hint; + final bool? hasPatientEducation; + final String? prevalence; + final String? acuteness; + + ConditionDetails({ + this.icd10Code, + this.category, + this.severity, + this.triageLevel, + this.hint, + this.hasPatientEducation, + this.prevalence, + this.acuteness, + }); + + factory ConditionDetails.fromJson(Map json) { + return ConditionDetails( + icd10Code: json['icd10_code'], + category: json['category'] != null ? ConditionCategory.fromJson(json['category']) : null, + severity: json['severity'] != null ? SeverityEnumExtension.fromInt(json['severity']) : null, + triageLevel: json['triage_level'] != null ? TriageLevelEnumExtension.fromInt(json['triage_level']) : null, + hint: json['hint'], + hasPatientEducation: json['has_patient_education'], + prevalence: json['prevalence'], + acuteness: json['acuteness'], + ); + } + + Map toJson() { + return { + 'icd10_code': icd10Code, + 'category': category?.toJson(), + 'severity': severity?.toInt, + 'triage_level': triageLevel?.toInt, + 'hint': hint, + 'has_patient_education': hasPatientEducation, + 'prevalence': prevalence, + 'acuteness': acuteness, + }; + } +} + +class ConditionCategory { + final String? id; + final String? name; + + ConditionCategory({ + this.id, + this.name, + }); + + factory ConditionCategory.fromJson(Map json) { + return ConditionCategory( + id: json['id'], + name: json['name'], + ); + } + + Map toJson() { + return { + 'id': id, + 'name': name, + }; + } +} diff --git a/lib/features/symptoms_checker/symptoms_checker_repo.dart b/lib/features/symptoms_checker/symptoms_checker_repo.dart index c55c2f0..154b13a 100644 --- a/lib/features/symptoms_checker/symptoms_checker_repo.dart +++ b/lib/features/symptoms_checker/symptoms_checker_repo.dart @@ -12,50 +12,42 @@ import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models import 'package:hmg_patient_app_new/services/logger_service.dart'; abstract class SymptomsCheckerRepo { - Future>> - getUserDetails({ + Future>> getUserDetails({ required String userName, required String password, }); - Future>> - getBodySymptomsByName({ + Future>> getBodySymptomsByName({ required List organNames, required String userSessionToken, required int gender, }); - Future>> - getRiskFactors({ + Future>> getRiskFactors({ required int age, - required String sex, + required int gender, required List evidenceIds, required String language, required String userSessionToken, - required int gender, required String sessionId, }); - Future>> - getSuggestions({ + Future>> getSuggestions({ required int age, - required String sex, + required int gender, required List evidenceIds, required String language, required String userSessionToken, required String sessionId, - required int gender, }); - Future>> - getDiagnosisForTriage({ + Future>> getDiagnosisForTriage({ required int age, - required String sex, + required int gender, required List evidenceIds, List>? triageEvidence, required String language, required String userSessionToken, - required int gender, required String sessionId, }); } @@ -64,12 +56,10 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { final ApiClient apiClient; final LoggerService loggerService; - SymptomsCheckerRepoImp( - {required this.apiClient, required this.loggerService}); + SymptomsCheckerRepoImp({required this.apiClient, required this.loggerService}); @override - Future>> - getUserDetails({ + Future>> getUserDetails({ required String userName, required String password, }) async { @@ -92,11 +82,9 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { onSuccess: (response, statusCode, {messageStatus, errorMessage}) { try { // Parse response if it's a string - final Map responseData = - response is String ? jsonDecode(response) : response; + final Map responseData = response is String ? jsonDecode(response) : response; - SymptomsUserDetailsResponseModel symptomsUserDetailsResponseModel = - SymptomsUserDetailsResponseModel.fromJson(responseData); + SymptomsUserDetailsResponseModel symptomsUserDetailsResponseModel = SymptomsUserDetailsResponseModel.fromJson(responseData); apiResponse = GenericApiModel( messageStatus: messageStatus ?? 1, @@ -123,8 +111,7 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { } @override - Future>> - getBodySymptomsByName({ + Future>> getBodySymptomsByName({ required List organNames, required String userSessionToken, required int gender, @@ -154,8 +141,7 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { }, onSuccess: (response, statusCode, {messageStatus, errorMessage}) { try { - BodySymptomResponseModel bodySymptomResponse = - BodySymptomResponseModel.fromJson(response); + BodySymptomResponseModel bodySymptomResponse = BodySymptomResponseModel.fromJson(response); apiResponse = GenericApiModel( messageStatus: messageStatus ?? 1, @@ -164,8 +150,7 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { data: bodySymptomResponse, ); } catch (e, stackTrace) { - loggerService - .logError("Error parsing GetBodySymptomsByName response: $e"); + loggerService.logError("Error parsing GetBodySymptomsByName response: $e"); loggerService.logError("StackTrace: $stackTrace"); failure = DataParsingFailure(e.toString()); } @@ -183,21 +168,19 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { } @override - Future>> - getRiskFactors({ + Future>> getRiskFactors({ required int age, - required String sex, + required int gender, required List evidenceIds, required String language, required String userSessionToken, - required int gender, required String sessionId, }) async { final Map body = { "age": { "value": age, }, - "sex": sex, + "gender": gender, "evidence": evidenceIds.map((id) => {"id": id}).toList(), "language": language, "generalId": sessionId, @@ -225,11 +208,9 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { onSuccess: (response, statusCode, {messageStatus, errorMessage}) { try { // Parse response if it's a string - final Map responseData = - response is String ? jsonDecode(response) : response; + final Map responseData = response is String ? jsonDecode(response) : response; - RiskAndSuggestionsResponseModel riskFactorsResponse = - RiskAndSuggestionsResponseModel.fromJson(responseData); + RiskAndSuggestionsResponseModel riskFactorsResponse = RiskAndSuggestionsResponseModel.fromJson(responseData); apiResponse = GenericApiModel( messageStatus: messageStatus ?? 1, @@ -255,16 +236,14 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { } } - Future>> - getDiagnosisForTriage({ + @override + Future>> getDiagnosisForTriage({ required int age, - required String sex, + required int gender, required List evidenceIds, - List>? - triageEvidence, // Additional triage-specific evidence + List>? triageEvidence, // Additional triage-specific evidence required String language, required String userSessionToken, - required int gender, required String sessionId, }) async { // Build evidence list: combine initial symptoms with triage evidence @@ -284,7 +263,7 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { "age": { "value": age, }, - "sex": sex, + "gender": gender, "evidence": evidenceList, "language": language, "suggest_method": "diagnosis", @@ -313,13 +292,11 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { onSuccess: (response, statusCode, {messageStatus, errorMessage}) { try { // Parse response if it's a string - final Map responseData = - response is String ? jsonDecode(response) : response; + final Map responseData = response is String ? jsonDecode(response) : response; final updatedResponseData = responseData['dataDetails']; - TriageDataDetails riskFactorsResponse = - TriageDataDetails.fromJson(updatedResponseData); + TriageDataDetails riskFactorsResponse = TriageDataDetails.fromJson(updatedResponseData); apiResponse = GenericApiModel( messageStatus: messageStatus ?? 1, @@ -328,8 +305,7 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { data: riskFactorsResponse, ); } catch (e, stackTrace) { - loggerService - .logError("Error parsing getDiagnosisForTriage response: $e"); + loggerService.logError("Error parsing getDiagnosisForTriage response: $e"); loggerService.logError("StackTrace: $stackTrace"); failure = DataParsingFailure(e.toString()); } @@ -347,21 +323,19 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { } @override - Future>> - getSuggestions({ + Future>> getSuggestions({ required int age, - required String sex, + required int gender, required List evidenceIds, required String language, required String userSessionToken, required String sessionId, - required int gender, }) async { final Map body = { "age": { "value": age, }, - "sex": sex, + "gender": gender, "evidence": evidenceIds.map((id) => {"id": id}).toList(), "language": language, "generalId": sessionId, @@ -389,11 +363,9 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { onSuccess: (response, statusCode, {messageStatus, errorMessage}) { try { // Parse response if it's a string - final Map responseData = - response is String ? jsonDecode(response) : response; + final Map responseData = response is String ? jsonDecode(response) : response; - RiskAndSuggestionsResponseModel riskFactorsResponse = - RiskAndSuggestionsResponseModel.fromJson(responseData); + RiskAndSuggestionsResponseModel riskFactorsResponse = RiskAndSuggestionsResponseModel.fromJson(responseData); apiResponse = GenericApiModel( messageStatus: messageStatus ?? 1, diff --git a/lib/features/symptoms_checker/symptoms_checker_view_model.dart b/lib/features/symptoms_checker/symptoms_checker_view_model.dart index 73768fe..929fe91 100644 --- a/lib/features/symptoms_checker/symptoms_checker_view_model.dart +++ b/lib/features/symptoms_checker/symptoms_checker_view_model.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/features/symptoms_checker/data/organ_mapping_data.dart'; @@ -47,12 +47,9 @@ class SymptomsCheckerViewModel extends ChangeNotifier { TriageDataDetails? triageDataDetails; // Triage state - int? - _selectedTriageChoiceIndex; // Deprecated - keeping for backward compatibility - final Map _selectedTriageChoicesByItemId = - {}; // Map of itemId -> choiceIndex for multi-item questions - final List> _triageEvidenceList = - []; // Store triage evidence with proper format + int? _selectedTriageChoiceIndex; // Deprecated - keeping for backward compatibility + final Map _selectedTriageChoicesByItemId = {}; // Map of itemId -> choiceIndex for multi-item questions + final List> _triageEvidenceList = []; // Store triage evidence with proper format int _triageQuestionCount = 0; // Track number of triage questions answered // Selected risk factors tracking @@ -66,8 +63,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { // User Info Flow State int _userInfoCurrentPage = 0; - bool _isSinglePageEditMode = - false; // Track if editing single page or full flow + bool _isSinglePageEditMode = false; // Track if editing single page or full flow String? _selectedGender; DateTime? _dateOfBirth; int? _selectedAge; @@ -107,17 +103,14 @@ class SymptomsCheckerViewModel extends ChangeNotifier { String? get tooltipOrganId => _tooltipOrganId; - String get currentSessionAuthToken => - symptomsUserDetailsResponseModel?.tokenDetails?.authToken ?? ""; + String get currentSessionAuthToken => symptomsUserDetailsResponseModel?.tokenDetails?.authToken ?? ""; - String get currentSessionId => - symptomsUserDetailsResponseModel?.sessionId ?? ""; + String get currentSessionId => symptomsUserDetailsResponseModel?.sessionId ?? ""; // Triage-related getters bool get shouldStopTriage => triageDataDetails?.shouldStop ?? false; - bool get hasEmergencyEvidence => - triageDataDetails?.hasEmergencyEvidence ?? false; + bool get hasEmergencyEvidence => triageDataDetails?.hasEmergencyEvidence ?? false; String? get currentInterviewToken => triageDataDetails?.interviewToken; @@ -137,15 +130,13 @@ class SymptomsCheckerViewModel extends ChangeNotifier { /// Check if all items in current question have been answered bool get areAllTriageItemsAnswered { - if (currentTriageQuestion?.items == null || - currentTriageQuestion!.items!.isEmpty) { + if (currentTriageQuestion?.items == null || currentTriageQuestion!.items!.isEmpty) { return false; } // Check if we have an answer for each item for (var item in currentTriageQuestion!.items!) { - if (item.id != null && - !_selectedTriageChoicesByItemId.containsKey(item.id)) { + if (item.id != null && !_selectedTriageChoicesByItemId.containsKey(item.id)) { return false; } } @@ -153,8 +144,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { } /// Get organs for current view - List get currentOrgans => - OrganData.getOrgansForView(_currentView); + List get currentOrgans => OrganData.getOrgansForView(_currentView); /// Get all selected organs from both views List get selectedOrgans { @@ -162,9 +152,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { ...OrganData.frontViewOrgans, ...OrganData.backViewOrgans, ]; - return allOrgans - .where((organ) => _selectedOrganIds.contains(organ.id)) - .toList(); + return allOrgans.where((organ) => _selectedOrganIds.contains(organ.id)).toList(); } /// Check if any organs are selected @@ -181,13 +169,11 @@ class SymptomsCheckerViewModel extends ChangeNotifier { } int get totalSelectedSymptomsCount { - return _selectedSymptomsByOrgan.values - .fold(0, (sum, symptomIds) => sum + symptomIds.length); + return _selectedSymptomsByOrgan.values.fold(0, (sum, symptomIds) => sum + symptomIds.length); } bool get hasSelectedSymptoms { - return _selectedSymptomsByOrgan.values - .any((symptomIds) => symptomIds.isNotEmpty); + return _selectedSymptomsByOrgan.values.any((symptomIds) => symptomIds.isNotEmpty); } /// Get risk factors list @@ -213,8 +199,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { } void toggleView() { - _currentView = - _currentView == BodyView.front ? BodyView.back : BodyView.front; + _currentView = _currentView == BodyView.front ? BodyView.back : BodyView.front; notifyListeners(); } @@ -317,8 +302,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { return; } - List organNames = - selectedOrgans.map((organ) => organ.name).toList(); + List organNames = selectedOrgans.map((organ) => organ.name).toList(); await getBodySymptomsByName( organNames: organNames, @@ -368,8 +352,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { } } - if (matchingOrganId != null && - _selectedSymptomsByOrgan.containsKey(matchingOrganId)) { + if (matchingOrganId != null && _selectedSymptomsByOrgan.containsKey(matchingOrganId)) { final selectedIds = _selectedSymptomsByOrgan[matchingOrganId]!; if (organResult.bodySymptoms != null) { @@ -420,10 +403,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { /// Get all selected risk factors List getAllSelectedRiskFactors() { - return riskFactorsList - .where((factor) => - factor.id != null && _selectedRiskFactorIds.contains(factor.id)) - .toList(); + return riskFactorsList.where((factor) => factor.id != null && _selectedRiskFactorIds.contains(factor.id)).toList(); } /// Clear all risk factor selections @@ -456,12 +436,11 @@ class SymptomsCheckerViewModel extends ChangeNotifier { } // Extract symptom IDs - List evidenceIds = - selectedSymptoms.where((s) => s.id != null).map((s) => s.id!).toList(); + List evidenceIds = selectedSymptoms.where((s) => s.id != null).map((s) => s.id!).toList(); await getRiskFactors( age: _selectedAge!, - sex: _selectedGender!.toLowerCase(), + gender: _selectedGender!.toLowerCase() == "male" ? 1 : 2, evidenceIds: evidenceIds, sessionId: currentSessionId, language: appState.isArabic() ? 'ar' : 'en', @@ -481,7 +460,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { /// Call Risk Factors API Future getRiskFactors({ required int age, - required String sex, + required int gender, required String sessionId, required List evidenceIds, required String language, @@ -493,12 +472,11 @@ class SymptomsCheckerViewModel extends ChangeNotifier { final result = await symptomsCheckerRepo.getRiskFactors( age: age, - sex: sex, + gender: gender, evidenceIds: evidenceIds, language: language, sessionId: sessionId, userSessionToken: currentSessionAuthToken, - gender: (selectedGender ?? "Male").toLowerCase() == "male" ? 1 : 2, ); result.fold( @@ -515,10 +493,8 @@ class SymptomsCheckerViewModel extends ChangeNotifier { if (apiResponse.messageStatus == 1 && apiResponse.data != null) { riskFactorsResponse = apiResponse.data; - if (riskFactorsResponse != null && - riskFactorsResponse!.dataDetails != null) { - RiskAndSuggestionsItemModel riskFactorItem = - RiskAndSuggestionsItemModel( + if (riskFactorsResponse != null && riskFactorsResponse!.dataDetails != null) { + RiskAndSuggestionsItemModel riskFactorItem = RiskAndSuggestionsItemModel( id: "not_applicable", commonName: "Not Applicable", name: "Not Applicable", @@ -572,10 +548,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { /// Get all selected risk factors List getAllSelectedSuggestions() { - return suggestionsList - .where((factor) => - factor.id != null && _selectedSuggestionsIds.contains(factor.id)) - .toList(); + return suggestionsList.where((factor) => factor.id != null && _selectedSuggestionsIds.contains(factor.id)).toList(); } /// Clear all risk factor selections @@ -590,20 +563,15 @@ class SymptomsCheckerViewModel extends ChangeNotifier { // Add selected symptoms final selectedSymptoms = getAllSelectedSymptoms(); - evidenceIds - .addAll(selectedSymptoms.where((s) => s.id != null).map((s) => s.id!)); + evidenceIds.addAll(selectedSymptoms.where((s) => s.id != null).map((s) => s.id!)); // Add selected risk factors (excluding "not_applicable") final selectedRiskFactors = getAllSelectedRiskFactors(); - evidenceIds.addAll(selectedRiskFactors - .where((rf) => rf.id != null && rf.id != "not_applicable") - .map((rf) => rf.id!)); + evidenceIds.addAll(selectedRiskFactors.where((rf) => rf.id != null && rf.id != "not_applicable").map((rf) => rf.id!)); // Add selected suggestions (excluding "not_applicable") final selectedSuggestions = getAllSelectedSuggestions(); - evidenceIds.addAll(selectedSuggestions - .where((s) => s.id != null && s.id != "not_applicable") - .map((s) => s.id!)); + evidenceIds.addAll(selectedSuggestions.where((s) => s.id != null && s.id != "not_applicable").map((s) => s.id!)); return evidenceIds; } @@ -632,23 +600,19 @@ class SymptomsCheckerViewModel extends ChangeNotifier { } // Extract symptom IDs - List evidenceIds = - selectedSymptoms.where((s) => s.id != null).map((s) => s.id!).toList(); + List evidenceIds = selectedSymptoms.where((s) => s.id != null).map((s) => s.id!).toList(); // Get all selected symptoms final selectedRisks = getAllSelectedRiskFactors(); if (selectedRisks.isNotEmpty) { - List evidenceRisksIds = selectedRisks - .where((s) => s.id != null && s.id != "not_applicable") - .map((s) => s.id!) - .toList(); + List evidenceRisksIds = selectedRisks.where((s) => s.id != null && s.id != "not_applicable").map((s) => s.id!).toList(); evidenceIds.addAll(evidenceRisksIds); } await getSuggestions( age: _selectedAge!, - sex: _selectedGender!.toLowerCase(), + gender: _selectedGender!.toLowerCase() == "male" ? 1 : 2, evidenceIds: evidenceIds, language: appState.isArabic() ? 'ar' : 'en', onSuccess: (response) { @@ -667,7 +631,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { /// Call Suggestions API Future getSuggestions({ required int age, - required String sex, + required int gender, required List evidenceIds, required String language, Function(RiskAndSuggestionsResponseModel)? onSuccess, @@ -678,12 +642,11 @@ class SymptomsCheckerViewModel extends ChangeNotifier { final result = await symptomsCheckerRepo.getSuggestions( age: age, - sex: sex, + gender: gender, evidenceIds: evidenceIds, language: language, sessionId: currentSessionId, userSessionToken: currentSessionAuthToken, - gender: (selectedGender ?? "Male").toLowerCase() == "male" ? 1 : 2, ); result.fold( @@ -700,10 +663,8 @@ class SymptomsCheckerViewModel extends ChangeNotifier { if (apiResponse.messageStatus == 1 && apiResponse.data != null) { suggestionsResponse = apiResponse.data; - if (suggestionsResponse != null && - suggestionsResponse!.dataDetails != null) { - RiskAndSuggestionsItemModel riskFactorItem = - RiskAndSuggestionsItemModel( + if (suggestionsResponse != null && suggestionsResponse!.dataDetails != null) { + RiskAndSuggestionsItemModel riskFactorItem = RiskAndSuggestionsItemModel( id: "not_applicable", commonName: "Not Applicable", name: "Not Applicable", @@ -730,7 +691,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { /// Call Diagnosis API for Triage - This is called iteratively until shouldStop is true Future getDiagnosisForTriage({ required int age, - required String sex, + required int gender, required List evidenceIds, List>? triageEvidence, required String language, @@ -742,13 +703,12 @@ class SymptomsCheckerViewModel extends ChangeNotifier { final result = await symptomsCheckerRepo.getDiagnosisForTriage( age: age, - sex: sex, + gender: gender, evidenceIds: evidenceIds, triageEvidence: triageEvidence, language: language, sessionId: currentSessionId, userSessionToken: currentSessionAuthToken, - gender: (selectedGender ?? "Male").toLowerCase() == "male" ? 1 : 2, ); result.fold( @@ -804,7 +764,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { await getDiagnosisForTriage( age: _selectedAge!, - sex: _selectedGender!.toLowerCase(), + gender: _selectedGender!.toLowerCase() == "male" ? 1 : 2, evidenceIds: evidenceIds, language: appState.isArabic() ? 'ar' : 'en', onSuccess: (response) { @@ -941,8 +901,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { // Calculate age from date of birth final now = DateTime.now(); int age = now.year - dateOfBirth.year; - if (now.month < dateOfBirth.month || - (now.month == dateOfBirth.month && now.day < dateOfBirth.day)) { + if (now.month < dateOfBirth.month || (now.month == dateOfBirth.month && now.day < dateOfBirth.day)) { age--; } _selectedAge = age; @@ -989,8 +948,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { }) async { isBodySymptomsLoading = true; notifyListeners(); - final result = await symptomsCheckerRepo.getUserDetails( - userName: userName, password: password); + final result = await symptomsCheckerRepo.getUserDetails(userName: userName, password: password); result.fold( (failure) async { diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index 29b4fe6..80e0f9b 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -50,7 +50,14 @@ class ServicesPage extends StatelessWidget { late MedicalFileViewModel medicalFileViewModel; late final List hmgServices = [ - HmgServicesComponentModel(11, LocaleKeys.emergencyServices.tr(), "", AppAssets.emergency_services_icon, bgColor: AppColors.primaryRedColor, true, route: null, onTap: () async { + HmgServicesComponentModel( + 11, + LocaleKeys.emergencyServices.tr(), + "", + AppAssets.emergency_services_icon, + bgColor: AppColors.primaryRedColor, + true, + route: null, onTap: () async { if (getIt.get().isAuthenticated) { getIt.get().flushData(); getIt.get().getTransportationOrders( @@ -59,7 +66,7 @@ class ServicesPage extends StatelessWidget { getIt.get().getRRTOrders( showLoader: false, ); - Navigator.of(GetIt.instance().navigatorKey.currentContext!).push( + Navigator.of(getIt.get().navigatorKey.currentContext!).push( CustomPageRoute( page: EmergencyServicesPage(), settings: const RouteSettings(name: '/EmergencyServicesPage'), @@ -78,7 +85,8 @@ class ServicesPage extends StatelessWidget { true, route: AppRoutes.bookAppointmentPage, ), - HmgServicesComponentModel(5, LocaleKeys.completeCheckup.tr(), "", AppAssets.comprehensiveCheckup, bgColor: AppColors.bgGreenColor, true, route: null, onTap: () async { + HmgServicesComponentModel( + 5, LocaleKeys.completeCheckup.tr(), "", AppAssets.comprehensiveCheckup, bgColor: AppColors.bgGreenColor, true, route: null, onTap: () async { if (getIt.get().isAuthenticated) { getIt.get().pushPageRoute(AppRoutes.comprehensiveCheckupPage); } else { @@ -131,7 +139,7 @@ class ServicesPage extends StatelessWidget { }, ), HmgServicesComponentModel( - 11, LocaleKeys.eReferralServices.tr(), "", AppAssets.eReferral, bgColor: AppColors.eReferralCardColor, true, route: null, onTap: () async { + 11, LocaleKeys.eReferralServices.tr(), "", AppAssets.eReferral, bgColor: AppColors.eReferralCardColor, true, route: null, onTap: () async { if (getIt.get().isAuthenticated) { getIt.get().pushPageRoute(AppRoutes.eReferralPage); } else { @@ -393,19 +401,19 @@ class ServicesPage extends StatelessWidget { ? CustomButton( height: 40.h, icon: AppAssets.recharge_icon, - iconSize: 16.w, - iconColor: AppColors.infoColor, - textColor: AppColors.infoColor, - text: LocaleKeys.recharge.tr(), - borderWidth: 0.w, - fontWeight: FontWeight.w500, - borderColor: Colors.transparent, - backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), - padding: EdgeInsets.all(8.w), - fontSize: 12.f, - onPressed: () { - Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); - }, + iconSize: 16.w, + iconColor: AppColors.infoColor, + textColor: AppColors.infoColor, + text: LocaleKeys.recharge.tr(), + borderWidth: 0.w, + fontWeight: FontWeight.w500, + borderColor: Colors.transparent, + backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), + padding: EdgeInsets.all(8.w), + fontSize: 12.f, + onPressed: () { + Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); + }, ) : SizedBox.shrink(), ], @@ -477,27 +485,27 @@ class ServicesPage extends StatelessWidget { getIt.get().isAuthenticated ? CustomButton( height: 40.h, - icon: AppAssets.add_icon, - iconSize: 16.w, - iconColor: AppColors.primaryRedColor, - textColor: AppColors.primaryRedColor, - text: LocaleKeys.addMember.tr(), - borderWidth: 0.w, - fontWeight: FontWeight.w500, - borderColor: Colors.transparent, - backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08), - padding: EdgeInsets.all(8.w), - fontSize: 12.f, - onPressed: () { - DialogService dialogService = getIt.get(); - medicalFileViewModel.clearAuthValues(); - dialogService.showAddFamilyFileSheet( - label: LocaleKeys.addFamilyMember.tr(), - message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(), - onVerificationPress: () { - medicalFileViewModel.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); - }); - }, + icon: AppAssets.add_icon, + iconSize: 16.w, + iconColor: AppColors.primaryRedColor, + textColor: AppColors.primaryRedColor, + text: LocaleKeys.addMember.tr(), + borderWidth: 0.w, + fontWeight: FontWeight.w500, + borderColor: Colors.transparent, + backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.08), + padding: EdgeInsets.all(8.w), + fontSize: 12.f, + onPressed: () { + DialogService dialogService = getIt.get(); + medicalFileViewModel.clearAuthValues(); + dialogService.showAddFamilyFileSheet( + label: LocaleKeys.addFamilyMember.tr(), + message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(), + onVerificationPress: () { + medicalFileViewModel.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); + }); + }, ) : SizedBox.shrink(), ], diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index fc400c4..5ea5b21 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -28,7 +28,6 @@ import 'package:hmg_patient_app_new/features/my_appointments/appointment_rating_ import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/notifications/notifications_view_model.dart'; -import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart'; import 'package:hmg_patient_app_new/features/todo_section/todo_section_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/appointments/appointment_queue_page.dart'; @@ -62,8 +61,6 @@ import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:hmg_patient_app_new/widgets/routes/spring_page_route_builder.dart'; import 'package:provider/provider.dart'; -import '../active_medication/active_medication_page.dart'; - import '../emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart'; class LandingPage extends StatefulWidget { @@ -394,22 +391,23 @@ class _LandingPageState extends State { layout: SwiperLayout.STACK, loop: true, itemWidth: MediaQuery.of(context).size.width - 48.h, - indicatorLayout: PageIndicatorLayout.COLOR, - axisDirection: AxisDirection.right, - controller: _controller, - itemHeight: 255.h, - pagination: SwiperPagination( - alignment: Alignment.bottomCenter, - margin: EdgeInsets.only(top: 240.h + 8 + 24), - builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor), - ), - itemBuilder: (BuildContext context, int index) { - return getIndexSwiperCard(index); - }, - ) + indicatorLayout: PageIndicatorLayout.COLOR, + axisDirection: AxisDirection.right, + controller: _controller, + itemHeight: 255.h, + pagination: SwiperPagination( + alignment: Alignment.bottomCenter, + margin: EdgeInsets.only(top: 240.h + 8 + 24), + builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor), + ), + itemBuilder: (BuildContext context, int index) { + return getIndexSwiperCard(index); + }, + ) : Container( width: double.infinity, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), + decoration: RoundedRectangleBorder() + .toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), child: Padding( padding: EdgeInsets.all(16.h), child: Column( @@ -469,7 +467,11 @@ class _LandingPageState extends State { backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.10), textColor: AppColors.primaryRedColor, ), - Utils.buildSvgWithAssets(icon: AppAssets.appointment_checkin_icon, width: 24.h, height: 24.h, iconColor: AppColors.primaryRedColor), + Utils.buildSvgWithAssets( + icon: AppAssets.appointment_checkin_icon, + width: 24.h, + height: 24.h, + iconColor: AppColors.primaryRedColor), ], ), SizedBox(height: 8.h), @@ -690,10 +692,18 @@ class _LandingPageState extends State { myAppointmentsViewModel.patientQueueDetailsList.first.queueNo!.toText12(isBold: true), SizedBox(width: 8.w), AppCustomChipWidget( - deleteIcon: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 ? AppAssets.call_for_vitals : AppAssets.call_for_doctor, - labelText: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 ? LocaleKeys.callForVitalSigns.tr() : LocaleKeys.callForDoctor.tr(), - iconColor: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 ? AppColors.primaryRedColor : AppColors.successColor, - textColor: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 ? AppColors.primaryRedColor : AppColors.successColor, + deleteIcon: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 + ? AppAssets.call_for_vitals + : AppAssets.call_for_doctor, + labelText: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 + ? LocaleKeys.callForVitalSigns.tr() + : LocaleKeys.callForDoctor.tr(), + iconColor: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 + ? AppColors.primaryRedColor + : AppColors.successColor, + textColor: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 + ? AppColors.primaryRedColor + : AppColors.successColor, iconSize: 14.w, backgroundColor: myAppointmentsViewModel.patientQueueDetailsList.first.callType == 1 ? AppColors.primaryRedColor.withValues(alpha: 0.1) @@ -707,7 +717,8 @@ class _LandingPageState extends State { : SizedBox(height: 12.h), SizedBox(height: 5.h), CustomButton( - text: Utils.getCardButtonText(myAppointmentsViewModel.currentQueueStatus, myAppointmentsViewModel.currentPatientQueueDetails.roomNo ?? ""), + text: Utils.getCardButtonText( + myAppointmentsViewModel.currentQueueStatus, myAppointmentsViewModel.currentPatientQueueDetails.roomNo ?? ""), onPressed: () {}, backgroundColor: Utils.getCardButtonColor(myAppointmentsViewModel.currentQueueStatus), borderColor: Utils.getCardButtonColor(myAppointmentsViewModel.currentQueueStatus).withValues(alpha: 0.01), @@ -761,7 +772,8 @@ class _LandingPageState extends State { SizedBox(width: 8.w), AppCustomChipWidget( icon: AppAssets.appointment_calendar_icon, - labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(immediateLiveCareViewModel.patientLiveCareHistoryList[0].arrivalTime), false)), + labelText: DateUtil.formatDateToDate( + DateUtil.convertStringToDate(immediateLiveCareViewModel.patientLiveCareHistoryList[0].arrivalTime), false)), ], ), Utils.buildSvgWithAssets(icon: AppAssets.waiting_icon, width: 24.h, height: 24.h), @@ -769,9 +781,12 @@ class _LandingPageState extends State { ], ), SizedBox(height: 10.h), - LocaleKeys.halaFirstName.tr(namedArgs: {'firstName': appState.getAuthenticatedUser()!.firstName!}, context: context).toText16(isBold: true), + LocaleKeys.halaFirstName + .tr(namedArgs: {'firstName': appState.getAuthenticatedUser()!.firstName!}, context: context).toText16(isBold: true), SizedBox(height: 8.h), - LocaleKeys.yourTurnIsAfterPatients.tr(namedArgs: {'count': immediateLiveCareViewModel.patientLiveCareHistoryList[0].patCount.toString()}, context: context).toText14(isBold: true), + LocaleKeys.yourTurnIsAfterPatients.tr( + namedArgs: {'count': immediateLiveCareViewModel.patientLiveCareHistoryList[0].patCount.toString()}, + context: context).toText14(isBold: true), SizedBox(height: 8.h), Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -978,7 +993,6 @@ class _LandingPageState extends State { isCloseButtonVisible: true, child: StatefulBuilder( builder: (context, setState) { - return RateAppointmentDoctor(); }, ), diff --git a/lib/presentation/home/navigation_screen.dart b/lib/presentation/home/navigation_screen.dart index 43cc3b9..b22e46b 100644 --- a/lib/presentation/home/navigation_screen.dart +++ b/lib/presentation/home/navigation_screen.dart @@ -8,11 +8,8 @@ import 'package:hmg_patient_app_new/presentation/contact_us/feedback_page.dart'; import 'package:hmg_patient_app_new/presentation/hmg_services/services_page.dart'; import 'package:hmg_patient_app_new/presentation/home/landing_page.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; -import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection.dart'; -import 'package:hmg_patient_app_new/presentation/todo_section/todo_page.dart'; import 'package:hmg_patient_app_new/routes/app_routes.dart'; import 'package:hmg_patient_app_new/widgets/bottom_navigation/bottom_navigation.dart'; -import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; class LandingNavigation extends StatefulWidget { const LandingNavigation({super.key}); @@ -53,11 +50,7 @@ class _LandingNavigationState extends State { } if (_currentIndex == 3) { if (appState.isAuthenticated) { - Navigator.of(context).push( - CustomPageRoute( - page: UserInfoSelectionScreen(), - ), - ); + context.navigateWithName(AppRoutes.userInfoSelection); } else { Utils.openWebView( url: 'https://x.com/HMG', diff --git a/lib/presentation/symptoms_checker/possible_conditions_screen.dart b/lib/presentation/symptoms_checker/possible_conditions_screen.dart index bc233a4..858218d 100644 --- a/lib/presentation/symptoms_checker/possible_conditions_screen.dart +++ b/lib/presentation/symptoms_checker/possible_conditions_screen.dart @@ -3,13 +3,14 @@ import 'package:flutter/material.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/dependencies.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/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/features/symptoms_checker/models/conditions_model.dart'; -import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/triage_response_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/presentation/symptoms_checker/widgets/condition_card.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; @@ -45,7 +46,7 @@ class PossibleConditionsPage extends StatelessWidget { ); } - Widget _buildPredictionsList(BuildContext context, List conditions) { + Widget _buildPredictionsList(BuildContext context, List conditions, List symptoms) { if (conditions.isEmpty) { return Center( child: Padding( @@ -74,19 +75,13 @@ class PossibleConditionsPage extends StatelessWidget { physics: NeverScrollableScrollPhysics(), separatorBuilder: (context, index) => SizedBox(height: 16.h), itemBuilder: (context, index) { - final conditionModel = conditions[index]; + final condition = conditions[index]; return ConditionCard( - icon: conditionModel.icon, - title: conditionModel.title, - percentage: conditionModel.percentage, - tagText: conditionModel.tagText, - clinic: conditionModel.clinic, - symptoms: conditionModel.symptoms, - description: conditionModel.description, - possibleConditionsSeverityEnum: conditionModel.possibleConditionsSeverityEnum, + condition: condition, + symptoms: symptoms, onActionPressed: () { dialogService.showErrorBottomSheet( - message: 'We are not available for a week. May you Rest In Peace :(', + message: 'icd10 Code is ${condition.conditionDetails?.icd10Code}. We need to get the clinics mapped against this code.', ); }, ); @@ -102,7 +97,7 @@ class PossibleConditionsPage extends StatelessWidget { title: LocaleKeys.notice.tr(context: context), context, child: Utils.getWarningWidget( - loadingText: LocaleKeys.areYouSureYouWantToRestartOrganSelection.tr(context: context), + loadingText: LocaleKeys.areYouSureYouWantToExitProgress.tr(context: context), isShowActionButtons: true, onCancelTap: () => Navigator.pop(context), onConfirmTap: () => onConfirm(), @@ -113,47 +108,88 @@ class PossibleConditionsPage extends StatelessWidget { ); } - _restartOrganSelection(BuildContext context) async { - final symptomsCheckerVm = context.read(); - symptomsCheckerVm.reset(); - context.pop(); - await Future.delayed(Duration(seconds: 1)).whenComplete(() => context.pop()); - } + Widget _buildInfoTile({required PossibleConditionsSeverityEnum severityEnum}) { + String title; + String description; + Color dotColor; - _navigateToLandingPage() { - NavigationService navigationService = getIt.get(); - navigationService.replaceAllRoutesAndNavigateToLanding(); - } + switch (severityEnum) { + case PossibleConditionsSeverityEnum.monitorOnly: + title = "Monitor".needTranslation; + description = "No need to seek medical advice. Just keep healthy routine.".needTranslation; + dotColor = AppColors.chipColorMonitor; + break; + case PossibleConditionsSeverityEnum.seekMedicalAdvice: + title = "Seek Medical Advice".needTranslation; + description = "Not emergency but better to monitor the symptoms.".needTranslation; + dotColor = AppColors.chipColorSeekMedicalAdvice; + break; + case PossibleConditionsSeverityEnum.emergency: + title = "Emergency".needTranslation; + description = "Need to consult doctor as soon as possible before getting too late.".needTranslation; + dotColor = AppColors.chipColorEmergency; + break; + } - _buildTrailingSection(BuildContext context) { return Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - height: 40.h, - padding: EdgeInsets.all(8.w), - child: Center( - child: Utils.buildSvgWithAssets( - icon: AppAssets.refreshIcon, - height: 20.h, - width: 20.w, - iconColor: AppColors.textColor, - ), + height: 14.h, + width: 14.w, + decoration: BoxDecoration(shape: BoxShape.circle, color: dotColor), + ).paddingOnly(top: 3.h), + SizedBox(width: 8.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + title.toText14(weight: FontWeight.w600, color: AppColors.textColor), + SizedBox(height: 4.h), + description.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + ], ), - ).onPress(() => _buildConfirmationBottomSheet(context: context, onConfirm: () => _restartOrganSelection(context))), - Container( - height: 40.h, - padding: EdgeInsets.all(8.w), - child: Center( - child: Utils.buildSvgWithAssets( - icon: AppAssets.homeBorderedIcon, - height: 20.h, - width: 20.w, - iconColor: AppColors.textColor, - ), - ), - ).onPress(() => _buildConfirmationBottomSheet(context: context, onConfirm: () => _navigateToLandingPage())), + ), ], - ).paddingSymmetrical(20.w, 0); + ); + } + + _buildSeverityDetailsBottomsheet({required BuildContext context}) { + return showCommonBottomSheetWithoutHeight( + title: "Color Science".needTranslation, + context, + child: Container( + padding: EdgeInsets.all(16.w), + width: double.infinity, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), + child: Column( + children: [ + _buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.monitorOnly), + Divider(color: AppColors.bottomNAVBorder, height: 24.h, thickness: 1), + _buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.seekMedicalAdvice), + Divider(color: AppColors.bottomNAVBorder, height: 24.h, thickness: 1), + _buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.emergency), + ], + ), + ), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } + + _buildTrailingSection(BuildContext context) { + return Container( + height: 40.h, + padding: EdgeInsets.all(8.w), + child: Center( + child: Utils.buildSvgWithAssets( + icon: AppAssets.coloredDotsIcon, + height: 20.h, + width: 20.w, + ), + ), + ).onPress(() => _buildSeverityDetailsBottomsheet(context: context)); } @override @@ -162,13 +198,32 @@ class PossibleConditionsPage extends StatelessWidget { backgroundColor: AppColors.bgScaffoldColor, body: CollapsingListView( title: LocaleKeys.possibleConditions.tr(context: context), + leadingCallback: () => _buildConfirmationBottomSheet( + context: context, + onConfirm: () { + context.pop(); + final SymptomsCheckerViewModel symptomsCheckerViewModel = context.read(); + symptomsCheckerViewModel.reset(); // Clear all symptoms checker data + final navigationService = getIt.get(); + navigationService.replaceAllRoutesAndNavigateToLanding(); + }, + ), trailing: _buildTrailingSection(context), child: Consumer( builder: (context, symptomsCheckerViewModel, child) { - if (symptomsCheckerViewModel.isPossibleConditionsLoading || symptomsCheckerViewModel.isPossibleConditionsLoading) { + if (symptomsCheckerViewModel.isPossibleConditionsLoading || symptomsCheckerViewModel.isTriageDiagnosisLoading) { return _buildLoadingShimmer(); } - return _buildPredictionsList(context, dummyConditions); + // Get conditions directly from ViewModel + final conditions = symptomsCheckerViewModel.currentConditions ?? []; + // Get selected symptoms names for display + final symptoms = symptomsCheckerViewModel + .getAllSelectedSymptoms() + .map((s) => s.commonName ?? s.name ?? '') + .where((name) => name.isNotEmpty) + .take(3) + .toList(); + return _buildPredictionsList(context, conditions, symptoms); }, ), ), diff --git a/lib/presentation/symptoms_checker/risk_factors_screen.dart b/lib/presentation/symptoms_checker/risk_factors_screen.dart index 6ee4f29..da41d78 100644 --- a/lib/presentation/symptoms_checker/risk_factors_screen.dart +++ b/lib/presentation/symptoms_checker/risk_factors_screen.dart @@ -196,7 +196,7 @@ class _RiskFactorsScreenState extends State { border: Border.all(color: AppColors.bottomNAVBorder, width: 1), ), child: Text( - 'Not Applicable Risk Factor', + 'Not Applicable Risk Factor'.needTranslation, style: TextStyle(fontSize: 14.f, color: AppColors.textColor), ), ).toShimmer2(isShow: true, radius: 24.r); diff --git a/lib/presentation/symptoms_checker/symptoms_selector_screen.dart b/lib/presentation/symptoms_checker/symptoms_selector_screen.dart index b4ba802..b241b44 100644 --- a/lib/presentation/symptoms_checker/symptoms_selector_screen.dart +++ b/lib/presentation/symptoms_checker/symptoms_selector_screen.dart @@ -4,12 +4,12 @@ import 'package:hmg_patient_app_new/core/app_export.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/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/features/symptoms_checker/models/resp_models/body_symptom_response_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/services/dialog_service.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.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/buttons/custom_button.dart'; @@ -82,10 +82,12 @@ class _SymptomsSelectorPageState extends State { title: LocaleKeys.symptomsSelector.tr(), leadingCallback: () => _buildConfirmationBottomSheet( context: context, - onConfirm: () => { - context.pop(), - context.pop(), - }), + onConfirm: () { + context.pop(); + viewModel.reset(); // Clear all symptoms checker data + final navigationService = getIt.get(); + navigationService.replaceAllRoutesAndNavigateToLanding(); + }), child: viewModel.isBodySymptomsLoading ? _buildLoadingShimmer() : viewModel.organSymptomsResults.isEmpty diff --git a/lib/presentation/symptoms_checker/triage_screen.dart b/lib/presentation/symptoms_checker/triage_screen.dart index 526136c..c0d48d6 100644 --- a/lib/presentation/symptoms_checker/triage_screen.dart +++ b/lib/presentation/symptoms_checker/triage_screen.dart @@ -14,6 +14,7 @@ import 'package:hmg_patient_app_new/features/symptoms_checker/symptoms_checker_v import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/widgets/custom_progress_bar.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.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/buttons/custom_button.dart'; @@ -119,12 +120,14 @@ class _TriagePageState extends State { SizedBox(height: 8.h), LocaleKeys.emergencyTriage.tr(context: context).toText28(color: AppColors.whiteColor, isBold: true), SizedBox(height: 8.h), - LocaleKeys.emergencyEvidenceDetected.tr(context: context) - .toText14(color: AppColors.whiteColor, weight: FontWeight.w500), + LocaleKeys.emergencyEvidenceDetected.tr(context: context).toText14(color: AppColors.whiteColor, weight: FontWeight.w500), SizedBox(height: 24.h), CustomButton( text: LocaleKeys.confirm.tr(context: context), - onPressed: () async => Navigator.of(context).pop(), + onPressed: () { + context.pop(); + context.navigateWithName(AppRoutes.possibleConditionsPage); + }, backgroundColor: AppColors.whiteColor, borderColor: AppColors.whiteColor, textColor: AppColors.primaryRedColor, @@ -197,7 +200,7 @@ class _TriagePageState extends State { // Call API with updated evidence viewModel.getDiagnosisForTriage( age: viewModel.selectedAge!, - sex: viewModel.selectedGender!.toLowerCase(), + gender: viewModel.selectedGender!.toLowerCase() == "male" ? 1 : 2, evidenceIds: initialEvidenceIds, triageEvidence: triageEvidence, language: viewModel.appState.isArabic() ? 'ar' : 'en', @@ -307,8 +310,10 @@ class _TriagePageState extends State { isShowActionButtons: true, onCancelTap: () => Navigator.pop(context), onConfirmTap: () { - Navigator.pop(context); context.pop(); + viewModel.reset(); // Clear all symptoms checker data + final navigationService = getIt.get(); + navigationService.replaceAllRoutesAndNavigateToLanding(); }, ), callBackFunc: () {}, diff --git a/lib/presentation/symptoms_checker/user_info_selection.dart b/lib/presentation/symptoms_checker/user_info_selection.dart index 9973d54..78eb916 100644 --- a/lib/presentation/symptoms_checker/user_info_selection.dart +++ b/lib/presentation/symptoms_checker/user_info_selection.dart @@ -16,14 +16,14 @@ import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:provider/provider.dart'; -class UserInfoSelectionScreen extends StatefulWidget { - const UserInfoSelectionScreen({super.key}); +class UserInfoSelectionPage extends StatefulWidget { + const UserInfoSelectionPage({super.key}); @override - State createState() => _UserInfoSelectionScreenState(); + State createState() => _UserInfoSelectionPageState(); } -class _UserInfoSelectionScreenState extends State { +class _UserInfoSelectionPageState extends State { @override void initState() { super.initState(); @@ -155,10 +155,12 @@ class _UserInfoSelectionScreenState extends State { // Show age calculated from DOB (prefer viewModel's age, fallback to calculated from user's DOB) int? displayAge = viewModel.selectedAge ?? userAgeFromDOB; String ageText = displayAge != null ? "$displayAge ${LocaleKeys.years.tr(context: context)}" : LocaleKeys.notSet.tr(context: context); - String heightText = - viewModel.selectedHeight != null ? "${viewModel.selectedHeight!.round()} ${viewModel.isHeightCm ? 'cm' : 'ft'}" : LocaleKeys.notSet.tr(context: context); - String weightText = - viewModel.selectedWeight != null ? "${viewModel.selectedWeight!.round()} ${viewModel.isWeightKg ? 'kg' : 'lbs'}" : LocaleKeys.notSet.tr(context: context); + String heightText = viewModel.selectedHeight != null + ? "${viewModel.selectedHeight!.round()} ${viewModel.isHeightCm ? 'cm' : 'ft'}" + : LocaleKeys.notSet.tr(context: context); + String weightText = viewModel.selectedWeight != null + ? "${viewModel.selectedWeight!.round()} ${viewModel.isWeightKg ? 'kg' : 'lbs'}" + : LocaleKeys.notSet.tr(context: context); return Column( children: [ @@ -176,9 +178,9 @@ class _UserInfoSelectionScreenState extends State { child: Column( children: [ LocaleKeys.helloIsYourInformationUpToDate.tr(namedArgs: {'name': name}).toText16( - weight: FontWeight.w600, - color: AppColors.textColor, - ), + weight: FontWeight.w600, + color: AppColors.textColor, + ), SizedBox(height: 32.h), _buildEditInfoTile( context: context, diff --git a/lib/presentation/symptoms_checker/widgets/condition_card.dart b/lib/presentation/symptoms_checker/widgets/condition_card.dart index b89eac2..b95e55c 100644 --- a/lib/presentation/symptoms_checker/widgets/condition_card.dart +++ b/lib/presentation/symptoms_checker/widgets/condition_card.dart @@ -5,6 +5,7 @@ import 'package:hmg_patient_app_new/core/app_export.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/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/symptoms_checker/models/resp_models/triage_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/symptoms_checker/widgets/custom_progress_bar.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; @@ -12,33 +13,128 @@ import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; class ConditionCard extends StatelessWidget { - final IconData icon; - final String title; - final int percentage; - final String tagText; - final String clinic; + final TriageCondition condition; final List symptoms; - final String description; - final String? monitorNote; - final String? appointmentLabel; - final PossibleConditionsSeverityEnum possibleConditionsSeverityEnum; final VoidCallback? onActionPressed; const ConditionCard({ super.key, - required this.icon, - required this.title, - required this.percentage, - required this.tagText, - required this.clinic, + required this.condition, required this.symptoms, - required this.description, - this.monitorNote, - this.appointmentLabel, - required this.possibleConditionsSeverityEnum, this.onActionPressed, }); + /// Get title from condition + String get title => condition.commonName ?? condition.name ?? ''; + + /// Get percentage from probability (0-1 to 0-100) + int get percentage => ((condition.probability ?? 0) * 100).toInt(); + + /// Get clinic name from category + String get clinic => condition.conditionDetails?.category?.name ?? ''; + + /// Get description from hint + String get description => condition.conditionDetails?.hint ?? ''; + + /// Get severity enum based on triage level + PossibleConditionsSeverityEnum get severityEnum { + final triageLevel = condition.conditionDetails?.triageLevel; + if (triageLevel != null) { + switch (triageLevel) { + case TriageLevelEnum.emergencyAmbulance: + case TriageLevelEnum.emergency: + return PossibleConditionsSeverityEnum.emergency; + case TriageLevelEnum.consultation24: + case TriageLevelEnum.consultation: + return PossibleConditionsSeverityEnum.seekMedicalAdvice; + case TriageLevelEnum.selfCare: + return PossibleConditionsSeverityEnum.monitorOnly; + } + } + // Default based on probability + if (percentage >= 70) { + return PossibleConditionsSeverityEnum.seekMedicalAdvice; + } else { + return PossibleConditionsSeverityEnum.monitorOnly; + } + } + + /// Get tag text based on triage level + String getTagText(BuildContext context) { + final triageLevel = condition.conditionDetails?.triageLevel; + if (triageLevel != null) { + switch (triageLevel) { + case TriageLevelEnum.emergencyAmbulance: + case TriageLevelEnum.emergency: + return LocaleKeys.emergency.tr(context: context); + case TriageLevelEnum.consultation24: + case TriageLevelEnum.consultation: + return "Seek Medical Advice".needTranslation; + case TriageLevelEnum.selfCare: + return LocaleKeys.monitor.tr(context: context); + } + } + // Default based on probability + if (percentage >= 70) { + return "Seek Medical Advice".needTranslation; + } else { + return LocaleKeys.monitor.tr(context: context); + } + } + + /// Get monitor note if applicable + String? getMonitorNote(BuildContext context) { + if (severityEnum == PossibleConditionsSeverityEnum.monitorOnly) { + return "No need to visit doctor".needTranslation; + } + return null; + } + + /// Get icon based on category name from API + IconData get icon { + final categoryName = condition.conditionDetails?.category?.name?.toLowerCase() ?? ''; + + if (categoryName.contains('cardio') || categoryName.contains('heart')) { + return Icons.favorite; + } else if (categoryName.contains('neuro') || categoryName.contains('brain')) { + return Icons.psychology_alt; + } else if (categoryName.contains('psychiatr') || categoryName.contains('mental')) { + return Icons.psychology; + } else if (categoryName.contains('eye') || categoryName.contains('ophthalmo')) { + return Icons.remove_red_eye; + } else if (categoryName.contains('ent') || categoryName.contains('ear')) { + return Icons.hearing; + } else if (categoryName.contains('derma') || categoryName.contains('skin')) { + return Icons.face; + } else if (categoryName.contains('ortho') || categoryName.contains('bone')) { + return Icons.accessibility_new; + } else if (categoryName.contains('gyneco') || categoryName.contains('obstet')) { + return Icons.pregnant_woman; + } else if (categoryName.contains('pediatr') || categoryName.contains('child')) { + return Icons.child_care; + } else if (categoryName.contains('surg')) { + return Icons.local_hospital; + } else if (categoryName.contains('pulmo') || categoryName.contains('lung') || categoryName.contains('respiratory')) { + return Icons.air; + } else if (categoryName.contains('gastro') || categoryName.contains('digest')) { + return Icons.restaurant; + } else if (categoryName.contains('nephro') || categoryName.contains('kidney')) { + return Icons.water_drop; + } else if (categoryName.contains('hemato') || categoryName.contains('blood')) { + return Icons.bloodtype; + } else if (categoryName.contains('infect') || categoryName.contains('virus')) { + return Icons.coronavirus; + } else if (categoryName.contains('emergency')) { + return Icons.emergency; + } else if (categoryName.contains('geriatr') || categoryName.contains('elder')) { + return Icons.elderly; + } else if (categoryName.contains('internal')) { + return Icons.medical_services; + } + + return Icons.medical_services; + } + Color getChipColorBySeverityEnum(PossibleConditionsSeverityEnum possibleConditionsSeverityEnum) { switch (possibleConditionsSeverityEnum) { case PossibleConditionsSeverityEnum.seekMedicalAdvice: @@ -67,7 +163,7 @@ class ConditionCard extends StatelessWidget { crossAxisAlignment: WrapCrossAlignment.center, children: [ for (int i = 0; i < symptoms.length; i++) ...[ - Text(symptoms[i], style: TextStyle(color: AppColors.greyTextColor, fontWeight: FontWeight.w500, fontSize: 12.f)), + "● ${symptoms[i]}".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), if (i != symptoms.length - 1) Padding( padding: EdgeInsets.symmetric(horizontal: 2.w), @@ -80,9 +176,12 @@ class ConditionCard extends StatelessWidget { @override Widget build(BuildContext context) { + // final monitorNote = getMonitorNote(context); + final tagText = getTagText(context); + return Container( width: double.infinity, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -90,14 +189,14 @@ class ConditionCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - width: 48.w, - height: 48.w, + width: 32.w, + height: 32.w, decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: getChipColorBySeverityEnum(possibleConditionsSeverityEnum).withValues(alpha: 0.2), - borderRadius: 12.r, + color: getChipColorBySeverityEnum(severityEnum).withValues(alpha: 0.2), + borderRadius: 8.r, hasShadow: false, ), - child: Icon(icon, color: getChipTextColorBySeverityEnum(possibleConditionsSeverityEnum), size: 24.f), + child: Icon(icon, color: getChipTextColorBySeverityEnum(severityEnum), size: 16.f), ), SizedBox(width: 12.w), Expanded( @@ -108,34 +207,23 @@ class ConditionCard extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( - child: Text( - title, - style: TextStyle(fontSize: 18.f, fontWeight: FontWeight.w600, color: AppColors.textColor), - overflow: TextOverflow.ellipsis, - ), + child: title.toText18(weight: FontWeight.w600, color: AppColors.textColor), ), AppCustomChipWidget( labelText: tagText, - backgroundColor: getChipColorBySeverityEnum(possibleConditionsSeverityEnum).withValues(alpha: 0.2), - textColor: getChipTextColorBySeverityEnum(possibleConditionsSeverityEnum), + backgroundColor: getChipColorBySeverityEnum(severityEnum).withValues(alpha: 0.2), + textColor: getChipTextColorBySeverityEnum(severityEnum), ), ], ), CustomRoundedProgressBar( percentage: percentage, height: 6.h, - color: getChipColorBySeverityEnum(possibleConditionsSeverityEnum), + color: getChipColorBySeverityEnum(severityEnum), backgroundColor: AppColors.scaffoldBgColor, titleWidget: Row( children: [ - Text( - "$percentage%", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 12.f, - color: getChipColorBySeverityEnum(possibleConditionsSeverityEnum), - ), - ), + "$percentage%".toText12(fontWeight: FontWeight.bold, color: getChipColorBySeverityEnum(severityEnum)), ], ).paddingSymmetrical(0, 4.h), ), @@ -148,50 +236,42 @@ class ConditionCard extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - clinic, - style: TextStyle( - fontWeight: FontWeight.w600, - fontSize: 14.f, - color: AppColors.textColor, - ), - ), + "Common Symptom".needTranslation.toText14(weight: FontWeight.w600, color: AppColors.textColor), _buildSymptomsRow(), SizedBox(height: 16.h), - Text(LocaleKeys.description.tr(context: context), style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.f, color: AppColors.textColor)), + LocaleKeys.description.tr(context: context).toText14(weight: FontWeight.bold, color: AppColors.textColor), SizedBox(height: 2.h), - Text(description, style: TextStyle(color: AppColors.greyTextColor, fontWeight: FontWeight.w500, fontSize: 12.f)), - if (possibleConditionsSeverityEnum == PossibleConditionsSeverityEnum.emergency) + description.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + if (severityEnum != PossibleConditionsSeverityEnum.monitorOnly) CustomButton( - text: appointmentLabel ?? LocaleKeys.bookAppointment.tr(context: context), + text: "Book Appointment".needTranslation, onPressed: () { if (onActionPressed != null) { onActionPressed!(); } }, - backgroundColor: AppColors.lightRedButtonColor, + backgroundColor: AppColors.primaryRedColor, borderColor: Colors.transparent, - textColor: AppColors.primaryRedColor, - fontSize: 16.f, + textColor: AppColors.whiteColor, + fontSize: 14.f, fontWeight: FontWeight.w500, - borderRadius: 12.r, padding: EdgeInsets.symmetric(horizontal: 10.w), - height: 48.h, icon: AppAssets.add_icon, - iconColor: AppColors.primaryRedColor, - iconSize: 18.h, + height: 48.h, + iconColor: AppColors.whiteColor, ).paddingOnly(top: 16.w), - if (monitorNote != null) - Container( - margin: EdgeInsets.only(top: 12.h), - child: AppCustomChipWidget( - labelText: monitorNote!, - backgroundColor: AppColors.whiteColor, - textColor: AppColors.textColor, - padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 8.h), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.r)), - ), - ), + + // if (monitorNote != null) + // Container( + // margin: EdgeInsets.only(top: 12.h), + // child: AppCustomChipWidget( + // labelText: monitorNote, + // backgroundColor: AppColors.whiteColor, + // textColor: AppColors.textColor, + // padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 8.h), + // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.r)), + // ), + // ), ], ).paddingAll(16.w), ], diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index bf665ea..018af1c 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -8,6 +8,7 @@ import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointme import 'package:hmg_patient_app_new/presentation/comprehensive_checkup/comprehensive_checkup_page.dart'; import 'package:hmg_patient_app_new/presentation/covid19test/covid19_landing_page.dart'; import 'package:hmg_patient_app_new/presentation/e_referral/new_e_referral.dart'; +import 'package:hmg_patient_app_new/presentation/emergency_services/emergency_services_page.dart'; import 'package:hmg_patient_app_new/presentation/health_calculators_and_converts/health_calculators_page.dart'; import 'package:hmg_patient_app_new/presentation/health_trackers/add_health_tracker_entry_page.dart'; import 'package:hmg_patient_app_new/presentation/health_trackers/health_tracker_detail_page.dart'; @@ -30,16 +31,14 @@ import 'package:hmg_patient_app_new/presentation/vital_sign/vital_sign_page.dart import 'package:hmg_patient_app_new/presentation/water_monitor/water_consumption_page.dart'; import 'package:hmg_patient_app_new/presentation/water_monitor/water_monitor_settings_page.dart'; import 'package:hmg_patient_app_new/splashPage.dart'; - -import '../features/qr_parking/qr_parking_view_model.dart'; -import '../presentation/covid19test/covid19_landing_page.dart'; +import 'package:provider/provider.dart'; import '../core/dependencies.dart'; import '../features/monthly_reports/monthly_reports_repo.dart'; import '../features/monthly_reports/monthly_reports_view_model.dart'; +import '../features/qr_parking/qr_parking_view_model.dart'; import '../presentation/parking/paking_page.dart'; import '../services/error_handler_service.dart'; -import 'package:provider/provider.dart'; class AppRoutes { static const String initialRoute = '/initialRoute'; @@ -84,8 +83,10 @@ class AppRoutes { static const String addHealthTrackerEntryPage = '/addHealthTrackerEntryPage'; static const String healthTrackerDetailPage = '/healthTrackerDetailPage'; - static Map get routes => - { + // Emergency Services + static const String emergencyServicesPage = '/emergencyServicesPage'; + + static Map get routes => { initialRoute: (context) => SplashPage(), loginScreen: (context) => LoginScreen(), landingScreen: (context) => LandingNavigation(), @@ -104,7 +105,7 @@ class AppRoutes { triagePage: (context) => TriagePage(), bloodDonationPage: (context) => BloodDonationPage(), bookAppointmentPage: (context) => BookAppointmentPage(), - userInfoSelection: (context) => UserInfoSelectionScreen(), + userInfoSelection: (context) => UserInfoSelectionPage(), userInfoFlowManager: (context) => UserInfoFlowManager(), smartWatches: (context) => SmartwatchInstructionsPage(), huaweiHealthExample: (context) => HuaweiHealthExample(), @@ -115,34 +116,28 @@ class AppRoutes { healthConvertersPage: (context) => HealthCalculatorsPage(type: HealthCalConEnum.converter), healthTrackersPage: (context) => HealthTrackersPage(), vitalSign: (context) => VitalSignPage(), + emergencyServicesPage: (context) => EmergencyServicesPage(), addHealthTrackerEntryPage: (context) { - final args = ModalRoute - .of(context) - ?.settings - .arguments as HealthTrackerTypeEnum?; + final args = ModalRoute.of(context)?.settings.arguments as HealthTrackerTypeEnum?; return AddHealthTrackerEntryPage( trackerType: args ?? HealthTrackerTypeEnum.bloodSugar, ); }, healthTrackerDetailPage: (context) { - final args = ModalRoute - .of(context) - ?.settings - .arguments as HealthTrackerTypeEnum?; + final args = ModalRoute.of(context)?.settings.arguments as HealthTrackerTypeEnum?; return HealthTrackerDetailPage( trackerType: args ?? HealthTrackerTypeEnum.bloodSugar, ); }, - - monthlyReports: (context) => ChangeNotifierProvider( - create: (_) => MonthlyReportsViewModel( - monthlyReportsRepo: getIt(), - errorHandlerService: getIt(), - ), - ), - qrParking: (context) => ChangeNotifierProvider( - create: (_) => getIt(), - child: const ParkingPage(), + monthlyReports: (context) => ChangeNotifierProvider( + create: (_) => MonthlyReportsViewModel( + monthlyReportsRepo: getIt(), + errorHandlerService: getIt(), + ), + ), + qrParking: (context) => ChangeNotifierProvider( + create: (_) => getIt(), + child: const ParkingPage(), ) }; } diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart index 9fbdc17..ee48c60 100644 --- a/lib/theme/colors.dart +++ b/lib/theme/colors.dart @@ -92,7 +92,7 @@ class AppColors { // SymptomsChecker static const Color chipColorSeekMedicalAdvice = Color(0xFFFFAF15); // #FFAF15 - static const Color chipTextColorSeekMedicalAdvice = Color(0xFFAB7103); // #AB7103 + static const Color chipTextColorSeekMedicalAdvice = Color(0xFFD48D05); // #AB7103 static const Color chipColorMonitor = Color(0xFF18C273); // #18C273 static const Color chipColorEmergency = Color(0xFFED1C2B); // #ED1C2B diff --git a/lib/widgets/buttons/custom_button.dart b/lib/widgets/buttons/custom_button.dart index 08d281f..7b248db 100644 --- a/lib/widgets/buttons/custom_button.dart +++ b/lib/widgets/buttons/custom_button.dart @@ -80,17 +80,14 @@ class CustomButton extends StatelessWidget { ), Visibility( visible: text.isNotEmpty, - child: Padding( - padding: EdgeInsets.only(top: 0), - child: Text( - text, - overflow: textOverflow, - style: context.dynamicTextStyle( - fontSize: fontS, - color: isDisabled ? AppColors.greyTextColor : textColor, - letterSpacing: 0, - fontWeight: fontWeight, - ), + child: Text( + text, + overflow: textOverflow, + style: context.dynamicTextStyle( + fontSize: fontS, + color: isDisabled ? AppColors.greyTextColor : textColor, + letterSpacing: 0, + fontWeight: fontWeight, ), ), ), diff --git a/pubspec.lock b/pubspec.lock deleted file mode 100644 index 7e5aaf5..0000000 --- a/pubspec.lock +++ /dev/null @@ -1,2073 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _flutterfire_internals: - dependency: transitive - description: - name: _flutterfire_internals - sha256: ff0a84a2734d9e1089f8aedd5c0af0061b82fb94e95260d943404e0ef2134b11 - url: "https://pub.dev" - source: hosted - version: "1.3.59" - adaptive_number: - dependency: transitive - description: - name: adaptive_number - sha256: "3a567544e9b5c9c803006f51140ad544aedc79604fd4f3f2c1380003f97c1d77" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - amazon_payfort: - dependency: "direct main" - description: - name: amazon_payfort - sha256: "7732df0764aecbb814f910db36d0dca2f696e7e5ea380b49aa3ec62965768b33" - url: "https://pub.dev" - source: hosted - version: "1.1.4" - archive: - dependency: transitive - description: - name: archive - sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" - url: "https://pub.dev" - source: hosted - version: "4.0.7" - args: - dependency: transitive - description: - name: args - sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 - url: "https://pub.dev" - source: hosted - version: "2.7.0" - async: - dependency: transitive - description: - name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" - url: "https://pub.dev" - source: hosted - version: "2.13.0" - audio_session: - dependency: transitive - description: - name: audio_session - sha256: "8f96a7fecbb718cb093070f868b4cdcb8a9b1053dce342ff8ab2fde10eb9afb7" - url: "https://pub.dev" - source: hosted - version: "0.2.2" - auto_size_text: - dependency: "direct main" - description: - name: auto_size_text - sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599" - url: "https://pub.dev" - source: hosted - version: "3.0.0" - barcode_scan2: - dependency: "direct main" - description: - name: barcode_scan2 - sha256: "50b286021c644deee71e20a06c1709adc6594e39d65024ced0458cc1e3ff298e" - url: "https://pub.dev" - source: hosted - version: "4.6.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - cached_network_image: - dependency: "direct main" - description: - name: cached_network_image - sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916" - url: "https://pub.dev" - source: hosted - version: "3.4.1" - cached_network_image_platform_interface: - dependency: transitive - description: - name: cached_network_image_platform_interface - sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829" - url: "https://pub.dev" - source: hosted - version: "4.1.1" - cached_network_image_web: - dependency: transitive - description: - name: cached_network_image_web - sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - carp_serializable: - dependency: transitive - description: - name: carp_serializable - sha256: f039f8ea22e9437aef13fe7e9743c3761c76d401288dcb702eadd273c3e4dcef - url: "https://pub.dev" - source: hosted - version: "2.0.1" - characters: - dependency: transitive - description: - name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 - url: "https://pub.dev" - source: hosted - version: "1.4.0" - chewie: - dependency: transitive - description: - name: chewie - sha256: "44bcfc5f0dfd1de290c87c9d86a61308b3282a70b63435d5557cfd60f54a69ca" - url: "https://pub.dev" - source: hosted - version: "1.13.0" - clock: - dependency: transitive - description: - name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b - url: "https://pub.dev" - source: hosted - version: "1.1.2" - collection: - dependency: transitive - description: - name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" - url: "https://pub.dev" - source: hosted - version: "1.19.1" - connectivity_plus: - dependency: "direct main" - description: - name: connectivity_plus - sha256: b5e72753cf63becce2c61fd04dfe0f1c430cc5278b53a1342dc5ad839eab29ec - url: "https://pub.dev" - source: hosted - version: "6.1.5" - connectivity_plus_platform_interface: - dependency: transitive - description: - name: connectivity_plus_platform_interface - sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - convert: - dependency: transitive - description: - name: convert - sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 - url: "https://pub.dev" - source: hosted - version: "3.1.2" - cross_file: - dependency: transitive - description: - name: cross_file - sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" - url: "https://pub.dev" - source: hosted - version: "0.3.4+2" - crypto: - dependency: transitive - description: - name: crypto - sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" - url: "https://pub.dev" - source: hosted - version: "3.0.6" - csslib: - dependency: transitive - description: - name: csslib - sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" - url: "https://pub.dev" - source: hosted - version: "1.0.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 - url: "https://pub.dev" - source: hosted - version: "1.0.8" - dart_jsonwebtoken: - dependency: "direct main" - description: - name: dart_jsonwebtoken - sha256: "0de65691c1d736e9459f22f654ddd6fd8368a271d4e41aa07e53e6301eff5075" - url: "https://pub.dev" - source: hosted - version: "3.3.1" - dartz: - dependency: "direct main" - description: - name: dartz - sha256: e6acf34ad2e31b1eb00948692468c30ab48ac8250e0f0df661e29f12dd252168 - url: "https://pub.dev" - source: hosted - version: "0.10.1" - dbus: - dependency: transitive - description: - name: dbus - sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" - url: "https://pub.dev" - source: hosted - version: "0.7.11" - device_calendar: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: "5ea5ed9e2bb499c0633383b53103f2920b634755" - url: "https://github.com/bardram/device_calendar" - source: git - version: "4.3.1" - device_calendar_plus: - dependency: "direct main" - description: - name: device_calendar_plus - sha256: d11a70d98eb123e8eb09fdcfaf220ca4f1aa65a1512e12092f176f4b54983507 - url: "https://pub.dev" - source: hosted - version: "0.3.3" - device_calendar_plus_android: - dependency: transitive - description: - name: device_calendar_plus_android - sha256: a341ef29fa0251251287d63c1d009dfd35c1459dc6a129fd5e03f5ac92d8d7ff - url: "https://pub.dev" - source: hosted - version: "0.3.3" - device_calendar_plus_ios: - dependency: transitive - description: - name: device_calendar_plus_ios - sha256: "3b2f84ce1ed002be8460e214a3229e66748bbaad4077603f2c734d67c42033ff" - url: "https://pub.dev" - source: hosted - version: "0.3.3" - device_calendar_plus_platform_interface: - dependency: transitive - description: - name: device_calendar_plus_platform_interface - sha256: "0ce7511c094ca256831a48e16efe8f1e97e7bd00a5ff3936296ffd650a1d76b5" - url: "https://pub.dev" - source: hosted - version: "0.3.3" - device_info_plus: - dependency: "direct main" - description: - name: device_info_plus - sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a" - url: "https://pub.dev" - source: hosted - version: "11.5.0" - device_info_plus_platform_interface: - dependency: transitive - description: - name: device_info_plus_platform_interface - sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f - url: "https://pub.dev" - source: hosted - version: "7.0.3" - dropdown_search: - dependency: "direct main" - description: - name: dropdown_search - sha256: c29b3e5147a82a06a4a08b3b574c51cb48cc17ad89893d53ee72a6f86643622e - url: "https://pub.dev" - source: hosted - version: "6.0.2" - easy_localization: - dependency: "direct main" - description: - name: easy_localization - sha256: "2ccdf9db8fe4d9c5a75c122e6275674508fd0f0d49c827354967b8afcc56bbed" - url: "https://pub.dev" - source: hosted - version: "3.0.8" - easy_logger: - dependency: transitive - description: - name: easy_logger - sha256: c764a6e024846f33405a2342caf91c62e357c24b02c04dbc712ef232bf30ffb7 - url: "https://pub.dev" - source: hosted - version: "0.0.2" - ed25519_edwards: - dependency: transitive - description: - name: ed25519_edwards - sha256: "6ce0112d131327ec6d42beede1e5dfd526069b18ad45dcf654f15074ad9276cd" - url: "https://pub.dev" - source: hosted - version: "0.3.1" - equatable: - dependency: "direct main" - description: - name: equatable - sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" - url: "https://pub.dev" - source: hosted - version: "2.0.7" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" - url: "https://pub.dev" - source: hosted - version: "1.3.3" - ffi: - dependency: transitive - description: - name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - file: - dependency: transitive - description: - name: file - sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://pub.dev" - source: hosted - version: "7.0.1" - file_picker: - dependency: "direct main" - description: - name: file_picker - sha256: f2d9f173c2c14635cc0e9b14c143c49ef30b4934e8d1d274d6206fcb0086a06f - url: "https://pub.dev" - source: hosted - version: "10.3.3" - file_selector_linux: - dependency: transitive - description: - name: file_selector_linux - sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33" - url: "https://pub.dev" - source: hosted - version: "0.9.3+2" - file_selector_macos: - dependency: transitive - description: - name: file_selector_macos - sha256: "19124ff4a3d8864fdc62072b6a2ef6c222d55a3404fe14893a3c02744907b60c" - url: "https://pub.dev" - source: hosted - version: "0.9.4+4" - file_selector_platform_interface: - dependency: transitive - description: - name: file_selector_platform_interface - sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b - url: "https://pub.dev" - source: hosted - version: "2.6.2" - file_selector_windows: - dependency: transitive - description: - name: file_selector_windows - sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b" - url: "https://pub.dev" - source: hosted - version: "0.9.3+4" - firebase_analytics: - dependency: "direct main" - description: - name: firebase_analytics - sha256: "4f85b161772e1d54a66893ef131c0a44bd9e552efa78b33d5f4f60d2caa5c8a3" - url: "https://pub.dev" - source: hosted - version: "11.6.0" - firebase_analytics_platform_interface: - dependency: transitive - description: - name: firebase_analytics_platform_interface - sha256: a44b6d1155ed5cae7641e3de7163111cfd9f6f6c954ca916dc6a3bdfa86bf845 - url: "https://pub.dev" - source: hosted - version: "4.4.3" - firebase_analytics_web: - dependency: transitive - description: - name: firebase_analytics_web - sha256: c7d1ed1f86ae64215757518af5576ff88341c8ce5741988c05cc3b2e07b0b273 - url: "https://pub.dev" - source: hosted - version: "0.5.10+16" - firebase_core: - dependency: "direct main" - description: - name: firebase_core - sha256: "7be63a3f841fc9663342f7f3a011a42aef6a61066943c90b1c434d79d5c995c5" - url: "https://pub.dev" - source: hosted - version: "3.15.2" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - sha256: "5873a370f0d232918e23a5a6137dbe4c2c47cf017301f4ea02d9d636e52f60f0" - url: "https://pub.dev" - source: hosted - version: "6.0.1" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - sha256: "0ed0dc292e8f9ac50992e2394e9d336a0275b6ae400d64163fdf0a8a8b556c37" - url: "https://pub.dev" - source: hosted - version: "2.24.1" - firebase_messaging: - dependency: "direct main" - description: - name: firebase_messaging - sha256: "60be38574f8b5658e2f22b7e311ff2064bea835c248424a383783464e8e02fcc" - url: "https://pub.dev" - source: hosted - version: "15.2.10" - firebase_messaging_platform_interface: - dependency: transitive - description: - name: firebase_messaging_platform_interface - sha256: "685e1771b3d1f9c8502771ccc9f91485b376ffe16d553533f335b9183ea99754" - url: "https://pub.dev" - source: hosted - version: "4.6.10" - firebase_messaging_web: - dependency: transitive - description: - name: firebase_messaging_web - sha256: "0d1be17bc89ed3ff5001789c92df678b2e963a51b6fa2bdb467532cc9dbed390" - url: "https://pub.dev" - source: hosted - version: "3.10.10" - fixnum: - dependency: transitive - description: - name: fixnum - sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be - url: "https://pub.dev" - source: hosted - version: "1.1.1" - fl_chart: - dependency: "direct main" - description: - name: fl_chart - sha256: "577aeac8ca414c25333334d7c4bb246775234c0e44b38b10a82b559dd4d764e7" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_cache_manager: - dependency: transitive - description: - name: flutter_cache_manager - sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" - url: "https://pub.dev" - source: hosted - version: "3.4.1" - flutter_callkit_incoming: - dependency: "direct main" - description: - name: flutter_callkit_incoming - sha256: "3589deb8b71e43f2d520a9c8a5240243f611062a8b246cdca4b1fda01fbbf9b8" - url: "https://pub.dev" - source: hosted - version: "3.0.0" - flutter_hooks: - dependency: transitive - description: - name: flutter_hooks - sha256: cde36b12f7188c85286fba9b38cc5a902e7279f36dd676967106c041dc9dde70 - url: "https://pub.dev" - source: hosted - version: "0.20.5" - flutter_inappwebview: - dependency: "direct main" - description: - name: flutter_inappwebview - sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5" - url: "https://pub.dev" - source: hosted - version: "6.1.5" - flutter_inappwebview_android: - dependency: transitive - description: - name: flutter_inappwebview_android - sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba" - url: "https://pub.dev" - source: hosted - version: "1.1.3" - flutter_inappwebview_internal_annotations: - dependency: transitive - description: - name: flutter_inappwebview_internal_annotations - sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - flutter_inappwebview_ios: - dependency: transitive - description: - name: flutter_inappwebview_ios - sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d" - url: "https://pub.dev" - source: hosted - version: "1.1.2" - flutter_inappwebview_macos: - dependency: transitive - description: - name: flutter_inappwebview_macos - sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1 - url: "https://pub.dev" - source: hosted - version: "1.1.2" - flutter_inappwebview_platform_interface: - dependency: transitive - description: - name: flutter_inappwebview_platform_interface - sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500 - url: "https://pub.dev" - source: hosted - version: "1.3.0+1" - flutter_inappwebview_web: - dependency: transitive - description: - name: flutter_inappwebview_web - sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598" - url: "https://pub.dev" - source: hosted - version: "1.1.2" - flutter_inappwebview_windows: - dependency: transitive - description: - name: flutter_inappwebview_windows - sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055" - url: "https://pub.dev" - source: hosted - version: "0.6.0" - flutter_ios_voip_kit_karmm: - dependency: "direct main" - description: - name: flutter_ios_voip_kit_karmm - sha256: "31a445d78aacacdf128a0354efb9f4e424285dfe4c0af3ea872e64f03e6f6bfc" - url: "https://pub.dev" - source: hosted - version: "0.8.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" - url: "https://pub.dev" - source: hosted - version: "5.0.0" - flutter_local_notifications: - dependency: "direct main" - description: - name: flutter_local_notifications - sha256: "7ed76be64e8a7d01dfdf250b8434618e2a028c9dfa2a3c41dc9b531d4b3fc8a5" - url: "https://pub.dev" - source: hosted - version: "19.4.2" - flutter_local_notifications_linux: - dependency: transitive - description: - name: flutter_local_notifications_linux - sha256: e3c277b2daab8e36ac5a6820536668d07e83851aeeb79c446e525a70710770a5 - url: "https://pub.dev" - source: hosted - version: "6.0.0" - flutter_local_notifications_platform_interface: - dependency: transitive - description: - name: flutter_local_notifications_platform_interface - sha256: "277d25d960c15674ce78ca97f57d0bae2ee401c844b6ac80fcd972a9c99d09fe" - url: "https://pub.dev" - source: hosted - version: "9.1.0" - flutter_local_notifications_windows: - dependency: transitive - description: - name: flutter_local_notifications_windows - sha256: "8d658f0d367c48bd420e7cf2d26655e2d1130147bca1eea917e576ca76668aaf" - url: "https://pub.dev" - source: hosted - version: "1.0.3" - flutter_localizations: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_nfc_kit: - dependency: "direct main" - description: - name: flutter_nfc_kit - sha256: "3cc4059626fa672031261512299458dd274de4ccb57a7f0ee0951ddd70a048e5" - url: "https://pub.dev" - source: hosted - version: "3.6.0" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - sha256: b0694b7fb1689b0e6cc193b3f1fcac6423c4f93c74fb20b806c6b6f196db0c31 - url: "https://pub.dev" - source: hosted - version: "2.0.30" - flutter_rating_bar: - dependency: "direct main" - description: - name: flutter_rating_bar - sha256: d2af03469eac832c591a1eba47c91ecc871fe5708e69967073c043b2d775ed93 - url: "https://pub.dev" - source: hosted - version: "4.0.1" - flutter_staggered_animations: - dependency: "direct main" - description: - name: flutter_staggered_animations - sha256: "81d3c816c9bb0dca9e8a5d5454610e21ffb068aedb2bde49d2f8d04f75538351" - url: "https://pub.dev" - source: hosted - version: "1.1.1" - flutter_svg: - dependency: "direct main" - description: - name: flutter_svg - sha256: b9c2ad5872518a27507ab432d1fb97e8813b05f0fc693f9d40fad06d073e0678 - url: "https://pub.dev" - source: hosted - version: "2.2.1" - flutter_swiper_view: - dependency: "direct main" - description: - name: flutter_swiper_view - sha256: "2a165b259e8a4c49d4da5626b967ed42a73dac2d075bd9e266ad8d23b9f01879" - url: "https://pub.dev" - source: hosted - version: "1.1.8" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - flutter_widget_from_html: - dependency: "direct main" - description: - name: flutter_widget_from_html - sha256: "7f1daefcd3009c43c7e7fb37501e6bb752d79aa7bfad0085fb0444da14e89bd0" - url: "https://pub.dev" - source: hosted - version: "0.17.1" - flutter_widget_from_html_core: - dependency: transitive - description: - name: flutter_widget_from_html_core - sha256: "1120ee6ed3509ceff2d55aa6c6cbc7b6b1291434422de2411b5a59364dd6ff03" - url: "https://pub.dev" - source: hosted - version: "0.17.0" - flutter_zoom_videosdk: - dependency: "direct main" - description: - name: flutter_zoom_videosdk - sha256: "46a4dea664b1c969099328a499c198a1755adf9ac333dea28bea5187910b3bf9" - url: "https://pub.dev" - source: hosted - version: "2.1.10" - fluttertoast: - dependency: "direct main" - description: - name: fluttertoast - sha256: "90778fe0497fe3a09166e8cf2e0867310ff434b794526589e77ec03cf08ba8e8" - url: "https://pub.dev" - source: hosted - version: "8.2.14" - fwfh_cached_network_image: - dependency: transitive - description: - name: fwfh_cached_network_image - sha256: "484cb5f8047f02cfac0654fca5832bfa91bb715fd7fc651c04eb7454187c4af8" - url: "https://pub.dev" - source: hosted - version: "0.16.1" - fwfh_chewie: - dependency: transitive - description: - name: fwfh_chewie - sha256: ae74fc26798b0e74f3983f7b851e74c63b9eeb2d3015ecd4b829096b2c3f8818 - url: "https://pub.dev" - source: hosted - version: "0.16.1" - fwfh_just_audio: - dependency: transitive - description: - name: fwfh_just_audio - sha256: dfd622a0dfe049ac647423a2a8afa7f057d9b2b93d92710b624e3d370b1ac69a - url: "https://pub.dev" - source: hosted - version: "0.17.0" - fwfh_svg: - dependency: transitive - description: - name: fwfh_svg - sha256: "2e6bb241179eeeb1a7941e05c8c923b05d332d36a9085233e7bf110ea7deb915" - url: "https://pub.dev" - source: hosted - version: "0.16.1" - fwfh_url_launcher: - dependency: transitive - description: - name: fwfh_url_launcher - sha256: c38aa8fb373fda3a89b951fa260b539f623f6edb45eee7874cb8b492471af881 - url: "https://pub.dev" - source: hosted - version: "0.16.1" - fwfh_webview: - dependency: transitive - description: - name: fwfh_webview - sha256: f71b0aa16e15d82f3c017f33560201ff5ae04e91e970cab5d12d3bcf970b870c - url: "https://pub.dev" - source: hosted - version: "0.15.6" - geoclue: - dependency: transitive - description: - name: geoclue - sha256: c2a998c77474fc57aa00c6baa2928e58f4b267649057a1c76738656e9dbd2a7f - url: "https://pub.dev" - source: hosted - version: "0.1.1" - geolocator: - dependency: "direct main" - description: - name: geolocator - sha256: "79939537046c9025be47ec645f35c8090ecadb6fe98eba146a0d25e8c1357516" - url: "https://pub.dev" - source: hosted - version: "14.0.2" - geolocator_android: - dependency: transitive - description: - name: geolocator_android - sha256: "179c3cb66dfa674fc9ccbf2be872a02658724d1c067634e2c427cf6df7df901a" - url: "https://pub.dev" - source: hosted - version: "5.0.2" - geolocator_apple: - dependency: transitive - description: - name: geolocator_apple - sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22 - url: "https://pub.dev" - source: hosted - version: "2.3.13" - geolocator_linux: - dependency: transitive - description: - name: geolocator_linux - sha256: c4e966f0a7a87e70049eac7a2617f9e16fd4c585a26e4330bdfc3a71e6a721f3 - url: "https://pub.dev" - source: hosted - version: "0.2.3" - geolocator_platform_interface: - dependency: transitive - description: - name: geolocator_platform_interface - sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67" - url: "https://pub.dev" - source: hosted - version: "4.2.6" - geolocator_web: - dependency: transitive - description: - name: geolocator_web - sha256: b1ae9bdfd90f861fde8fd4f209c37b953d65e92823cb73c7dee1fa021b06f172 - url: "https://pub.dev" - source: hosted - version: "4.1.3" - geolocator_windows: - dependency: transitive - description: - name: geolocator_windows - sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6" - url: "https://pub.dev" - source: hosted - version: "0.2.5" - get_it: - dependency: "direct main" - description: - name: get_it - sha256: a4292e7cf67193f8e7c1258203104eb2a51ec8b3a04baa14695f4064c144297b - url: "https://pub.dev" - source: hosted - version: "8.2.0" - gms_check: - dependency: "direct main" - description: - name: gms_check - sha256: b3fc08fd41da233f9761f9981303346aa9778b4802e90ce9bd8122674fcca6f0 - url: "https://pub.dev" - source: hosted - version: "1.0.4" - google_api_availability: - dependency: "direct main" - description: - name: google_api_availability - sha256: "2ffdc91e1e0cf4e7974fef6c2988a24cefa81f03526ff04b694df6dc0fcbca03" - url: "https://pub.dev" - source: hosted - version: "5.0.1" - google_api_availability_android: - dependency: transitive - description: - name: google_api_availability_android - sha256: "4794147f43a8f3eee6b514d3ae30dbe6f7b9048cae8cd2a74cb4055cd28d74a8" - url: "https://pub.dev" - source: hosted - version: "1.1.1" - google_api_availability_platform_interface: - dependency: transitive - description: - name: google_api_availability_platform_interface - sha256: "65b7da62fe5b582bb3d508628ad827d36d890710ea274766a992a56fa5420da6" - url: "https://pub.dev" - source: hosted - version: "1.0.1" - google_maps: - dependency: transitive - description: - name: google_maps - sha256: "5d410c32112d7c6eb7858d359275b2aa04778eed3e36c745aeae905fb2fa6468" - url: "https://pub.dev" - source: hosted - version: "8.2.0" - google_maps_flutter: - dependency: "direct main" - description: - name: google_maps_flutter - sha256: c389e16fafc04b37a4105e0757ecb9d59806026cee72f408f1ba68811d01bfe6 - url: "https://pub.dev" - source: hosted - version: "2.13.1" - google_maps_flutter_android: - dependency: transitive - description: - name: google_maps_flutter_android - sha256: a6c9d43f6a944ff4bae5c3deb34817970ac3d591dcd7f5bd2ea450ab9e9c514a - url: "https://pub.dev" - source: hosted - version: "2.18.2" - google_maps_flutter_ios: - dependency: transitive - description: - name: google_maps_flutter_ios - sha256: ca02463b19a9abc7d31fcaf22631d021d647107467f741b917a69fa26659fd75 - url: "https://pub.dev" - source: hosted - version: "2.15.5" - google_maps_flutter_platform_interface: - dependency: transitive - description: - name: google_maps_flutter_platform_interface - sha256: f4b9b44f7b12a1f6707ffc79d082738e0b7e194bf728ee61d2b3cdf5fdf16081 - url: "https://pub.dev" - source: hosted - version: "2.14.0" - google_maps_flutter_web: - dependency: transitive - description: - name: google_maps_flutter_web - sha256: "53e5dbf73ff04153acc55a038248706967c21d5b6ef6657a57fce2be73c2895a" - url: "https://pub.dev" - source: hosted - version: "0.5.14+2" - gsettings: - dependency: transitive - description: - name: gsettings - sha256: "1b0ce661f5436d2db1e51f3c4295a49849f03d304003a7ba177d01e3a858249c" - url: "https://pub.dev" - source: hosted - version: "0.2.8" - health: - dependency: "direct main" - description: - name: health - sha256: "320633022fb2423178baa66508001c4ca5aee5806ffa2c913e66488081e9fd47" - url: "https://pub.dev" - source: hosted - version: "13.1.4" - hijri_gregorian_calendar: - dependency: "direct main" - description: - name: hijri_gregorian_calendar - sha256: aecdbe3c9365fac55f17b5e1f24086a81999b1e5c9372cb08888bfbe61e07fa1 - url: "https://pub.dev" - source: hosted - version: "0.1.1" - html: - dependency: transitive - description: - name: html - sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" - url: "https://pub.dev" - source: hosted - version: "0.15.6" - http: - dependency: "direct main" - description: - name: http - sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 - url: "https://pub.dev" - source: hosted - version: "1.5.0" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" - url: "https://pub.dev" - source: hosted - version: "4.1.2" - huawei_health: - dependency: "direct main" - description: - name: huawei_health - sha256: "52fb9990e1fc857e2fa1b1251dde63b2146086a13b2d9c50bdfc3c4f715c8a12" - url: "https://pub.dev" - source: hosted - version: "6.16.0+300" - huawei_location: - dependency: "direct main" - description: - name: huawei_location - sha256: "3100d6b2b11df56481b8deade71baa84970e0bae0ade6ec56407be2b036af355" - url: "https://pub.dev" - source: hosted - version: "6.14.2+301" - huawei_map: - dependency: "direct main" - description: - path: flutter-hms-map - ref: HEAD - resolved-ref: "9a16541e4016e3bf58a2571e6aa658a4751af399" - url: "https://github.com/fleoparra/hms-flutter-plugin.git" - source: git - version: "6.11.2+303" - image_picker: - dependency: "direct main" - description: - name: image_picker - sha256: "736eb56a911cf24d1859315ad09ddec0b66104bc41a7f8c5b96b4e2620cf5041" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - image_picker_android: - dependency: transitive - description: - name: image_picker_android - sha256: "28f3987ca0ec702d346eae1d90eda59603a2101b52f1e234ded62cff1d5cfa6e" - url: "https://pub.dev" - source: hosted - version: "0.8.13+1" - image_picker_for_web: - dependency: transitive - description: - name: image_picker_for_web - sha256: "40c2a6a0da15556dc0f8e38a3246064a971a9f512386c3339b89f76db87269b6" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - image_picker_ios: - dependency: transitive - description: - name: image_picker_ios - sha256: eb06fe30bab4c4497bad449b66448f50edcc695f1c59408e78aa3a8059eb8f0e - url: "https://pub.dev" - source: hosted - version: "0.8.13" - image_picker_linux: - dependency: transitive - description: - name: image_picker_linux - sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4" - url: "https://pub.dev" - source: hosted - version: "0.2.2" - image_picker_macos: - dependency: transitive - description: - name: image_picker_macos - sha256: d58cd9d67793d52beefd6585b12050af0a7663c0c2a6ece0fb110a35d6955e04 - url: "https://pub.dev" - source: hosted - version: "0.2.2" - image_picker_platform_interface: - dependency: transitive - description: - name: image_picker_platform_interface - sha256: "9f143b0dba3e459553209e20cc425c9801af48e6dfa4f01a0fcf927be3f41665" - url: "https://pub.dev" - source: hosted - version: "2.11.0" - image_picker_windows: - dependency: transitive - description: - name: image_picker_windows - sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae - url: "https://pub.dev" - source: hosted - version: "0.2.2" - intl: - dependency: "direct main" - description: - name: intl - sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" - url: "https://pub.dev" - source: hosted - version: "0.20.2" - jiffy: - dependency: "direct main" - description: - name: jiffy - sha256: "9bafbfe6d97587048bf449165e050029e716a12438f54a3d39e7e3a256decdac" - url: "https://pub.dev" - source: hosted - version: "6.4.3" - json_annotation: - dependency: transitive - description: - name: json_annotation - sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" - url: "https://pub.dev" - source: hosted - version: "4.9.0" - just_audio: - dependency: "direct main" - description: - name: just_audio - sha256: "9694e4734f515f2a052493d1d7e0d6de219ee0427c7c29492e246ff32a219908" - url: "https://pub.dev" - source: hosted - version: "0.10.5" - just_audio_platform_interface: - dependency: transitive - description: - name: just_audio_platform_interface - sha256: "2532c8d6702528824445921c5ff10548b518b13f808c2e34c2fd54793b999a6a" - url: "https://pub.dev" - source: hosted - version: "4.6.0" - just_audio_web: - dependency: transitive - description: - name: just_audio_web - sha256: "6ba8a2a7e87d57d32f0f7b42856ade3d6a9fbe0f1a11fabae0a4f00bb73f0663" - url: "https://pub.dev" - source: hosted - version: "0.4.16" - keyboard_actions: - dependency: "direct main" - description: - name: keyboard_actions - sha256: "31e0ab2a706ac8f58887efa60efc1f19aecdf37d8ab0f665a0f156d1fbeab650" - url: "https://pub.dev" - source: hosted - version: "4.2.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" - url: "https://pub.dev" - source: hosted - version: "11.0.2" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" - url: "https://pub.dev" - source: hosted - version: "3.0.10" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - lints: - dependency: transitive - description: - name: lints - sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 - url: "https://pub.dev" - source: hosted - version: "5.1.1" - local_auth: - dependency: "direct main" - description: - name: local_auth - sha256: "434d854cf478f17f12ab29a76a02b3067f86a63a6d6c4eb8fbfdcfe4879c1b7b" - url: "https://pub.dev" - source: hosted - version: "2.3.0" - local_auth_android: - dependency: transitive - description: - name: local_auth_android - sha256: "48924f4a8b3cc45994ad5993e2e232d3b00788a305c1bf1c7db32cef281ce9a3" - url: "https://pub.dev" - source: hosted - version: "1.0.52" - local_auth_darwin: - dependency: transitive - description: - name: local_auth_darwin - sha256: "0e9706a8543a4a2eee60346294d6a633dd7c3ee60fae6b752570457c4ff32055" - url: "https://pub.dev" - source: hosted - version: "1.6.0" - local_auth_platform_interface: - dependency: transitive - description: - name: local_auth_platform_interface - sha256: "1b842ff177a7068442eae093b64abe3592f816afd2a533c0ebcdbe40f9d2075a" - url: "https://pub.dev" - source: hosted - version: "1.0.10" - local_auth_windows: - dependency: transitive - description: - name: local_auth_windows - sha256: bc4e66a29b0fdf751aafbec923b5bed7ad6ed3614875d8151afe2578520b2ab5 - url: "https://pub.dev" - source: hosted - version: "1.0.11" - location: - dependency: "direct main" - description: - name: location - sha256: b080053c181c7d152c43dd576eec6436c40e25f326933051c330da563ddd5333 - url: "https://pub.dev" - source: hosted - version: "8.0.1" - location_platform_interface: - dependency: transitive - description: - name: location_platform_interface - sha256: ca8700bb3f6b1e8b2afbd86bd78b2280d116c613ca7bfa1d4d7b64eba357d749 - url: "https://pub.dev" - source: hosted - version: "6.0.1" - location_web: - dependency: transitive - description: - name: location_web - sha256: b8e3add5efe0d65c5e692b7a135d80a4015c580d3ea646fa71973e97668dd868 - url: "https://pub.dev" - source: hosted - version: "6.0.1" - logger: - dependency: "direct main" - description: - name: logger - sha256: "55d6c23a6c15db14920e037fe7e0dc32e7cdaf3b64b4b25df2d541b5b6b81c0c" - url: "https://pub.dev" - source: hosted - version: "2.6.1" - logging: - dependency: transitive - description: - name: logging - sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 - url: "https://pub.dev" - source: hosted - version: "1.3.0" - lottie: - dependency: "direct main" - description: - name: lottie - sha256: c5fa04a80a620066c15cf19cc44773e19e9b38e989ff23ea32e5903ef1015950 - url: "https://pub.dev" - source: hosted - version: "3.3.1" - manage_calendar_events: - dependency: "direct main" - description: - name: manage_calendar_events - sha256: f17600fcb7dc7047120c185993045e493d686930237b4e3c2689c26a64513d66 - url: "https://pub.dev" - source: hosted - version: "2.0.3" - maps_launcher: - dependency: "direct main" - description: - name: maps_launcher - sha256: dac4c609720211fa6336b5903d917fe45e545c6b5665978efc3db2a3f436b1ae - url: "https://pub.dev" - source: hosted - version: "3.0.0+1" - matcher: - dependency: transitive - description: - name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 - url: "https://pub.dev" - source: hosted - version: "0.12.17" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" - source: hosted - version: "0.11.1" - meta: - dependency: transitive - description: - name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c - url: "https://pub.dev" - source: hosted - version: "1.16.0" - mime: - dependency: transitive - description: - name: mime - sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" - url: "https://pub.dev" - source: hosted - version: "2.0.0" - ndef: - dependency: transitive - description: - name: ndef - sha256: "5083507cff4bb823b2a198a27ea2c70c4d6bc27a97b66097d966a250e1615d54" - url: "https://pub.dev" - source: hosted - version: "0.3.4" - nested: - dependency: transitive - description: - name: nested - sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - network_info_plus: - dependency: "direct main" - description: - name: network_info_plus - sha256: f926b2ba86aa0086a0dfbb9e5072089bc213d854135c1712f1d29fc89ba3c877 - url: "https://pub.dev" - source: hosted - version: "6.1.4" - network_info_plus_platform_interface: - dependency: transitive - description: - name: network_info_plus_platform_interface - sha256: "7e7496a8a9d8136859b8881affc613c4a21304afeb6c324bcefc4bd0aff6b94b" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - nm: - dependency: transitive - description: - name: nm - sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" - url: "https://pub.dev" - source: hosted - version: "0.5.0" - octo_image: - dependency: transitive - description: - name: octo_image - sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - open_filex: - dependency: "direct main" - description: - name: open_filex - sha256: "9976da61b6a72302cf3b1efbce259200cd40232643a467aac7370addf94d6900" - url: "https://pub.dev" - source: hosted - version: "4.7.0" - package_info_plus: - dependency: transitive - description: - name: package_info_plus - sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968" - url: "https://pub.dev" - source: hosted - version: "8.3.1" - package_info_plus_platform_interface: - dependency: transitive - description: - name: package_info_plus_platform_interface - sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - path: - dependency: transitive - description: - name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://pub.dev" - source: hosted - version: "1.9.1" - path_parsing: - dependency: transitive - description: - name: path_parsing - sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - path_provider: - dependency: "direct main" - description: - name: path_provider - sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" - url: "https://pub.dev" - source: hosted - version: "2.1.5" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db" - url: "https://pub.dev" - source: hosted - version: "2.2.18" - path_provider_foundation: - dependency: transitive - description: - name: path_provider_foundation - sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd" - url: "https://pub.dev" - source: hosted - version: "2.4.2" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 - url: "https://pub.dev" - source: hosted - version: "2.2.1" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 - url: "https://pub.dev" - source: hosted - version: "2.3.0" - permission_handler: - dependency: "direct main" - description: - name: permission_handler - sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1 - url: "https://pub.dev" - source: hosted - version: "12.0.1" - permission_handler_android: - dependency: transitive - description: - name: permission_handler_android - sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6" - url: "https://pub.dev" - source: hosted - version: "13.0.1" - permission_handler_apple: - dependency: transitive - description: - name: permission_handler_apple - sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023 - url: "https://pub.dev" - source: hosted - version: "9.4.7" - permission_handler_html: - dependency: transitive - description: - name: permission_handler_html - sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" - url: "https://pub.dev" - source: hosted - version: "0.1.3+5" - permission_handler_platform_interface: - dependency: transitive - description: - name: permission_handler_platform_interface - sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 - url: "https://pub.dev" - source: hosted - version: "4.3.0" - permission_handler_windows: - dependency: transitive - description: - name: permission_handler_windows - sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" - url: "https://pub.dev" - source: hosted - version: "0.2.1" - petitparser: - dependency: transitive - description: - name: petitparser - sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" - url: "https://pub.dev" - source: hosted - version: "7.0.1" - platform: - dependency: transitive - description: - name: platform - sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" - url: "https://pub.dev" - source: hosted - version: "3.1.6" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.dev" - source: hosted - version: "2.1.8" - pointycastle: - dependency: transitive - description: - name: pointycastle - sha256: "92aa3841d083cc4b0f4709b5c74fd6409a3e6ba833ffc7dc6a8fee096366acf5" - url: "https://pub.dev" - source: hosted - version: "4.0.0" - posix: - dependency: transitive - description: - name: posix - sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" - url: "https://pub.dev" - source: hosted - version: "6.0.3" - protobuf: - dependency: transitive - description: - name: protobuf - sha256: "75ec242d22e950bdcc79ee38dd520ce4ee0bc491d7fadc4ea47694604d22bf06" - url: "https://pub.dev" - source: hosted - version: "6.0.0" - provider: - dependency: "direct main" - description: - name: provider - sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" - url: "https://pub.dev" - source: hosted - version: "6.1.5+1" - quiver: - dependency: transitive - description: - name: quiver - sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 - url: "https://pub.dev" - source: hosted - version: "3.2.2" - rrule: - dependency: transitive - description: - name: rrule - sha256: b7425410c594d4b6717c9f17ec8ef83c9d1ff2e513c428a135b5924fc2e8e045 - url: "https://pub.dev" - source: hosted - version: "0.2.17" - rxdart: - dependency: transitive - description: - name: rxdart - sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" - url: "https://pub.dev" - source: hosted - version: "0.28.0" - sanitize_html: - dependency: transitive - description: - name: sanitize_html - sha256: "12669c4a913688a26555323fb9cec373d8f9fbe091f2d01c40c723b33caa8989" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - scrollable_positioned_list: - dependency: "direct main" - description: - name: scrollable_positioned_list - sha256: "1b54d5f1329a1e263269abc9e2543d90806131aa14fe7c6062a8054d57249287" - url: "https://pub.dev" - source: hosted - version: "0.3.8" - share_plus: - dependency: "direct main" - description: - name: share_plus - sha256: d7dc0630a923883c6328ca31b89aa682bacbf2f8304162d29f7c6aaff03a27a1 - url: "https://pub.dev" - source: hosted - version: "11.1.0" - share_plus_platform_interface: - dependency: transitive - description: - name: share_plus_platform_interface - sha256: "88023e53a13429bd65d8e85e11a9b484f49d4c190abbd96c7932b74d6927cc9a" - url: "https://pub.dev" - source: hosted - version: "6.1.0" - shared_preferences: - dependency: "direct main" - description: - name: shared_preferences - sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" - url: "https://pub.dev" - source: hosted - version: "2.5.3" - shared_preferences_android: - dependency: transitive - description: - name: shared_preferences_android - sha256: bd14436108211b0d4ee5038689a56d4ae3620fd72fd6036e113bf1345bc74d9e - url: "https://pub.dev" - source: hosted - version: "2.4.13" - shared_preferences_foundation: - dependency: transitive - description: - name: shared_preferences_foundation - sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" - url: "https://pub.dev" - source: hosted - version: "2.5.4" - shared_preferences_linux: - dependency: transitive - description: - name: shared_preferences_linux - sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 - url: "https://pub.dev" - source: hosted - version: "2.4.3" - shared_preferences_windows: - dependency: transitive - description: - name: shared_preferences_windows - sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - shimmer: - dependency: "direct main" - description: - name: shimmer - sha256: "5f88c883a22e9f9f299e5ba0e4f7e6054857224976a5d9f839d4ebdc94a14ac9" - url: "https://pub.dev" - source: hosted - version: "3.0.0" - sizer: - dependency: "direct main" - description: - name: sizer - sha256: "9963c89e4d30d7c2108de3eafc0a7e6a4a8009799376ea6be5ef0a9ad87cfbad" - url: "https://pub.dev" - source: hosted - version: "3.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - smooth_corner: - dependency: "direct main" - description: - name: smooth_corner - sha256: "112d7331f82ead81ec870c5d1eb0624f2e7e367eccd166c2fffe4c11d4f87c4f" - url: "https://pub.dev" - source: hosted - version: "1.1.1" - sms_otp_auto_verify: - dependency: "direct main" - description: - name: sms_otp_auto_verify - sha256: ee02af0d6b81d386ef70d7d0317a1929bc0b4a3a30a451284450bbcf6901ba1a - url: "https://pub.dev" - source: hosted - version: "2.2.0" - source_span: - dependency: transitive - description: - name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" - url: "https://pub.dev" - source: hosted - version: "1.10.1" - sprintf: - dependency: transitive - description: - name: sprintf - sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" - url: "https://pub.dev" - source: hosted - version: "7.0.0" - sqflite: - dependency: transitive - description: - name: sqflite - sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03 - url: "https://pub.dev" - source: hosted - version: "2.4.2" - sqflite_android: - dependency: transitive - description: - name: sqflite_android - sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6" - url: "https://pub.dev" - source: hosted - version: "2.5.6" - sqflite_darwin: - dependency: transitive - description: - name: sqflite_darwin - sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3" - url: "https://pub.dev" - source: hosted - version: "2.4.2" - sqflite_platform_interface: - dependency: transitive - description: - name: sqflite_platform_interface - sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920" - url: "https://pub.dev" - source: hosted - version: "2.4.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" - url: "https://pub.dev" - source: hosted - version: "1.12.1" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - stream_transform: - dependency: transitive - description: - name: stream_transform - sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 - url: "https://pub.dev" - source: hosted - version: "2.1.1" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" - url: "https://pub.dev" - source: hosted - version: "1.4.1" - syncfusion_flutter_calendar: - dependency: "direct main" - description: - name: syncfusion_flutter_calendar - sha256: "8e8a4eef01d6a82ae2c17e76d497ff289ded274de014c9f471ffabc12d1e2e71" - url: "https://pub.dev" - source: hosted - version: "30.2.7" - syncfusion_flutter_core: - dependency: transitive - description: - name: syncfusion_flutter_core - sha256: bfd026c0f9822b49ff26fed11cd3334519acb6a6ad4b0c81d9cd18df6af1c4c0 - url: "https://pub.dev" - source: hosted - version: "30.2.7" - syncfusion_flutter_datepicker: - dependency: transitive - description: - name: syncfusion_flutter_datepicker - sha256: b5f35cc808e91b229d41613efe71dadab1549a35bfd493f922fc06ccc2fe908c - url: "https://pub.dev" - source: hosted - version: "30.2.7" - syncfusion_localizations: - dependency: transitive - description: - name: syncfusion_localizations - sha256: bb32b07879b4c1dee5d4c8ad1c57343a4fdae55d65a87f492727c11b68f23164 - url: "https://pub.dev" - source: hosted - version: "30.2.7" - synchronized: - dependency: transitive - description: - name: synchronized - sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 - url: "https://pub.dev" - source: hosted - version: "3.4.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" - url: "https://pub.dev" - source: hosted - version: "1.2.2" - test_api: - dependency: transitive - description: - name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" - url: "https://pub.dev" - source: hosted - version: "0.7.6" - time: - dependency: transitive - description: - name: time - sha256: "370572cf5d1e58adcb3e354c47515da3f7469dac3a95b447117e728e7be6f461" - url: "https://pub.dev" - source: hosted - version: "2.1.5" - timezone: - dependency: "direct main" - description: - name: timezone - sha256: dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1 - url: "https://pub.dev" - source: hosted - version: "0.10.1" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://pub.dev" - source: hosted - version: "1.4.0" - url_launcher: - dependency: "direct main" - description: - name: url_launcher - sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 - url: "https://pub.dev" - source: hosted - version: "6.3.2" - url_launcher_android: - dependency: transitive - description: - name: url_launcher_android - sha256: "81777b08c498a292d93ff2feead633174c386291e35612f8da438d6e92c4447e" - url: "https://pub.dev" - source: hosted - version: "6.3.20" - url_launcher_ios: - dependency: transitive - description: - name: url_launcher_ios - sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7 - url: "https://pub.dev" - source: hosted - version: "6.3.4" - url_launcher_linux: - dependency: transitive - description: - name: url_launcher_linux - sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - url_launcher_macos: - dependency: transitive - description: - name: url_launcher_macos - sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f - url: "https://pub.dev" - source: hosted - version: "3.2.3" - url_launcher_platform_interface: - dependency: transitive - description: - name: url_launcher_platform_interface - sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" - url: "https://pub.dev" - source: hosted - version: "2.3.2" - url_launcher_web: - dependency: transitive - description: - name: url_launcher_web - sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" - url: "https://pub.dev" - source: hosted - version: "2.4.1" - url_launcher_windows: - dependency: transitive - description: - name: url_launcher_windows - sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" - url: "https://pub.dev" - source: hosted - version: "3.1.4" - uuid: - dependency: "direct main" - description: - name: uuid - sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff - url: "https://pub.dev" - source: hosted - version: "4.5.1" - vector_graphics: - dependency: transitive - description: - name: vector_graphics - sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6 - url: "https://pub.dev" - source: hosted - version: "1.1.19" - vector_graphics_codec: - dependency: transitive - description: - name: vector_graphics_codec - sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146" - url: "https://pub.dev" - source: hosted - version: "1.1.13" - vector_graphics_compiler: - dependency: transitive - description: - name: vector_graphics_compiler - sha256: d354a7ec6931e6047785f4db12a1f61ec3d43b207fc0790f863818543f8ff0dc - url: "https://pub.dev" - source: hosted - version: "1.1.19" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b - url: "https://pub.dev" - source: hosted - version: "2.2.0" - video_player: - dependency: transitive - description: - name: video_player - sha256: "0d55b1f1a31e5ad4c4967bfaa8ade0240b07d20ee4af1dfef5f531056512961a" - url: "https://pub.dev" - source: hosted - version: "2.10.0" - video_player_android: - dependency: transitive - description: - name: video_player_android - sha256: "6cfe0b1e102522eda1e139b82bf00602181c5844fd2885340f595fb213d74842" - url: "https://pub.dev" - source: hosted - version: "2.8.14" - video_player_avfoundation: - dependency: transitive - description: - name: video_player_avfoundation - sha256: f9a780aac57802b2892f93787e5ea53b5f43cc57dc107bee9436458365be71cd - url: "https://pub.dev" - source: hosted - version: "2.8.4" - video_player_platform_interface: - dependency: transitive - description: - name: video_player_platform_interface - sha256: cf2a1d29a284db648fd66cbd18aacc157f9862d77d2cc790f6f9678a46c1db5a - url: "https://pub.dev" - source: hosted - version: "6.4.0" - video_player_web: - dependency: transitive - description: - name: video_player_web - sha256: "9f3c00be2ef9b76a95d94ac5119fb843dca6f2c69e6c9968f6f2b6c9e7afbdeb" - url: "https://pub.dev" - source: hosted - version: "2.4.0" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 - url: "https://pub.dev" - source: hosted - version: "15.0.0" - wakelock_plus: - dependency: transitive - description: - name: wakelock_plus - sha256: "61713aa82b7f85c21c9f4cd0a148abd75f38a74ec645fcb1e446f882c82fd09b" - url: "https://pub.dev" - source: hosted - version: "1.3.3" - wakelock_plus_platform_interface: - dependency: transitive - description: - name: wakelock_plus_platform_interface - sha256: "036deb14cd62f558ca3b73006d52ce049fabcdcb2eddfe0bf0fe4e8a943b5cf2" - url: "https://pub.dev" - source: hosted - version: "1.3.0" - web: - dependency: "direct main" - description: - name: web - sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" - url: "https://pub.dev" - source: hosted - version: "1.1.1" - webview_flutter: - dependency: transitive - description: - name: webview_flutter - sha256: c3e4fe614b1c814950ad07186007eff2f2e5dd2935eba7b9a9a1af8e5885f1ba - url: "https://pub.dev" - source: hosted - version: "4.13.0" - webview_flutter_android: - dependency: transitive - description: - name: webview_flutter_android - sha256: "9a25f6b4313978ba1c2cda03a242eea17848174912cfb4d2d8ee84a556f248e3" - url: "https://pub.dev" - source: hosted - version: "4.10.1" - webview_flutter_platform_interface: - dependency: transitive - description: - name: webview_flutter_platform_interface - sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0" - url: "https://pub.dev" - source: hosted - version: "2.14.0" - webview_flutter_wkwebview: - dependency: transitive - description: - name: webview_flutter_wkwebview - sha256: fb46db8216131a3e55bcf44040ca808423539bc6732e7ed34fb6d8044e3d512f - url: "https://pub.dev" - source: hosted - version: "3.23.0" - win32: - dependency: transitive - description: - name: win32 - sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" - url: "https://pub.dev" - source: hosted - version: "5.14.0" - win32_registry: - dependency: transitive - description: - name: win32_registry - sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - xml: - dependency: transitive - description: - name: xml - sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" - url: "https://pub.dev" - source: hosted - version: "6.6.1" -sdks: - dart: ">=3.8.1 <4.0.0" - flutter: ">=3.32.0" From f54ce71177f9cb4dbca7b13b90fefde1dc53268b Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 21 Jan 2026 10:07:15 +0300 Subject: [PATCH 07/10] translation changes --- lib/core/utils/utils.dart | 3 +- .../widgets/otp_verification_screen.dart | 16 +++---- .../appointment_details_page.dart | 46 +++++++++--------- .../appointment_payment_page.dart | 14 +++--- .../hospital_bottom_sheet_body.dart | 12 ++--- lib/presentation/authentication/login.dart | 18 +++---- .../authentication/quick_login.dart | 10 ++-- lib/presentation/authentication/register.dart | 24 +++++----- .../authentication/register_step2.dart | 36 +++++++------- .../book_appointment_page.dart | 48 +++++++++---------- .../book_appointment/select_clinic_page.dart | 8 ++-- .../widgets/appointment_calendar.dart | 6 +-- .../home/widgets/large_service_card.dart | 2 +- .../home/widgets/small_service_card.dart | 2 +- lib/presentation/lab/lab_orders_page.dart | 2 +- .../lab/lab_results/lab_result_details.dart | 8 ++-- .../medical_file/medical_file_page.dart | 16 +++---- .../profile_settings/profile_settings.dart | 31 ++++++------ lib/services/dialog_service.dart | 12 ++--- lib/widgets/app_language_change.dart | 2 +- lib/widgets/common_bottom_sheet.dart | 4 +- lib/widgets/input_widget.dart | 14 ++++-- 22 files changed, 171 insertions(+), 163 deletions(-) diff --git a/lib/core/utils/utils.dart b/lib/core/utils/utils.dart index e5b0ca4..5995438 100644 --- a/lib/core/utils/utils.dart +++ b/lib/core/utils/utils.dart @@ -814,7 +814,8 @@ class Utils { child: Utils.buildSvgWithAssets(icon: AppAssets.saudi_riyal_icon, width: iconSize.h, height: iconSize.h, iconColor: iconColor), ), 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( color: textColor, fontSize: fontSize ?? 32.f, diff --git a/lib/features/authentication/widgets/otp_verification_screen.dart b/lib/features/authentication/widgets/otp_verification_screen.dart index e33222c..7ddccda 100644 --- a/lib/features/authentication/widgets/otp_verification_screen.dart +++ b/lib/features/authentication/widgets/otp_verification_screen.dart @@ -545,20 +545,20 @@ class _OTPVerificationScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 10.h), - LocaleKeys.otpVerification.tr().toText24(isBold: true), + LocaleKeys.otpVerification.tr(context: context).toText24(isBold: true), SizedBox(height: 20.h), Wrap( spacing: 2.h, runSpacing: 2.h, 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), - 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) .toText15(color: AppColors.inputLabelTextColor, isBold: true, letterSpacing: -0.4), appState.getUserRegistrationPayload.isRegister != null && appState.getUserRegistrationPayload.isRegister == true - ? LocaleKeys.forRegistrationVerification.tr().toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4) - : LocaleKeys.forLoginVerification.tr().toText15(color: AppColors.inputLabelTextColor, letterSpacing: -0.4), + ? LocaleKeys.forRegistrationVerification.tr(context: context).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 { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - LocaleKeys.didntReceiveIt.tr().toText16(color: AppColors.inputLabelTextColor), + LocaleKeys.didntReceiveIt.tr(context: context).toText16(color: AppColors.inputLabelTextColor), SizedBox(width: 5.h), if (_resendTime > 0) Builder( @@ -599,7 +599,7 @@ class _OTPVerificationScreenState extends State { final seconds = (_resendTime % 60).toString().padLeft(2, '0'); return Row( children: [ - LocaleKeys.resendIn.tr().toText16(color: AppColors.inputLabelTextColor), + LocaleKeys.resendIn.tr(context: context).toText16(color: AppColors.inputLabelTextColor), SizedBox(width: 2.h), ' ($minutes:$seconds). '.toText16(color: AppColors.inputLabelTextColor) ], @@ -609,7 +609,7 @@ class _OTPVerificationScreenState extends State { else GestureDetector( onTap: _resendOtp, - child: LocaleKeys.resendOTP.tr().toText16(color: AppColors.primaryRedColor), + child: LocaleKeys.resendOTP.tr(context: context).toText16(color: AppColors.primaryRedColor), ), ], ), diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index 0b8066e..3f98e6d 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -87,7 +87,7 @@ class _AppointmentDetailsPageState extends State { children: [ Expanded( child: CollapsingListView( - title: LocaleKeys.appointmentDetails.tr(), + title: LocaleKeys.appointmentDetails.tr(context: context), report: AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) ? () { contactUsViewModel.setPatientFeedbackSelectedAppointment(widget.patientAppointmentHistoryResponseModel); @@ -105,7 +105,7 @@ class _AppointmentDetailsPageState extends State { AppointmentDoctorCard( patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, onAskDoctorTap: () async { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingDoctorAvailability.tr()); + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingDoctorAvailability.tr(context: context)); await myAppointmentsViewModel.isDoctorAvailable( projectID: widget.patientAppointmentHistoryResponseModel.projectID, doctorId: widget.patientAppointmentHistoryResponseModel.doctorID, @@ -135,7 +135,7 @@ class _AppointmentDetailsPageState extends State { onCancelTap: () async { myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.cancellingAppointmentPleaseWait.tr()); + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.cancellingAppointmentPleaseWait.tr(context: context)); await myAppointmentsViewModel.cancelAppointment( patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, onSuccess: (apiResponse) { @@ -144,7 +144,7 @@ class _AppointmentDetailsPageState extends State { myAppointmentsViewModel.getPatientAppointments(true, false); showCommonBottomSheetWithoutHeight( context, - child: Utils.getSuccessWidget(loadingText: LocaleKeys.appointmentCancelledSuccessfully.tr()), + child: Utils.getSuccessWidget(loadingText: LocaleKeys.appointmentCancelledSuccessfully.tr(context: context)), callBackFunc: () { Navigator.of(context).pop(); }, @@ -181,13 +181,13 @@ class _AppointmentDetailsPageState extends State { children: [ Row( children: [ - LocaleKeys.appointmentStatus.tr().toText16(isBold: true), + LocaleKeys.appointmentStatus.tr(context: context).toText16(isBold: true), ], ), SizedBox(height: 4.h), (!AppointmentType.isConfirmed(widget.patientAppointmentHistoryResponseModel) - ? LocaleKeys.notConfirmed.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500) - : LocaleKeys.confirmed.tr().toText12(color: AppColors.successColor, fontWeight: FontWeight.w500)), + ? LocaleKeys.notConfirmed.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500) + : LocaleKeys.confirmed.tr(context: context).toText12(color: AppColors.successColor, fontWeight: FontWeight.w500)), SizedBox(height: 16.h), //TODO Add countdown timer in case of LiveCare Appointment widget.patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false @@ -199,7 +199,7 @@ class _AppointmentDetailsPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, 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 { MapsLauncher.launchCoordinates(double.parse(widget.patientAppointmentHistoryResponseModel.latitude!), 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), borderColor: AppointmentType.getNextActionButtonColor(widget.patientAppointmentHistoryResponseModel.nextAction).withValues(alpha: 0.01), textColor: AppColors.whiteColor, @@ -280,7 +280,7 @@ class _AppointmentDetailsPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ 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(), @@ -365,7 +365,7 @@ class _AppointmentDetailsPageState extends State { isLargeText: true, iconSize: 36.w, ).onPress(() async { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingLabResults.tr()); + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingLabResults.tr(context: context)); await labViewModel.getLabResultsByAppointmentNo( appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo, projectID: widget.patientAppointmentHistoryResponseModel.projectID, @@ -398,7 +398,7 @@ class _AppointmentDetailsPageState extends State { isLargeText: true, iconSize: 36.w, ).onPress(() async { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingRadiologyResults.tr()); + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingRadiologyResults.tr(context: context)); await radiologyViewModel.getPatientRadiologyOrdersByAppointment( appointmentNo: widget.patientAppointmentHistoryResponseModel.appointmentNo, projectID: widget.patientAppointmentHistoryResponseModel.projectID, @@ -425,7 +425,7 @@ class _AppointmentDetailsPageState extends State { isLargeText: true, iconSize: 36.w, ).onPress(() async { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingAppointmentPrescriptions.tr()); + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingAppointmentPrescriptions.tr(context: context)); await prescriptionsViewModel.getPrescriptionDetails( getPrescriptionRequestModel(), onSuccess: (val) { @@ -453,7 +453,7 @@ class _AppointmentDetailsPageState extends State { } else { showCommonBottomSheetWithoutHeight( context, - child: Utils.getErrorWidget(loadingText: LocaleKeys.noPrescriptionsForAppointment.tr()), + child: Utils.getErrorWidget(loadingText: LocaleKeys.noPrescriptionsForAppointment.tr(context: context)), callBackFunc: () {}, isFullScreen: false, isCloseButtonVisible: true, @@ -522,7 +522,7 @@ class _AppointmentDetailsPageState extends State { // ], // ), // SizedBox(height: 16.h), - // LocaleKeys.prescriptions.tr().toText18(isBold: true), + // LocaleKeys.prescriptions.tr(context: context).toText18(isBold: true), // SizedBox(height: 16.h), // Consumer(builder: (context, prescriptionVM, child) { // return prescriptionVM.isPrescriptionsDetailsLoading @@ -708,7 +708,7 @@ class _AppointmentDetailsPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.amountBeforeTax.tr().toText18(isBold: true), + LocaleKeys.amountBeforeTax.tr(context: context).toText18(isBold: true), Utils.getPaymentAmountWithSymbol( widget.patientAppointmentHistoryResponseModel.patientShare!.toString().toText16(isBold: true), AppColors.blackColor, @@ -752,7 +752,7 @@ class _AppointmentDetailsPageState extends State { ).paddingOnly(left: 16.h, top: 24.h, right: 16.h, bottom: 0.h), AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel) ? CustomButton( - text: LocaleKeys.rebookAppointment.tr(), + text: LocaleKeys.rebookAppointment.tr(context: context), onPressed: () { openDoctorScheduleCalendar(); }, @@ -810,13 +810,13 @@ class _AppointmentDetailsPageState extends State { projectName: widget.patientAppointmentHistoryResponseModel.projectName, ); bookAppointmentsViewModel.setSelectedDoctor(doctor); - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingDoctorSchedulePleaseWait.tr()); + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingDoctorSchedulePleaseWait.tr(context: context)); await bookAppointmentsViewModel.getDoctorFreeSlots( isBookingForLiveCare: false, onSuccess: (dynamic respData) async { LoaderBottomSheet.hideLoader(); showCommonBottomSheetWithoutHeight( - title: LocaleKeys.pickADate.tr(), + title: LocaleKeys.pickADate.tr(context: context), context, child: AppointmentCalendar(), isFullScreen: false, @@ -841,14 +841,14 @@ class _AppointmentDetailsPageState extends State { case 0: break; case 10: - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.confirmingAppointmentPleaseWait.tr()); + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.confirmingAppointmentPleaseWait.tr(context: context)); await myAppointmentsViewModel.confirmAppointment( patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, onSuccess: (apiResponse) { LoaderBottomSheet.hideLoader(); myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); 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(); }, title: "", @@ -869,10 +869,10 @@ class _AppointmentDetailsPageState extends State { ), ); case 50: - // return LocaleKeys.confirmLiveCare.tr(); + // return LocaleKeys.confirmLiveCare.tr(context: context); case 90: showCommonBottomSheetWithoutHeight(context, - title: LocaleKeys.onlineCheckIn.tr(), + title: LocaleKeys.onlineCheckIn.tr(context: context), child: AppointmentCheckinBottomSheet( patientAppointmentHistoryResponseModel: widget.patientAppointmentHistoryResponseModel, myAppointmentsViewModel: myAppointmentsViewModel, diff --git a/lib/presentation/appointments/appointment_payment_page.dart b/lib/presentation/appointments/appointment_payment_page.dart index a38a9f1..f817a89 100644 --- a/lib/presentation/appointments/appointment_payment_page.dart +++ b/lib/presentation/appointments/appointment_payment_page.dart @@ -90,7 +90,7 @@ class _AppointmentPaymentPageState extends State { children: [ Expanded( child: CollapsingListView( - title: LocaleKeys.appointmentPayment.tr(), + title: LocaleKeys.appointmentPayment.tr(context: context), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -248,7 +248,7 @@ class _AppointmentPaymentPageState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.insuranceExpiredOrInactive.tr() + LocaleKeys.insuranceExpiredOrInactive.tr(context: context) .toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500) .paddingSymmetrical(24.h, 0.h), CustomButton( @@ -274,12 +274,12 @@ class _AppointmentPaymentPageState extends State { ) : const SizedBox(), 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), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.amountBeforeTax.tr().toText14(isBold: true), + LocaleKeys.amountBeforeTax.tr(context: context).toText14(isBold: true), Utils.getPaymentAmountWithSymbol( myAppointmentsVM.patientAppointmentShareResponseModel!.patientShare!.toString().toText16(isBold: true), AppColors.blackColor, @@ -380,7 +380,7 @@ class _AppointmentPaymentPageState extends State { } void checkPaymentStatus() async { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingPaymentStatusPleaseWait.tr()); + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.checkingPaymentStatusPleaseWait.tr(context: context)); if (selectedPaymentMethod == "TAMARA") { await payfortViewModel.checkTamaraPaymentStatus( transactionID: transID, @@ -438,7 +438,7 @@ class _AppointmentPaymentPageState extends State { LoaderBottomSheet.hideLoader(); showCommonBottomSheetWithoutHeight( context, - child: Utils.getErrorWidget(loadingText: LocaleKeys.paymentFailedPleaseTryAgain.tr()), + child: Utils.getErrorWidget(loadingText: LocaleKeys.paymentFailedPleaseTryAgain.tr(context: context)), callBackFunc: () {}, isFullScreen: false, isCloseButtonVisible: true, @@ -519,7 +519,7 @@ class _AppointmentPaymentPageState extends State { } else { showCommonBottomSheetWithoutHeight( context, - child: Utils.getErrorWidget(loadingText: LocaleKeys.paymentFailedPleaseTryAgain.tr()), + child: Utils.getErrorWidget(loadingText: LocaleKeys.paymentFailedPleaseTryAgain.tr(context: context)), callBackFunc: () {}, isFullScreen: false, isCloseButtonVisible: true, diff --git a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart index eed45df..f3301f0 100644 --- a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart +++ b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart @@ -32,7 +32,7 @@ import '../../../emergency_services/call_ambulance/widgets/type_selection_widget // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // Text( -// LocaleKeys.selectHospital.tr(), +// LocaleKeys.selectHospital.tr(context: context), // style: TextStyle( // fontSize: 21, // fontWeight: FontWeight.w600, @@ -40,7 +40,7 @@ import '../../../emergency_services/call_ambulance/widgets/type_selection_widget // ), // ), // Text( -// LocaleKeys.selectHospitalSubTitle.tr(), +// LocaleKeys.selectHospitalSubTitle.tr(context: context), // style: TextStyle( // fontSize: 16, // fontWeight: FontWeight.w500, @@ -49,8 +49,8 @@ import '../../../emergency_services/call_ambulance/widgets/type_selection_widget // ), // SizedBox(height: 16.h), // TextInputWidget( -// labelText: LocaleKeys.search.tr(), -// hintText: LocaleKeys.searchHospital.tr(), +// labelText: LocaleKeys.search.tr(context: context), +// hintText: LocaleKeys.searchHospital.tr(context: context), // controller: searchText, // onChange: (value) { // appointmentsViewModel.filterHospitalListByString( @@ -135,8 +135,8 @@ class HospitalBottomSheetBody extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ TextInputWidget( - labelText: LocaleKeys.search.tr(), - hintText: LocaleKeys.searchHospital.tr(), + labelText: LocaleKeys.search.tr(context: context), + hintText: LocaleKeys.searchHospital.tr(context: context), controller: searchText, onChange: (value) { debouncer.run((){ diff --git a/lib/presentation/authentication/login.dart b/lib/presentation/authentication/login.dart index a59062d..6dcf15f 100644 --- a/lib/presentation/authentication/login.dart +++ b/lib/presentation/authentication/login.dart @@ -71,10 +71,10 @@ class LoginScreenState extends State { children: [ 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 - LocaleKeys.welcomeToDrSulaiman.tr().toText32(isBold: true, color: AppColors.textColor), + LocaleKeys.welcomeToDrSulaiman.tr(context: context).toText32(isBold: true, color: AppColors.textColor), SizedBox(height: 32.h), TextInputWidget( - labelText: "${LocaleKeys.nationalId.tr()} / ${LocaleKeys.fileNo.tr()}", + labelText: "${LocaleKeys.nationalId.tr(context: context)} / ${LocaleKeys.fileNo.tr(context: context)}", hintText: "xxxxxxxxx", controller: authVm.nationalIdController, focusNode: _nationalIdFocusNode, @@ -87,13 +87,13 @@ class LoginScreenState extends State { isAllowLeadingIcon: true, padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 10.h), leadingIcon: AppAssets.student_card, - errorMessage: LocaleKeys.enterValidIDorIqama.tr(), + errorMessage: LocaleKeys.enterValidIDorIqama.tr(context: context), hasError: false, ), SizedBox(height: 16.h), CustomButton( height: 50.h, - text: LocaleKeys.login.tr(), + text: LocaleKeys.login.tr(context: context), icon: AppAssets.login1, iconColor: Colors.white, onPressed: () { @@ -116,10 +116,10 @@ class LoginScreenState extends State { text: TextSpan( style: context.dynamicTextStyle(color: Colors.black, fontSize: 14.f, height: 26 / 16, fontWeight: FontWeight.w500), children: [ - TextSpan(text: LocaleKeys.dontHaveAccount.tr(), style: context.dynamicTextStyle()), + TextSpan(text: LocaleKeys.dontHaveAccount.tr(context: context), style: context.dynamicTextStyle()), TextSpan(text: " "), TextSpan( - text: LocaleKeys.registernow.tr(), + text: LocaleKeys.registernow.tr(context: context), style: context.dynamicTextStyle( color: AppColors.primaryRedColor, fontSize: 14.f, // Adjusted to sizer unit @@ -172,7 +172,7 @@ class LoginScreenState extends State { Padding( padding: EdgeInsets.only(bottom: 10.h), child: CustomButton( - text: LocaleKeys.sendOTPSMS.tr(), + text: LocaleKeys.sendOTPSMS.tr(context: context), onPressed: () async { if (ValidationUtils.isValidatePhone( phoneNumber: phoneNumberController!.text, @@ -196,14 +196,14 @@ class LoginScreenState extends State { children: [ Padding( 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: EdgeInsets.only(bottom: 10.h, top: 10.h), child: CustomButton( - text: LocaleKeys.sendOTPWHATSAPP.tr(), + text: LocaleKeys.sendOTPWHATSAPP.tr(context: context), onPressed: () async { if (ValidationUtils.isValidatePhone( phoneNumber: phoneNumberController!.text, diff --git a/lib/presentation/authentication/quick_login.dart b/lib/presentation/authentication/quick_login.dart index bdeb0ff..fbcb17d 100644 --- a/lib/presentation/authentication/quick_login.dart +++ b/lib/presentation/authentication/quick_login.dart @@ -49,7 +49,7 @@ class QuickLoginState extends State { ], ), 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( // ' TranslationBase.of(context).allSet', // textAlign: TextAlign.center, @@ -67,7 +67,7 @@ class QuickLoginState extends State { children: [ Image.asset(AppAssets.lockIcon, height: 100), SizedBox(height: 10.h), - LocaleKeys.enableQuickLogin.tr().toText26(isBold: true), + LocaleKeys.enableQuickLogin.tr(context: context).toText26(isBold: true), // Text( // ' TranslationBase.of(context).enableQuickLogin', // style: context.dynamicTextStyle( @@ -77,7 +77,7 @@ class QuickLoginState extends State { // ), // ), SizedBox(height: 5.h), - LocaleKeys.enableQuickLogin.tr().toText16(color: AppColors.quickLoginColor), + LocaleKeys.enableQuickLogin.tr(context: context).toText16(color: AppColors.quickLoginColor), // Description // Text( // 'TranslationBase.of(context).enableMsg', @@ -94,7 +94,7 @@ class QuickLoginState extends State { children: [ Expanded( child: CustomButton( - text: LocaleKeys.enableQuickLogin.tr(), + text: LocaleKeys.enableQuickLogin.tr(context: context), onPressed: () { widget.onPressed(); }, @@ -114,7 +114,7 @@ class QuickLoginState extends State { children: [ Expanded( child: CustomButton( - text: LocaleKeys.notNow.tr(), + text: LocaleKeys.notNow.tr(context: context), onPressed: () { cacheService.saveBool(key: CacheConst.quickLoginEnabled, value: false); Navigator.pop(context, "true"); diff --git a/lib/presentation/authentication/register.dart b/lib/presentation/authentication/register.dart index fa10b95..d14419f 100644 --- a/lib/presentation/authentication/register.dart +++ b/lib/presentation/authentication/register.dart @@ -80,7 +80,7 @@ class _RegisterNew extends State { children: [ 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), - LocaleKeys.prepareToElevate.tr().toText32(isBold: true), + LocaleKeys.prepareToElevate.tr(context: context).toText32(isBold: true), SizedBox(height: 24.h), Directionality( textDirection: Directionality.of(context), @@ -96,7 +96,7 @@ class _RegisterNew extends State { ).withVerticalPadding(8.h), Divider(height: 1.h), TextInputWidget( - labelText: LocaleKeys.nationalIdNumber.tr(), + labelText: LocaleKeys.nationalIdNumber.tr(context: context), hintText: "xxxxxxxxx", controller: authVm.nationalIdController, focusNode: _nationalIdFocusNode, @@ -111,7 +111,7 @@ class _RegisterNew extends State { ).withVerticalPadding(8), Divider(height: 1), TextInputWidget( - labelText: LocaleKeys.dob.tr(), + labelText: LocaleKeys.dob.tr(context: context), hintText: "11 July, 1994", controller: authVm.dobController, focusNode: _dobFocusNode, @@ -156,7 +156,7 @@ class _RegisterNew extends State { Row( children: [ Text( - LocaleKeys.iAcceptThe.tr(), + LocaleKeys.iAcceptThe.tr(context: context), style: context.dynamicTextStyle(fontSize: 14.f, fontWeight: FontWeight.w500, color: Color(0xFF2E3039)), ), GestureDetector( @@ -165,7 +165,7 @@ class _RegisterNew extends State { Navigator.of(context).pushNamed('/terms'); }, child: Text( - LocaleKeys.termsConditoins.tr(), + LocaleKeys.termsConditoins.tr(context: context), style: context.dynamicTextStyle( fontSize: 14.f, fontWeight: FontWeight.w500, @@ -179,7 +179,7 @@ class _RegisterNew extends State { ), // Expanded( // 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)), // ), // ), @@ -188,7 +188,7 @@ class _RegisterNew extends State { ), SizedBox(height: 25.h), CustomButton( - text: LocaleKeys.registernow.tr(), + text: LocaleKeys.registernow.tr(context: context), icon: AppAssets.note_edit, onPressed: () { // Dismiss keyboard before proceeding @@ -220,10 +220,10 @@ class _RegisterNew extends State { fontWeight: FontWeight.w500, ), children: [ - TextSpan(text: LocaleKeys.alreadyHaveAccount.tr(), style: context.dynamicTextStyle()), + TextSpan(text: LocaleKeys.alreadyHaveAccount.tr(context: context), style: context.dynamicTextStyle()), TextSpan(text: " "), TextSpan( - text: LocaleKeys.loginNow.tr(), + text: LocaleKeys.loginNow.tr(context: context), style: context.dynamicTextStyle( color: AppColors.primaryRedColor, fontSize: 16.f, @@ -271,7 +271,7 @@ class _RegisterNew extends State { Padding( padding: const EdgeInsets.only(bottom: 10), child: CustomButton( - text: LocaleKeys.sendOTPSMS.tr(), + text: LocaleKeys.sendOTPSMS.tr(context: context), onPressed: () async { // Dismiss keyboard before validation FocusScope.of(context).unfocus(); @@ -298,14 +298,14 @@ class _RegisterNew extends State { children: [ Padding( 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: EdgeInsets.only(bottom: 10.h, top: 10.h), child: CustomButton( - text: LocaleKeys.sendOTPWHATSAPP.tr(), + text: LocaleKeys.sendOTPWHATSAPP.tr(context: context), onPressed: () async { FocusScope.of(context).unfocus(); if (ValidationUtils.isValidatePhone( diff --git a/lib/presentation/authentication/register_step2.dart b/lib/presentation/authentication/register_step2.dart index 71cef96..c4bdf0f 100644 --- a/lib/presentation/authentication/register_step2.dart +++ b/lib/presentation/authentication/register_step2.dart @@ -73,7 +73,7 @@ class _RegisterNew extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - 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), Container( decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(24)), @@ -81,8 +81,8 @@ class _RegisterNew extends State { child: Column( children: [ TextInputWidget( - labelText: authVM!.isUserFromUAE() ? LocaleKeys.fullName.tr() : LocaleKeys.name.tr(), - hintText: authVM!.isUserFromUAE() ? LocaleKeys.enterNameHere.tr() : (name), + labelText: authVM!.isUserFromUAE() ? LocaleKeys.fullName.tr(context: context) : LocaleKeys.name.tr(context: context), + hintText: authVM!.isUserFromUAE() ? LocaleKeys.enterNameHere.tr(context: context) : (name), controller: authVM!.isUserFromUAE() ? authVM!.nameController : null, isEnable: true, prefix: null, @@ -100,7 +100,7 @@ class _RegisterNew extends State { ).paddingSymmetrical(0.h, 16.h), Divider(height: 1.h, color: AppColors.greyColor), TextInputWidget( - labelText: LocaleKeys.nationalIdNumber.tr(), + labelText: LocaleKeys.nationalIdNumber.tr(context: context), hintText: authVM!.isUserFromUAE() ? appState.getUserRegistrationPayload.patientIdentificationId.toString() : (appState.getNHICUserData.idNumber ?? ""), controller: null, isEnable: true, @@ -120,8 +120,8 @@ class _RegisterNew extends State { builder: (context, genderType, child) { final authVM = context.read(); return DropdownWidget( - labelText: LocaleKeys.gender.tr(), - hintText: LocaleKeys.malE.tr(), + labelText: LocaleKeys.gender.tr(context: context), + hintText: LocaleKeys.malE.tr(context: context), isEnable: true, dropdownItems: GenderTypeEnum.values.map((e) => appState.isArabic() ? e.typeAr : e.type).toList(), selectedValue: genderType != null ? (appState.isArabic() ? genderType.typeAr : genderType.type) : "", @@ -136,7 +136,7 @@ class _RegisterNew extends State { ).withVerticalPadding(8); }) : TextInputWidget( - labelText: LocaleKeys.gender.tr(), + labelText: LocaleKeys.gender.tr(context: context), hintText: (appState.getNHICUserData.gender ?? ""), controller: null, isEnable: true, @@ -157,8 +157,8 @@ class _RegisterNew extends State { builder: (context, maritalStatus, child) { final authVM = context.read(); // For onChange return DropdownWidget( - labelText: LocaleKeys.maritalStatus.tr(), - hintText: LocaleKeys.married.tr(), + labelText: LocaleKeys.maritalStatus.tr(context: context), + hintText: LocaleKeys.married.tr(context: context), isEnable: true, dropdownItems: MaritalStatusTypeEnum.values.map((e) => appState.isArabic() ? e.typeAr : e.type).toList(), selectedValue: maritalStatus != null ? (appState.isArabic() ? maritalStatus.typeAr : maritalStatus.type) : "", @@ -174,7 +174,7 @@ class _RegisterNew extends State { }, ) : TextInputWidget( - labelText: LocaleKeys.maritalStatus.tr(), + labelText: LocaleKeys.maritalStatus.tr(context: context), hintText: appState.isArabic() ? (MaritalStatusTypeExtension.fromValue(appState.getNHICUserData.maritalStatusCode)!.typeAr) : (MaritalStatusTypeExtension.fromValue(appState.getNHICUserData.maritalStatusCode)!.type), @@ -203,8 +203,8 @@ class _RegisterNew extends State { builder: (context, data, child) { final authVM = context.read(); return DropdownWidget( - labelText: LocaleKeys.country.tr(), - hintText: LocaleKeys.uae.tr(), + labelText: LocaleKeys.country.tr(context: context), + hintText: LocaleKeys.uae.tr(context: context), isEnable: true, dropdownItems: (data.countriesList ?? []).map((e) => data.isArabic ? e.nameN ?? "" : e.name ?? "").toList(), selectedValue: data.selectedCountry != null @@ -224,7 +224,7 @@ class _RegisterNew extends State { }, ) : TextInputWidget( - labelText: LocaleKeys.nationality.tr(), + labelText: LocaleKeys.nationality.tr(context: context), 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()).name ?? ""), @@ -243,7 +243,7 @@ class _RegisterNew extends State { color: AppColors.greyColor, ), TextInputWidget( - labelText: LocaleKeys.mobileNumber.tr(), + labelText: LocaleKeys.mobileNumber.tr(context: context), hintText: (appState.getUserRegistrationPayload.patientMobileNumber.toString() ?? ""), controller: null, isEnable: false, @@ -260,7 +260,7 @@ class _RegisterNew extends State { color: AppColors.greyColor, ), TextInputWidget( - labelText: LocaleKeys.dob.tr(), + labelText: LocaleKeys.dob.tr(context: context), hintText: authVM!.isUserFromUAE() ? appState.getUserRegistrationPayload.dob! : appState.getNHICUserData.dateOfBirth ?? "", controller: authVM!.isUserFromUAE() ? authVM!.dobController : null, isEnable: false, @@ -280,7 +280,7 @@ class _RegisterNew extends State { children: [ Expanded( child: CustomButton( - text: LocaleKeys.cancel.tr(), + text: LocaleKeys.cancel.tr(context: context), icon: AppAssets.cancel, onPressed: () { Navigator.of(context).pop(); @@ -298,7 +298,7 @@ class _RegisterNew extends State { backgroundColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedColor, textColor: AppColors.whiteColor, - text: LocaleKeys.confirm.tr(), + text: LocaleKeys.confirm.tr(context: context), icon: AppAssets.confirm, iconColor: AppColors.whiteColor, onPressed: () { @@ -345,7 +345,7 @@ class _RegisterNew extends State { Padding( padding: const EdgeInsets.only(bottom: 10), child: CustomButton( - text: LocaleKeys.submit.tr(), + text: LocaleKeys.submit.tr(context: context), onPressed: () { if (ValidationUtils.isValidateEmail( email: authVM!.emailController.text, diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart index 39d5eee..bc0c49a 100644 --- a/lib/presentation/book_appointment/book_appointment_page.dart +++ b/lib/presentation/book_appointment/book_appointment_page.dart @@ -89,8 +89,8 @@ class _BookAppointmentPageState extends State { activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), initialIndex: bookAppointmentsVM.selectedTabIndex, tabs: [ - CustomTabBarModel(null, LocaleKeys.general.tr()), - CustomTabBarModel(null, LocaleKeys.liveCare.tr()), + CustomTabBarModel(null, LocaleKeys.general.tr(context: context)), + CustomTabBarModel(null, LocaleKeys.liveCare.tr(context: context)), ], onTabChange: (index) { bookAppointmentsVM.onTabChanged(index); @@ -121,7 +121,7 @@ class _BookAppointmentPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ 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: 110.h, @@ -232,8 +232,8 @@ class _BookAppointmentPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.searchByClinic.tr().toText14(color: AppColors.textColor, weight: FontWeight.w500), - LocaleKeys.tapToSelectClinic.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), + LocaleKeys.searchByClinic.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500), + LocaleKeys.tapToSelectClinic.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), ], ), ], @@ -264,8 +264,8 @@ class _BookAppointmentPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.searchByDoctor.tr().toText14(color: AppColors.textColor, weight: FontWeight.w500), - LocaleKeys.tapToSelect.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), + LocaleKeys.searchByDoctor.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500), + LocaleKeys.tapToSelect.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), ], ), ], @@ -294,8 +294,8 @@ class _BookAppointmentPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.searchByRegion.tr().toText14(color: AppColors.textColor, weight: FontWeight.w500), - LocaleKeys.centralRegion.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), + LocaleKeys.searchByRegion.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500), + LocaleKeys.centralRegion.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), ], ), ], @@ -340,8 +340,8 @@ class _BookAppointmentPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.immediateConsultation.tr().toText14(color: AppColors.textColor, weight: FontWeight.w500), - LocaleKeys.tapToSelectClinic.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), + LocaleKeys.immediateConsultation.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500), + LocaleKeys.tapToSelectClinic.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), ], ), ], @@ -382,8 +382,8 @@ class _BookAppointmentPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.scheduledConsultation.tr().toText14(color: AppColors.textColor, weight: FontWeight.w500), - LocaleKeys.tapToSelectClinic.tr().toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), + LocaleKeys.scheduledConsultation.tr(context: context).toText14(color: AppColors.textColor, weight: FontWeight.w500), + LocaleKeys.tapToSelectClinic.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), ], ), ], @@ -412,7 +412,7 @@ class _BookAppointmentPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, 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), ], ), @@ -447,9 +447,9 @@ class _BookAppointmentPageState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, 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), - LocaleKeys.mentionYourSymptomsAndFindDoctors.tr().toText12( + LocaleKeys.mentionYourSymptomsAndFindDoctors.tr(context: context).toText12( fontWeight: FontWeight.w500, color: AppColors.greyTextColor, ), @@ -531,7 +531,7 @@ class _BookAppointmentPageState extends State { getTitle(AppointmentViaRegionViewmodel data) { if (data.selectedRegionId == null) { - return LocaleKeys.selectRegion.tr().toText20(weight: FontWeight.w600); + return LocaleKeys.selectRegion.tr(context: context).toText20(weight: FontWeight.w600); } else { return Transform.flip( flipX: data.isArabic ? true : false, @@ -558,8 +558,8 @@ class _BookAppointmentPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.immediateService.tr().toText18(color: AppColors.textColor, isBold: true), - LocaleKeys.noNeedToWaitGetMedicalConsultation.tr().toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + LocaleKeys.immediateService.tr(context: context).toText18(color: AppColors.textColor, isBold: true), + LocaleKeys.noNeedToWaitGetMedicalConsultation.tr(context: context).toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), ], ), ), @@ -574,7 +574,7 @@ class _BookAppointmentPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, 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), ], ), @@ -590,8 +590,8 @@ class _BookAppointmentPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.doctorWillContact.tr().toText18(color: AppColors.textColor, isBold: true), - LocaleKeys.specialisedDoctorWillContactYou.tr().toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + LocaleKeys.doctorWillContact.tr(context: context).toText18(color: AppColors.textColor, isBold: true), + LocaleKeys.specialisedDoctorWillContactYou.tr(context: context).toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), ], ), ), @@ -606,8 +606,8 @@ class _BookAppointmentPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.freeMedicineDelivery.tr().toText18(color: AppColors.textColor, isBold: true), - LocaleKeys.offersFreeMedicineDelivery.tr().toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), + LocaleKeys.freeMedicineDelivery.tr(context: context).toText18(color: AppColors.textColor, isBold: true), + LocaleKeys.offersFreeMedicineDelivery.tr(context: context).toText14(color: AppColors.greyTextColor, weight: FontWeight.w500), ], ), ), diff --git a/lib/presentation/book_appointment/select_clinic_page.dart b/lib/presentation/book_appointment/select_clinic_page.dart index e76e1c9..d96c9da 100644 --- a/lib/presentation/book_appointment/select_clinic_page.dart +++ b/lib/presentation/book_appointment/select_clinic_page.dart @@ -79,7 +79,7 @@ class _SelectClinicPageState extends State { 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), child: CustomButton( - text: LocaleKeys.bookAppo.tr(), + text: LocaleKeys.bookAppo.tr(context: context), onPressed: () { if (widget.calculatedResult["clinicId"] == null) { bookAppointmentsViewModel.setIsDoctorsListLoading(true); @@ -1097,7 +1097,7 @@ class _SelectClinicPageState extends State { getTitle(AppointmentViaRegionViewmodel data) { if (data.selectedRegionId == null) { - return LocaleKeys.selectRegion.tr().toText20(weight: FontWeight.w600); + return LocaleKeys.selectRegion.tr(context: context).toText20(weight: FontWeight.w600); } else { return Transform.flip( flipX: data.isArabic ? true : false, @@ -1185,7 +1185,7 @@ class _SelectClinicPageState extends State { children: [ Expanded( child: CustomButton( - text: LocaleKeys.cancel.tr(), + text: LocaleKeys.cancel.tr(context: context), onPressed: () { bookAppointmentsViewModel.setIsContinueDentalPlan(false); bookAppointmentsViewModel.setIsChiefComplaintsListLoading(true); @@ -1206,7 +1206,7 @@ class _SelectClinicPageState extends State { SizedBox(width: 8.h), Expanded( child: CustomButton( - text: LocaleKeys.confirm.tr(), + text: LocaleKeys.confirm.tr(context: context), onPressed: () async { bookAppointmentsViewModel.setIsContinueDentalPlan(true); Navigator.of(context).pop(); diff --git a/lib/presentation/book_appointment/widgets/appointment_calendar.dart b/lib/presentation/book_appointment/widgets/appointment_calendar.dart index c91e7a7..8fa72d4 100644 --- a/lib/presentation/book_appointment/widgets/appointment_calendar.dart +++ b/lib/presentation/book_appointment/widgets/appointment_calendar.dart @@ -204,13 +204,13 @@ class _AppointmentCalendarState extends State { children: [ Lottie.asset(AppAnimations.errorAnimation, repeat: true, reverse: false, frameRate: FrameRate(60), width: 100.h, height: 100.h, fit: BoxFit.fill), SizedBox(height: 8.h), - (LocaleKeys.loginToUseService.tr()).toText16(color: AppColors.blackColor), + (LocaleKeys.loginToUseService.tr(context: context)).toText16(color: AppColors.blackColor), SizedBox(height: 16.h), Row( children: [ Expanded( child: CustomButton( - text: LocaleKeys.cancel.tr(), + text: LocaleKeys.cancel.tr(context: context), onPressed: () { Navigator.of(context).pop(); }, @@ -224,7 +224,7 @@ class _AppointmentCalendarState extends State { SizedBox(width: 8.h), Expanded( child: CustomButton( - text: LocaleKeys.confirm.tr(), + text: LocaleKeys.confirm.tr(context: context), onPressed: () async { Navigator.of(context).pop(); Navigator.pushAndRemoveUntil( diff --git a/lib/presentation/home/widgets/large_service_card.dart b/lib/presentation/home/widgets/large_service_card.dart index 5df415d..9292004 100644 --- a/lib/presentation/home/widgets/large_service_card.dart +++ b/lib/presentation/home/widgets/large_service_card.dart @@ -97,7 +97,7 @@ class LargeServiceCard extends StatelessWidget { ], ).paddingSymmetrical(12.w, 24.h), 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: () { handleOnTap(); }, diff --git a/lib/presentation/home/widgets/small_service_card.dart b/lib/presentation/home/widgets/small_service_card.dart index 2ccf21c..390c001 100644 --- a/lib/presentation/home/widgets/small_service_card.dart +++ b/lib/presentation/home/widgets/small_service_card.dart @@ -173,7 +173,7 @@ class SmallServiceCard extends StatelessWidget { void openIndoorNavigationBottomSheet(BuildContext context) { showCommonBottomSheetWithoutHeight( - title: LocaleKeys.selectHospital.tr(), + title: LocaleKeys.selectHospital.tr(context: context), context, child: ChangeNotifierProvider( create: (context) => HospitalSelectionBottomSheetViewModel(getIt()), diff --git a/lib/presentation/lab/lab_orders_page.dart b/lib/presentation/lab/lab_orders_page.dart index 799f574..538f250 100644 --- a/lib/presentation/lab/lab_orders_page.dart +++ b/lib/presentation/lab/lab_orders_page.dart @@ -1 +1 @@ -import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.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/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.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/features/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart'; import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_toolbar.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; import 'alphabeticScroll.dart'; class LabOrdersPage extends StatefulWidget { const LabOrdersPage({super.key}); @override State createState() => _LabOrdersPageState(); } class _LabOrdersPageState extends State { late LabViewModel labProvider; late DateRangeSelectorRangeViewModel rangeViewModel; late AppState _appState; List?> labSuggestions = []; int? expandedIndex; String? selectedFilterText = ''; int activeIndex = 0; @override void initState() { scheduleMicrotask(() { labProvider.initLabProvider(); }); super.initState(); } @override Widget build(BuildContext context) { labProvider = Provider.of(context, listen: false); rangeViewModel = Provider.of(context); _appState = getIt(); return CollapsingToolbar( title: LocaleKeys.labResults.tr(), search: () async { final lavVM = Provider.of(context, listen: false); if (lavVM.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: lavVM.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; lavVM.filterLabReports(value); } } }, child: Consumer( builder: (context, model, child) { return SingleChildScrollView( physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.all(24.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: CustomTabBar( activeTextColor: Color(0xffED1C2B), activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), tabs: [ CustomTabBarModel(null, LocaleKeys.byVisit.tr()), CustomTabBarModel(null, LocaleKeys.byTest.tr()), // CustomTabBarModel(null, "Completed".needTranslation), ], onTabChange: (index) { activeIndex = index; setState(() {}); }, ), ), ], ), if (activeIndex == 0) Padding( padding: EdgeInsets.symmetric(vertical: 10.h), child: Row( children: [ CustomButton( text: LocaleKeys.byClinic.tr(context: context), onPressed: () { model.setIsSortByClinic(true); }, backgroundColor: model.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, borderColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), SizedBox(width: 8.h), CustomButton( text: LocaleKeys.byHospital.tr(context: context), onPressed: () { model.setIsSortByClinic(false); }, backgroundColor: model.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, borderColor: model.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, textColor: model.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ], ), ), SizedBox(height: 8.h), selectedFilterText!.isNotEmpty ? CustomChipWidget( chipText: selectedFilterText!, chipType: ChipTypeEnum.alert, isSelected: true, ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available model.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (model.patientLabOrdersViewList.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: model.patientLabOrdersViewList.length, itemBuilder: (context, index) { final group = model.patientLabOrdersViewList[index]; final isExpanded = expandedIndex == index; return AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 500), child: SlideAnimation( verticalOffset: 100.0, child: FadeInAnimation( child: AnimatedContainer( duration: Duration(milliseconds: 300), curve: Curves.easeInOut, margin: EdgeInsets.symmetric(vertical: 8.h), decoration: RoundedRectangleBorder() .toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true), child: InkWell( onTap: () { setState(() { expandedIndex = isExpanded ? null : index; }); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.all(16.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppCustomChipWidget(labelText: "${group.length} ${LocaleKeys.results.tr(context: context)}"), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), Text( model.isSortByClinic ? (group.first.clinicDescription ?? 'Unknown') : (group.first.projectName ?? 'Unknown'), style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), overflow: TextOverflow.ellipsis, ), ], ), ), AnimatedSwitcher( duration: Duration(milliseconds: 500), switchInCurve: Curves.easeIn, switchOutCurve: Curves.easeOut, transitionBuilder: (Widget child, Animation animation) { return FadeTransition( opacity: animation, child: SizeTransition( sizeFactor: animation, axisAlignment: 0.0, child: child, ), ); }, child: isExpanded ? Container( key: ValueKey(index), padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 0.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ...group.map((order) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Image.network( order.doctorImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", width: 24.w, height: 24.h, fit: BoxFit.cover, ).circle(100), SizedBox(width: 8.h), Expanded(child: (order.doctorName ?? order.doctorNameEnglish ?? "").toString().toText14(weight: FontWeight.w500)), ], ), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ AppCustomChipWidget( labelText: ("${LocaleKeys.orderNo.tr()}: ${order.orderNo!}"), ), AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), ), AppCustomChipWidget( labelText: model.isSortByClinic ? (order.clinicDescription ?? "") : (order.projectName ?? ""), ), ], ), // Row( // children: [ // CustomButton( // text: ("Order No: ".needTranslation + order.orderNo!), // onPressed: () {}, // backgroundColor: AppColors.greyColor, // borderColor: AppColors.greyColor, // textColor: AppColors.blackColor, // fontSize: 10, // fontWeight: FontWeight.w500, // borderRadius: 8, // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), // height: 24.h, // ), // SizedBox(width: 8.h), // CustomButton( // text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), // onPressed: () {}, // backgroundColor: AppColors.greyColor, // borderColor: AppColors.greyColor, // textColor: AppColors.blackColor, // fontSize: 10, // fontWeight: FontWeight.w500, // borderRadius: 8, // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), // height: 24.h, // ), // ], // ), // SizedBox(height: 8.h), // Row( // children: [ // CustomButton( // text: model.isSortByClinic ? (order.clinicDescription ?? "") : (order.projectName ?? ""), // onPressed: () {}, // backgroundColor: AppColors.greyColor, // borderColor: AppColors.greyColor, // textColor: AppColors.blackColor, // fontSize: 10, // fontWeight: FontWeight.w500, // borderRadius: 8, // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), // height: 24.h, // ), // ], // ), SizedBox(height: 12.h), Row( children: [ Expanded(flex: 2, child: SizedBox()), // Expanded( // flex: 1, // child: Container( // height: 40.h, // width: 40.w, // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( // color: AppColors.textColor, // borderRadius: 12, // ), // child: Padding( // padding: EdgeInsets.all(12.h), // child: Transform.flip( // flipX: _appState.isArabic(), // child: Utils.buildSvgWithAssets( // icon: AppAssets.forward_arrow_icon_small, // iconColor: AppColors.whiteColor, // fit: BoxFit.contain, // ), // ), // ), // ).onPress(() { // model.currentlySelectedPatientOrder = order; // labProvider.getPatientLabResultByHospital(order); // labProvider.getPatientSpecialResult(order); // Navigator.of(context).push( // CustomPageRoute(page: LabResultByClinic(labOrder: order)), // ); // }), // ) Expanded( flex:2, child: CustomButton( icon: AppAssets.view_report_icon, iconColor: AppColors.primaryRedColor, iconSize: 16.h, text: LocaleKeys.viewResults.tr(context: context), onPressed: () { model.currentlySelectedPatientOrder = order; labProvider.getPatientLabResultByHospital(order); labProvider.getPatientSpecialResult(order); Navigator.of(context).push( CustomPageRoute(page: LabResultByClinic(labOrder: order)), ); }, backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, fontSize: 14, fontWeight: FontWeight.w500, borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ) ], ), SizedBox(height: 12.h), Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), SizedBox(height: 12.h), ], ); }), ], ), ) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (model.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: model.indexedCharacterForUniqueTest, details: model.uniqueTestsList, labViewModel: model, rangeViewModel: rangeViewModel, appState: _appState, ) ], ) ); }, ), ); } Color getLabOrderStatusColor(num status) { switch (status) { case 44: return AppColors.warningColorYellow; case 45: return AppColors.warningColorYellow; case 16: return AppColors.successColor; case 17: return AppColors.successColor; default: return AppColors.greyColor; } } String getLabOrderStatusText(num status) { switch (status) { case 44: return LocaleKeys.resultsPending.tr(context: context); case 45: return LocaleKeys.resultsPending.tr(context: context); case 16: return LocaleKeys.resultsAvailable.tr(context: context); case 17: return LocaleKeys.resultsAvailable.tr(context: context); default: return ""; } } getLabSuggestions(LabViewModel model) { if (model.patientLabOrders.isEmpty) { return []; } return model.patientLabOrders.map((m) => m.testDetails).toList(); } } \ No newline at end of file +import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.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/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.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/features/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart'; import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_toolbar.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; import 'alphabeticScroll.dart'; class LabOrdersPage extends StatefulWidget { const LabOrdersPage({super.key}); @override State createState() => _LabOrdersPageState(); } class _LabOrdersPageState extends State { late LabViewModel labProvider; late DateRangeSelectorRangeViewModel rangeViewModel; late AppState _appState; List?> labSuggestions = []; int? expandedIndex; String? selectedFilterText = ''; int activeIndex = 0; @override void initState() { scheduleMicrotask(() { labProvider.initLabProvider(); }); super.initState(); } @override Widget build(BuildContext context) { labProvider = Provider.of(context, listen: false); rangeViewModel = Provider.of(context); _appState = getIt(); return CollapsingToolbar( title: LocaleKeys.labResults.tr(context: context), search: () async { final lavVM = Provider.of(context, listen: false); if (lavVM.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: lavVM.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; lavVM.filterLabReports(value); } } }, child: Consumer( builder: (context, model, child) { return SingleChildScrollView( physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.all(24.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: CustomTabBar( activeTextColor: Color(0xffED1C2B), activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), tabs: [ CustomTabBarModel(null, LocaleKeys.byVisit.tr(context: context)), CustomTabBarModel(null, LocaleKeys.byTest.tr(context: context)), // CustomTabBarModel(null, "Completed".needTranslation), ], onTabChange: (index) { activeIndex = index; setState(() {}); }, ), ), ], ), if (activeIndex == 0) Padding( padding: EdgeInsets.symmetric(vertical: 10.h), child: Row( children: [ CustomButton( text: LocaleKeys.byClinic.tr(context: context), onPressed: () { model.setIsSortByClinic(true); }, backgroundColor: model.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, borderColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), SizedBox(width: 8.h), CustomButton( text: LocaleKeys.byHospital.tr(context: context), onPressed: () { model.setIsSortByClinic(false); }, backgroundColor: model.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, borderColor: model.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, textColor: model.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ], ), ), SizedBox(height: 8.h), selectedFilterText!.isNotEmpty ? CustomChipWidget( chipText: selectedFilterText!, chipType: ChipTypeEnum.alert, isSelected: true, ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available model.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (model.patientLabOrdersViewList.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: model.patientLabOrdersViewList.length, itemBuilder: (context, index) { final group = model.patientLabOrdersViewList[index]; final isExpanded = expandedIndex == index; return AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 500), child: SlideAnimation( verticalOffset: 100.0, child: FadeInAnimation( child: AnimatedContainer( duration: Duration(milliseconds: 300), curve: Curves.easeInOut, margin: EdgeInsets.symmetric(vertical: 8.h), decoration: RoundedRectangleBorder() .toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true), child: InkWell( onTap: () { setState(() { expandedIndex = isExpanded ? null : index; }); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.all(16.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppCustomChipWidget(labelText: "${group.length} ${LocaleKeys.results.tr(context: context)}"), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), Text( model.isSortByClinic ? (group.first.clinicDescription ?? 'Unknown') : (group.first.projectName ?? 'Unknown'), style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), overflow: TextOverflow.ellipsis, ), ], ), ), AnimatedSwitcher( duration: Duration(milliseconds: 500), switchInCurve: Curves.easeIn, switchOutCurve: Curves.easeOut, transitionBuilder: (Widget child, Animation animation) { return FadeTransition( opacity: animation, child: SizeTransition( sizeFactor: animation, axisAlignment: 0.0, child: child, ), ); }, child: isExpanded ? Container( key: ValueKey(index), padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 0.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ...group.map((order) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Image.network( order.doctorImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", width: 24.w, height: 24.h, fit: BoxFit.cover, ).circle(100), SizedBox(width: 8.h), Expanded(child: (order.doctorName ?? order.doctorNameEnglish ?? "").toString().toText14(weight: FontWeight.w500)), ], ), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ AppCustomChipWidget( labelText: ("${LocaleKeys.orderNo.tr(context: context)}: ${order.orderNo!}"), ), AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), ), AppCustomChipWidget( labelText: model.isSortByClinic ? (order.clinicDescription ?? "") : (order.projectName ?? ""), ), ], ), // Row( // children: [ // CustomButton( // text: ("Order No: ".needTranslation + order.orderNo!), // onPressed: () {}, // backgroundColor: AppColors.greyColor, // borderColor: AppColors.greyColor, // textColor: AppColors.blackColor, // fontSize: 10, // fontWeight: FontWeight.w500, // borderRadius: 8, // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), // height: 24.h, // ), // SizedBox(width: 8.h), // CustomButton( // text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), // onPressed: () {}, // backgroundColor: AppColors.greyColor, // borderColor: AppColors.greyColor, // textColor: AppColors.blackColor, // fontSize: 10, // fontWeight: FontWeight.w500, // borderRadius: 8, // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), // height: 24.h, // ), // ], // ), // SizedBox(height: 8.h), // Row( // children: [ // CustomButton( // text: model.isSortByClinic ? (order.clinicDescription ?? "") : (order.projectName ?? ""), // onPressed: () {}, // backgroundColor: AppColors.greyColor, // borderColor: AppColors.greyColor, // textColor: AppColors.blackColor, // fontSize: 10, // fontWeight: FontWeight.w500, // borderRadius: 8, // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), // height: 24.h, // ), // ], // ), SizedBox(height: 12.h), Row( children: [ Expanded(flex: 2, child: SizedBox()), // Expanded( // flex: 1, // child: Container( // height: 40.h, // width: 40.w, // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( // color: AppColors.textColor, // borderRadius: 12, // ), // child: Padding( // padding: EdgeInsets.all(12.h), // child: Transform.flip( // flipX: _appState.isArabic(), // child: Utils.buildSvgWithAssets( // icon: AppAssets.forward_arrow_icon_small, // iconColor: AppColors.whiteColor, // fit: BoxFit.contain, // ), // ), // ), // ).onPress(() { // model.currentlySelectedPatientOrder = order; // labProvider.getPatientLabResultByHospital(order); // labProvider.getPatientSpecialResult(order); // Navigator.of(context).push( // CustomPageRoute(page: LabResultByClinic(labOrder: order)), // ); // }), // ) Expanded( flex:2, child: CustomButton( icon: AppAssets.view_report_icon, iconColor: AppColors.primaryRedColor, iconSize: 16.h, text: LocaleKeys.viewResults.tr(context: context), onPressed: () { model.currentlySelectedPatientOrder = order; labProvider.getPatientLabResultByHospital(order); labProvider.getPatientSpecialResult(order); Navigator.of(context).push( CustomPageRoute(page: LabResultByClinic(labOrder: order)), ); }, backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, fontSize: 14, fontWeight: FontWeight.w500, borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ) ], ), SizedBox(height: 12.h), Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), SizedBox(height: 12.h), ], ); }), ], ), ) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (model.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: model.indexedCharacterForUniqueTest, details: model.uniqueTestsList, labViewModel: model, rangeViewModel: rangeViewModel, appState: _appState, ) ], ) ); }, ), ); } Color getLabOrderStatusColor(num status) { switch (status) { case 44: return AppColors.warningColorYellow; case 45: return AppColors.warningColorYellow; case 16: return AppColors.successColor; case 17: return AppColors.successColor; default: return AppColors.greyColor; } } String getLabOrderStatusText(num status) { switch (status) { case 44: return LocaleKeys.resultsPending.tr(context: context); case 45: return LocaleKeys.resultsPending.tr(context: context); case 16: return LocaleKeys.resultsAvailable.tr(context: context); case 17: return LocaleKeys.resultsAvailable.tr(context: context); default: return ""; } } getLabSuggestions(LabViewModel model) { if (model.patientLabOrders.isEmpty) { return []; } return model.patientLabOrders.map((m) => m.testDetails).toList(); } } \ No newline at end of file diff --git a/lib/presentation/lab/lab_results/lab_result_details.dart b/lib/presentation/lab/lab_results/lab_result_details.dart index eb39fef..29e15ee 100644 --- a/lib/presentation/lab/lab_results/lab_result_details.dart +++ b/lib/presentation/lab/lab_results/lab_result_details.dart @@ -74,7 +74,7 @@ class LabResultDetails extends StatelessWidget { .getSeverityText( recentLabResult.calculatedResultFlag ?? "", ) - .tr() + .tr(context: context) .toText10(weight: FontWeight.w500, color: AppColors.greyTextColor), Utils.buildSvgWithAssets( icon: AppAssets.lab_result_indicator, @@ -151,8 +151,8 @@ class LabResultDetails extends StatelessWidget { children: [ Text( labmodel.isGraphVisible - ? LocaleKeys.historyFlowchart.tr() - : LocaleKeys.history.tr(), + ? LocaleKeys.historyFlowchart.tr(context: context) + : LocaleKeys.history.tr(context: context), style: TextStyle( fontSize: 16, fontFamily: 'Poppins', @@ -181,7 +181,7 @@ class LabResultDetails extends StatelessWidget { height: 24) .onPress(() { showCommonBottomSheetWithoutHeight( - title: LocaleKeys.setTheDateRange.tr(), + title: LocaleKeys.setTheDateRange.tr(context: context), context, child: DateRangeSelector( onRangeSelected: (start, end) { diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index fc49000..fa8a591 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -319,7 +319,7 @@ class _MedicalFilePageState extends State { LocaleKeys.vitalSigns.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2), Row( 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), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), ], @@ -359,7 +359,7 @@ class _MedicalFilePageState extends State { children: [ Utils.buildSvgWithAssets(icon: AppAssets.call_for_vitals, width: 32.h, height: 32.h), SizedBox(height: 12.h), - LocaleKeys.noVitalSignsRecordedYet.tr().toText12(isCenter: true), + LocaleKeys.noVitalSignsRecordedYet.tr(context: context).toText12(isCenter: true), ], ), ), @@ -577,10 +577,10 @@ class _MedicalFilePageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.appointmentsAndVisits.tr().toText16(weight: FontWeight.w500, letterSpacing: -0.2), + LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2), Row( 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), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), ], @@ -705,7 +705,7 @@ class _MedicalFilePageState extends State { ); }), 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), Row( children: [ @@ -744,7 +744,7 @@ class _MedicalFilePageState extends State { ], ).paddingSymmetrical(0.w, 0.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), Consumer(builder: (context, prescriptionVM, child) { return prescriptionVM.isPrescriptionsOrdersLoading @@ -902,7 +902,7 @@ class _MedicalFilePageState extends State { LocaleKeys.myDoctor.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2), Row( 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), Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), ], @@ -1352,7 +1352,7 @@ class _MedicalFilePageState extends State { SizedBox(height: 16.h), Row( 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), diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart index 0bf7058..8cc2103 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -114,8 +114,8 @@ class ProfileSettingsState extends State { onAddFamilyMemberPress: () { DialogService dialogService = getIt.get(); dialogService.showAddFamilyFileSheet( - label: LocaleKeys.addFamilyMember.tr(), - message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(), + label: LocaleKeys.addFamilyMember.tr(context: context), + message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(context: context), onVerificationPress: () { medicalVm.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); }); @@ -197,19 +197,18 @@ class ProfileSettingsState extends State { 1.divider, actionItem(AppAssets.bell, LocaleKeys.notificationsSettings.tr(context: context), () {}), 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) - .paddingOnly(left: 24.w, right: 24.w), + LocaleKeys.personalInformation.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w), Container( margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h, bottom: 24.h), padding: EdgeInsets.only(top: 4.h, bottom: 4.h), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), child: Column( children: [ - actionItem(AppAssets.email_transparent, LocaleKeys.updateEmailAddress.tr(), () {}), + actionItem(AppAssets.email_transparent, LocaleKeys.updateEmailAddress.tr(context: context), () {}), // 1.divider, // actionItem(AppAssets.smart_phone_fill, "Phone Number".needTranslation, () {}), // 1.divider, @@ -219,8 +218,7 @@ class ProfileSettingsState extends State { ], ), ), - LocaleKeys.helpAndSupport.tr().toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1) - .paddingOnly(left: 24.w, right: 24.w), + LocaleKeys.helpAndSupport.tr(context: context).toText18(weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1).paddingOnly(left: 24.w, right: 24.w), Container( margin: EdgeInsets.only(left: 24.w, right: 24.w, top: 16.h), padding: EdgeInsets.only(top: 4.h, bottom: 4.h), @@ -231,9 +229,9 @@ class ProfileSettingsState extends State { launchUrl(Uri.parse("tel://" + "+966 11 525 9999")); }, trailingLabel: "011 525 9999"), 1.divider, - actionItem(AppAssets.permission, LocaleKeys.permissions.tr(), () {}, trailingLabel: "Location, Camera"), + actionItem(AppAssets.permission, LocaleKeys.permissions.tr(context: context), () {}, trailingLabel: "Location, Camera"), 1.divider, - actionItem(AppAssets.rate, LocaleKeys.rateApp.tr(), () { + actionItem(AppAssets.rate, LocaleKeys.rateApp.tr(context: context), () { if (Platform.isAndroid) { Utils.openWebView( url: 'https://play.google.com/store/apps/details?id=com.ejada.hmg', @@ -245,7 +243,7 @@ class ProfileSettingsState extends State { } }, isExternalLink: true), 1.divider, - actionItem(AppAssets.privacy_terms, LocaleKeys.privacyPolicy.tr(), () { + actionItem(AppAssets.privacy_terms, LocaleKeys.privacyPolicy.tr(context: context), () { Utils.openWebView( url: 'https://hmg.com/en/Pages/Privacy.aspx', ); @@ -262,7 +260,7 @@ class ProfileSettingsState extends State { CustomButton( height: 56.h, icon: AppAssets.minus, - text: LocaleKeys.deactivateAccount.tr(), + text: LocaleKeys.deactivateAccount.tr(context: context), onPressed: () {}, ).paddingAll(24.w), ], @@ -346,7 +344,8 @@ class FamilyCardWidget extends StatelessWidget { ), ], ).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), @@ -421,7 +420,7 @@ class FamilyCardWidget extends StatelessWidget { ), ], ).paddingOnly(top: 16.h, right: 16.w, left: 16.w, bottom: 12.h), - 1.divider, + 1.divider.paddingSymmetrical(16.w, 0.h), _buildActionButton(appState), ], ), @@ -445,7 +444,7 @@ class FamilyCardWidget extends StatelessWidget { return CustomButton( 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, backgroundColor: canSwitch ? AppColors.secondaryLightRedColor : AppColors.primaryRedColor, borderColor: canSwitch ? AppColors.secondaryLightRedColor : AppColors.primaryRedColor, @@ -461,7 +460,7 @@ class FamilyCardWidget extends StatelessWidget { return CustomButton( 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, borderColor: canSwitchBack ? AppColors.primaryRedColor : Colors.grey.shade200, textColor: canSwitchBack ? AppColors.whiteColor : AppColors.greyTextColor, diff --git a/lib/services/dialog_service.dart b/lib/services/dialog_service.dart index 3092674..79cc3a9 100644 --- a/lib/services/dialog_service.dart +++ b/lib/services/dialog_service.dart @@ -212,7 +212,7 @@ Widget exceptionBottomSheetWidget( children: [ Expanded( child: CustomButton( - text: LocaleKeys.cancel.tr(), + text: LocaleKeys.cancel.tr(context: context), onPressed: () { Navigator.of(context).pop(); }, @@ -226,7 +226,7 @@ Widget exceptionBottomSheetWidget( SizedBox(width: 10.h), Expanded( child: CustomButton( - text: LocaleKeys.confirm.tr(), + text: LocaleKeys.confirm.tr(context: context), onPressed: onOkPressed, backgroundColor: AppColors.bgGreenColor, borderColor: AppColors.bgGreenColor, @@ -240,7 +240,7 @@ Widget exceptionBottomSheetWidget( Padding( padding: EdgeInsets.only(bottom: 10.h), child: CustomButton( - text: LocaleKeys.cancel.tr(), + text: LocaleKeys.cancel.tr(context: context), onPressed: (onCancelPressed == null) ? () { context.pop(); @@ -266,7 +266,7 @@ Widget showPhoneNumberPickerWidget( Padding( padding: EdgeInsets.only(bottom: 10.h), child: CustomButton( - text: LocaleKeys.sendOTPSMS.tr(), + text: LocaleKeys.sendOTPSMS.tr(context: context), onPressed: onSMSPress, backgroundColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedBorderColor, @@ -280,14 +280,14 @@ Widget showPhoneNumberPickerWidget( children: [ Padding( 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: EdgeInsets.only(bottom: 10.h, top: 10.h), child: CustomButton( - text: LocaleKeys.sendOTPWHATSAPP.tr(), + text: LocaleKeys.sendOTPWHATSAPP.tr(context: context), onPressed: onWhatsappPress, backgroundColor: Colors.white, borderColor: AppColors.borderOnlyColor, diff --git a/lib/widgets/app_language_change.dart b/lib/widgets/app_language_change.dart index 67a52db..c94195a 100644 --- a/lib/widgets/app_language_change.dart +++ b/lib/widgets/app_language_change.dart @@ -48,7 +48,7 @@ class _AppLanguageChangeState extends State { ), ), CustomButton( - text: LocaleKeys.save.tr(), + text: LocaleKeys.save.tr(context: context), onPressed: () { context.setLocale(selectedValue == 'en' ? Locale('en', 'US') : Locale('ar', 'SA')).then((val) { Navigator.pop(context); diff --git a/lib/widgets/common_bottom_sheet.dart b/lib/widgets/common_bottom_sheet.dart index 4cfde1b..1f8593a 100644 --- a/lib/widgets/common_bottom_sheet.dart +++ b/lib/widgets/common_bottom_sheet.dart @@ -42,13 +42,13 @@ class BottomSheetUtils{ Future _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 { - showCommonBottomSheetWithoutHeight(providedContext, title: LocaleKeys.setTimerOfReminder.tr(), child: PrescriptionReminderView( + showCommonBottomSheetWithoutHeight(providedContext, title: LocaleKeys.setTimerOfReminder.tr(context: providedContext), child: PrescriptionReminderView( setReminder: (int value) async { if (!isMultiAllowed!) { if (onMultiDateSuccess == null) { CalenderUtilsNew calendarUtils = CalenderUtilsNew.instance; await calendarUtils.createOrUpdateEvent( - title: title ?? LocaleKeys.youHaveAppointmentWithDr.tr() + doctorName, + title: title ?? LocaleKeys.youHaveAppointmentWithDr.tr(context: providedContext) + doctorName, description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted, scheduleDateTime: dateTime, eventId: eventId, diff --git a/lib/widgets/input_widget.dart b/lib/widgets/input_widget.dart index d97b0f0..ad2a579 100644 --- a/lib/widgets/input_widget.dart +++ b/lib/widgets/input_widget.dart @@ -153,10 +153,18 @@ class TextInputWidget extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, 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( 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( height: 40.h, width: 40.h, - margin: EdgeInsets.only(right: 10.w, left: 10.w), + // margin: EdgeInsets.symmetric(horizontal: 10.w), padding: EdgeInsets.all(8.h), decoration: RoundedRectangleBorder().toSmoothCornerDecoration( borderRadius: 12.r, From d2deb974b183b89956964a6e19601c46b214ad96 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 21 Jan 2026 10:31:36 +0300 Subject: [PATCH 08/10] symptoms merge --- lib/features/symptoms_checker/symptoms_checker_repo.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/features/symptoms_checker/symptoms_checker_repo.dart b/lib/features/symptoms_checker/symptoms_checker_repo.dart index 154b13a..c0214e1 100644 --- a/lib/features/symptoms_checker/symptoms_checker_repo.dart +++ b/lib/features/symptoms_checker/symptoms_checker_repo.dart @@ -63,7 +63,7 @@ class SymptomsCheckerRepoImp implements SymptomsCheckerRepo { required String userName, required String password, }) async { - Map body = {"userName": userName, "password": password}; + Map body = {"userName": userName, "password": password}; try { GenericApiModel? apiResponse; From 4188365e6dfb36af819d6b290248c6ae85f3e0ee Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 21 Jan 2026 10:34:24 +0300 Subject: [PATCH 09/10] readme update --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 1a459e3..3fea310 100644 --- a/README.md +++ b/README.md @@ -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 A comprehensive Flutter-based mobile application for HMG (Habib Medical Group) patients, From 14f3c6cb81fa6546e87498249e50bcfba6208bab Mon Sep 17 00:00:00 2001 From: faizatflutter Date: Wed, 21 Jan 2026 23:15:25 +0300 Subject: [PATCH 10/10] Added Arabic Support for symptoms checker --- assets/langs/ar-SA.json | 12 ++ assets/langs/en-US.json | 12 ++ convert_json.dart | 146 +++++++++--------- lib/core/api/api_client.dart | 2 +- .../data/organ_mapping_data.dart | 102 ++++++++++++ .../symptoms_checker/models/organ_model.dart | 18 +++ .../risk_and_suggestions_response_model.dart | 15 +- .../resp_models/triage_response_model.dart | 16 ++ .../symptoms_checker_view_model.dart | 45 +++++- lib/generated/locale_keys.g.dart | 11 ++ .../organ_selector_screen.dart | 77 +++++---- .../possible_conditions_screen.dart | 22 +-- .../symptoms_checker/risk_factors_screen.dart | 7 +- .../symptoms_checker/suggestions_screen.dart | 9 +- .../symptoms_selector_screen.dart | 14 +- .../symptoms_checker/triage_screen.dart | 8 +- .../symptoms_checker/user_info_selection.dart | 38 +++-- .../pages/gender_selection_page.dart | 49 +++++- .../user_info_flow_manager.dart | 29 ++-- .../widgets/condition_card.dart | 19 ++- .../widgets/interactive_body_widget.dart | 7 +- lib/widgets/buttons/custom_button.dart | 18 ++- 22 files changed, 497 insertions(+), 179 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index e0b0d8a..3ceb2e9 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1377,6 +1377,18 @@ "suggestions": "الاقتراحات", "pleaseGoBackAndSelectOrgansFirst": "يرجى العودة واختيار الأعضاء أولاً", "symptomsSelector": "محدد الأعراض", + "possibleSymptomsRelatedTo": "الأعراض المحتملة المتعلقة بـ", + "suggestionAIListDescription": "هذه قائمة بالأعراض المقترحة من قبل الذكاء الاصطناعي، بناءً على المعلومات التي تم جمعها حتى الآن خلال المقابلة", + "analyzing": "جاري التحليل...", + "seekMedicalAdvice": "اطلب المشورة الطبية", + "monitorDescription": "لا حاجة لطلب المشورة الطبية. فقط حافظ على روتين صحي.", + "seekMedicalAdviceDescription": "ليست حالة طوارئ ولكن من الأفضل مراقبة الأعراض.", + "emergencyDescription": "تحتاج إلى استشارة الطبيب في أقرب وقت ممكن قبل فوات الأوان.", + "colorScience": "دلالات الألوان", + "noNeedToVisitDoctor": "لا حاجة لزي��رة الطبيب", + "commonSymptom": "الأعراض الشائعة", + "bookAppointment": "احجز موعد", + "notApplicable": "لا ينطبق", "emergencyTriage": "طوارئ", "emergencyEvidenceDetected": "تم اكتشاف دليل طوارئ. يرجى طلب العناية الطبية.", "noQuestionItemsAvailable": "لا توجد عناصر أسئلة متاحة", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index fa59b19..50d4481 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1367,6 +1367,18 @@ "suggestions": "Suggestions", "pleaseGoBackAndSelectOrgansFirst": "Please go back and select organs first", "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", "emergencyEvidenceDetected": "Emergency evidence detected. Please seek medical attention.", "noQuestionItemsAvailable": "No question items available", diff --git a/convert_json.dart b/convert_json.dart index 08f344d..af5c594 100644 --- a/convert_json.dart +++ b/convert_json.dart @@ -1,73 +1,73 @@ -import 'dart:convert'; -import 'dart:io'; - -void main() async { - final file = File('assets/json/body_symptoms_data.json'); - final content = await file.readAsString(); - - print('File size: ${content.length} characters'); - - // Split into two parts - final parts = content.split('export const SymptomsData = ['); - if (parts.length != 2) { - print('ERROR: Could not split file properly'); - exit(1); - } - - print('Split into ${parts.length} parts'); - - // Process BodySymptomsData - var bodyPart = parts[0] - .replaceAll('export const BodySymptomsData = ', '') - .trim() - .replaceAll(RegExp(r';$'), ''); - - print('Parsing body symptoms...'); - Map bodySymptomsData; - try { - bodySymptomsData = json.decode(bodyPart); - print('✅ Body symptoms parsed: ${bodySymptomsData.length} body parts'); - } catch (e) { - print('❌ Error parsing body symptoms: $e'); - exit(1); - } - - // Process SymptomsData - print('Processing symptoms data...'); - var symptomsPart = parts[1] - .trim() - .replaceAll(RegExp(r'\];$'), '') - .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*)name:'), (m) => '\n${m.group(1)}"name":') - .replaceAllMapped(RegExp(r'\n(\s*)common_name:'), (m) => '\n${m.group(1)}"common_name":'); - - print('Parsing symptoms...'); - List symptomsData; - try { - symptomsData = json.decode('[$symptomsPart]'); - print('✅ Symptoms parsed: ${symptomsData.length} symptoms'); - } catch (e) { - print('❌ Error parsing symptoms: $e'); - print('First 1000 chars:'); - print('[$symptomsPart]'.substring(0, 1000)); - exit(1); - } - - // Create final JSON - print('Creating final JSON structure...'); - final jsonStructure = { - 'bodySymptoms': bodySymptomsData, - 'symptoms': symptomsData, - }; - - // Write to file - print('Writing to file...'); - final encoder = JsonEncoder.withIndent(' '); - await file.writeAsString(encoder.convert(jsonStructure)); - - print('\n✅ SUCCESS! File converted to proper JSON'); - print('✅ Body parts: ${bodySymptomsData.length}'); - print('✅ Symptoms: ${symptomsData.length}'); -} - +// import 'dart:convert'; +// import 'dart:io'; +// +// void main() async { +// final file = File('assets/json/body_symptoms_data.json'); +// final content = await file.readAsString(); +// +// print('File size: ${content.length} characters'); +// +// // Split into two parts +// final parts = content.split('export const SymptomsData = ['); +// if (parts.length != 2) { +// print('ERROR: Could not split file properly'); +// exit(1); +// } +// +// print('Split into ${parts.length} parts'); +// +// // Process BodySymptomsData +// var bodyPart = parts[0] +// .replaceAll('export const BodySymptomsData = ', '') +// .trim() +// .replaceAll(RegExp(r';$'), ''); +// +// print('Parsing body symptoms...'); +// Map bodySymptomsData; +// try { +// bodySymptomsData = json.decode(bodyPart); +// print('✅ Body symptoms parsed: ${bodySymptomsData.length} body parts'); +// } catch (e) { +// print('❌ Error parsing body symptoms: $e'); +// exit(1); +// } +// +// // Process SymptomsData +// print('Processing symptoms data...'); +// var symptomsPart = parts[1] +// .trim() +// .replaceAll(RegExp(r'\];$'), '') +// .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*)name:'), (m) => '\n${m.group(1)}"name":') +// .replaceAllMapped(RegExp(r'\n(\s*)common_name:'), (m) => '\n${m.group(1)}"common_name":'); +// +// print('Parsing symptoms...'); +// List symptomsData; +// try { +// symptomsData = json.decode('[$symptomsPart]'); +// print('✅ Symptoms parsed: ${symptomsData.length} symptoms'); +// } catch (e) { +// print('❌ Error parsing symptoms: $e'); +// print('First 1000 chars:'); +// print('[$symptomsPart]'.substring(0, 1000)); +// exit(1); +// } +// +// // Create final JSON +// print('Creating final JSON structure...'); +// final jsonStructure = { +// 'bodySymptoms': bodySymptomsData, +// 'symptoms': symptomsData, +// }; +// +// // Write to file +// print('Writing to file...'); +// final encoder = JsonEncoder.withIndent(' '); +// await file.writeAsString(encoder.convert(jsonStructure)); +// +// print('\n✅ SUCCESS! File converted to proper JSON'); +// print('✅ Body parts: ${bodySymptomsData.length}'); +// print('✅ Symptoms: ${symptomsData.length}'); +// } +// diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 66aa34a..39a6177 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -189,7 +189,7 @@ class ApiClientImp implements ApiClient { // body['SessionID'] = "45786230487560q"; } - body['IsNewFlutterApp'] = true; + // body['IsNewFlutterApp'] = true; body.removeWhere((key, value) => value == null); } diff --git a/lib/features/symptoms_checker/data/organ_mapping_data.dart b/lib/features/symptoms_checker/data/organ_mapping_data.dart index 6b50b25..c338a94 100644 --- a/lib/features/symptoms_checker/data/organ_mapping_data.dart +++ b/lib/features/symptoms_checker/data/organ_mapping_data.dart @@ -8,28 +8,36 @@ class OrganData { OrganModel( id: 'head', name: 'whole_head', + nameAr: 'الرأس_كامل', description: 'Head', + descriptionAr: 'الرأس', bodyView: BodyView.front, position: OrganPosition(x: 0.50, y: 0.03), ), OrganModel( id: 'left_eye', name: 'eyes', + nameAr: 'العيون', description: 'Left Eye', + descriptionAr: 'العين اليسرى', bodyView: BodyView.front, position: OrganPosition(x: 0.43, y: 0.07), ), OrganModel( id: 'right_eye', name: 'eyes', + nameAr: 'العيون', description: 'Right Eye', + descriptionAr: 'العين اليمنى', bodyView: BodyView.front, position: OrganPosition(x: 0.57, y: 0.07), ), OrganModel( id: 'nose_mouth', name: 'oral_cavity', + nameAr: 'تجويف_الفم', description: 'Nose/Mouth', + descriptionAr: 'الأنف/الفم', bodyView: BodyView.front, position: OrganPosition(x: 0.50, y: 0.09), ), @@ -38,7 +46,9 @@ class OrganData { OrganModel( id: 'throat', name: 'neck_or_throat', + nameAr: 'الرقبة_أو_الحلق', description: 'Throat', + descriptionAr: 'الحلق', bodyView: BodyView.front, position: OrganPosition(x: 0.50, y: 0.15), ), @@ -47,14 +57,18 @@ class OrganData { OrganModel( id: 'left_shoulder', name: 'upper_arm', + nameAr: 'الذراع_العلوي', description: 'Left Shoulder', + descriptionAr: 'الكتف الأيسر', bodyView: BodyView.front, position: OrganPosition(x: 0.22, y: 0.22), ), OrganModel( id: 'right_shoulder', name: 'upper_arm', + nameAr: 'الذراع_العلوي', description: 'Right Shoulder', + descriptionAr: 'الكتف الأيمن', bodyView: BodyView.front, position: OrganPosition(x: 0.8, y: 0.22), ), @@ -63,21 +77,27 @@ class OrganData { OrganModel( id: 'left_chest', name: 'chest', + nameAr: 'الصدر', description: 'Left Chest', + descriptionAr: 'الصدر الأيسر', bodyView: BodyView.front, position: OrganPosition(x: 0.38, y: 0.22), ), OrganModel( id: 'center_chest', name: 'chest', + nameAr: 'الصدر', description: 'Center Chest', + descriptionAr: 'وسط الصدر', bodyView: BodyView.front, position: OrganPosition(x: 0.52, y: 0.25), ), OrganModel( id: 'right_chest', name: 'chest', + nameAr: 'الصدر', description: 'Right Chest', + descriptionAr: 'الصدر الأيمن', bodyView: BodyView.front, position: OrganPosition(x: 0.65, y: 0.22), ), @@ -86,14 +106,18 @@ class OrganData { OrganModel( id: 'left_ribs', name: 'chest', + nameAr: 'الصدر', description: 'Left Ribs', + descriptionAr: 'الأضلاع اليسرى', bodyView: BodyView.front, position: OrganPosition(x: 0.38, y: 0.35), ), OrganModel( id: 'right_ribs', name: 'chest', + nameAr: 'الصدر', description: 'Right Ribs', + descriptionAr: 'الأضلاع اليمنى', bodyView: BodyView.front, position: OrganPosition(x: 0.64, y: 0.35), ), @@ -102,21 +126,27 @@ class OrganData { OrganModel( id: 'upper_abdomen', name: 'upper_abdomen', + nameAr: 'البطن_العلوي', description: 'Upper Abdomen', + descriptionAr: 'أعلى البطن', bodyView: BodyView.front, position: OrganPosition(x: 0.51, y: 0.31), ), OrganModel( id: 'navel', name: 'mid_abdomen', + nameAr: 'البطن_الأوسط', description: 'Navel', + descriptionAr: 'السرة', bodyView: BodyView.front, position: OrganPosition(x: 0.51, y: 0.38), ), OrganModel( id: 'lower_abdomen', name: 'lower_abdomen', + nameAr: 'البطن_السفلي', description: 'Lower Abdomen', + descriptionAr: 'أسفل البطن', bodyView: BodyView.front, position: OrganPosition(x: 0.51, y: 0.44), ), @@ -125,14 +155,18 @@ class OrganData { OrganModel( id: 'left_groin', name: 'sexual_organs', + nameAr: 'الأعضاء_التناسلية', description: 'Left Groin', + descriptionAr: 'الفخذ الأيسر', bodyView: BodyView.front, position: OrganPosition(x: 0.42, y: 0.49), ), OrganModel( id: 'right_groin', name: 'sexual_organs', + nameAr: 'الأعضاء_التناسلية', description: 'Right Groin', + descriptionAr: 'الفخذ الأيمن', bodyView: BodyView.front, position: OrganPosition(x: 0.59, y: 0.49), ), @@ -142,21 +176,27 @@ class OrganData { OrganModel( id: 'left_elbow', name: 'elbow', + nameAr: 'الكوع', description: 'Left Elbow', + descriptionAr: 'الكوع الأيسر', bodyView: BodyView.front, position: OrganPosition(x: 0.21, y: 0.35), ), OrganModel( id: 'left_forearm', name: 'forearm', + nameAr: 'الساعد', description: 'Left Forearm', + descriptionAr: 'الساعد الأيسر', bodyView: BodyView.front, position: OrganPosition(x: 0.19, y: 0.43), ), OrganModel( id: 'left_wrist', name: 'hand', + nameAr: 'اليد', description: 'Left Wrist', + descriptionAr: 'المعصم الأيسر', bodyView: BodyView.front, position: OrganPosition(x: 0.14, y: 0.5), ), @@ -166,21 +206,27 @@ class OrganData { OrganModel( id: 'right_elbow', name: 'elbow', + nameAr: 'الكوع', description: 'Right Elbow', + descriptionAr: 'الكوع الأيمن', bodyView: BodyView.front, position: OrganPosition(x: 0.79, y: 0.35), ), OrganModel( id: 'right_forearm', name: 'forearm', + nameAr: 'الساعد', description: 'Right Forearm', + descriptionAr: 'الساعد الأيمن', bodyView: BodyView.front, position: OrganPosition(x: 0.81, y: 0.43), ), OrganModel( id: 'right_wrist', name: 'hand', + nameAr: 'اليد', description: 'Right Wrist', + descriptionAr: 'المعصم الأيمن', bodyView: BodyView.front, position: OrganPosition(x: 0.85, y: 0.5), ), @@ -189,28 +235,36 @@ class OrganData { OrganModel( id: 'left_thigh', name: 'thigh', + nameAr: 'الفخذ', description: 'Left Thigh', + descriptionAr: 'الفخذ الأيسر', bodyView: BodyView.front, position: OrganPosition(x: 0.4, y: 0.60), ), OrganModel( id: 'left_knee', name: 'knee', + nameAr: 'الركبة', description: 'Left Knee', + descriptionAr: 'الركبة اليسرى', bodyView: BodyView.front, position: OrganPosition(x: 0.4, y: 0.72), ), OrganModel( id: 'left_shin', name: 'lower_leg', + nameAr: 'الساق_السفلي', description: 'Left Shin', + descriptionAr: 'الساق اليسرى', bodyView: BodyView.front, position: OrganPosition(x: 0.41, y: 0.82), ), OrganModel( id: 'left_ankle', name: 'foot', + nameAr: 'القدم', description: 'Left Ankle', + descriptionAr: 'الكاحل الأيسر', bodyView: BodyView.front, position: OrganPosition(x: 0.43, y: 0.91), ), @@ -219,28 +273,36 @@ class OrganData { OrganModel( id: 'right_thigh', name: 'thigh', + nameAr: 'الفخذ', description: 'Right Thigh', + descriptionAr: 'الفخذ الأيمن', bodyView: BodyView.front, position: OrganPosition(x: 0.65, y: 0.60), ), OrganModel( id: 'right_knee', name: 'knee', + nameAr: 'الركبة', description: 'Right Knee', + descriptionAr: 'الركبة اليمنى', bodyView: BodyView.front, position: OrganPosition(x: 0.6, y: 0.72), ), OrganModel( id: 'right_shin', name: 'lower_leg', + nameAr: 'الساق_السفلي', description: 'Right Shin', + descriptionAr: 'الساق اليمنى', bodyView: BodyView.front, position: OrganPosition(x: 0.57, y: 0.82), ), OrganModel( id: 'right_ankle', name: 'foot', + nameAr: 'القدم', description: 'Right Ankle', + descriptionAr: 'الكاحل الأيمن', bodyView: BodyView.front, position: OrganPosition(x: 0.57, y: 0.91), ), @@ -252,14 +314,18 @@ class OrganData { OrganModel( id: 'back_of_head', name: 'whole_head', + nameAr: 'الرأس_كامل', description: 'Back of Head', + descriptionAr: 'مؤخرة الرأس', bodyView: BodyView.back, position: OrganPosition(x: 0.50, y: 0.04), ), OrganModel( id: 'neck_back', name: 'nape_of_neck', + nameAr: 'مؤخرة_الرقبة', description: 'Neck', + descriptionAr: 'الرقبة', bodyView: BodyView.back, position: OrganPosition(x: 0.50, y: 0.14), ), @@ -268,14 +334,18 @@ class OrganData { OrganModel( id: 'left_shoulder_back', name: 'upper_arm', + nameAr: 'الذراع_العلوي', description: 'Left Shoulder', + descriptionAr: 'الكتف الأيسر', bodyView: BodyView.back, position: OrganPosition(x: 0.33, y: 0.19), ), OrganModel( id: 'right_shoulder_back', name: 'upper_arm', + nameAr: 'الذراع_العلوي', description: 'Right Shoulder', + descriptionAr: 'الكتف الأيمن', bodyView: BodyView.back, position: OrganPosition(x: 0.67, y: 0.19), ), @@ -284,21 +354,27 @@ class OrganData { OrganModel( id: 'upper_spine', name: 'back', + nameAr: 'الظهر', description: 'Upper Spine', + descriptionAr: 'العمود الفقري العلوي', bodyView: BodyView.back, position: OrganPosition(x: 0.50, y: 0.23), ), OrganModel( id: 'left_upper_back', name: 'back', + nameAr: 'الظهر', description: 'Left Upper Back', + descriptionAr: 'أعلى الظهر الأيسر', bodyView: BodyView.back, position: OrganPosition(x: 0.38, y: 0.28), ), OrganModel( id: 'right_upper_back', name: 'back', + nameAr: 'الظهر', description: 'Right Upper Back', + descriptionAr: 'أعلى الظهر الأيمن', bodyView: BodyView.back, position: OrganPosition(x: 0.62, y: 0.28), ), @@ -307,21 +383,27 @@ class OrganData { OrganModel( id: 'mid_spine', name: 'back', + nameAr: 'الظهر', description: 'Mid Spine', + descriptionAr: 'العمود الفقري الأوسط', bodyView: BodyView.back, position: OrganPosition(x: 0.50, y: 0.35), ), OrganModel( id: 'left_mid_back', name: 'back', + nameAr: 'الظهر', description: 'Left Mid Back', + descriptionAr: 'وسط الظهر الأيسر', bodyView: BodyView.back, position: OrganPosition(x: 0.38, y: 0.35), ), OrganModel( id: 'right_mid_back', name: 'back', + nameAr: 'الظهر', description: 'Right Mid Back', + descriptionAr: 'وسط الظهر الأيمن', bodyView: BodyView.back, position: OrganPosition(x: 0.62, y: 0.35), ), @@ -330,21 +412,27 @@ class OrganData { OrganModel( id: 'lower_spine', name: 'lower_back', + nameAr: 'أسفل_الظهر', description: 'Lower Back', + descriptionAr: 'أسفل الظهر', bodyView: BodyView.back, position: OrganPosition(x: 0.50, y: 0.43), ), OrganModel( id: 'left_lower_back', name: 'lower_back', + nameAr: 'أسفل_الظهر', description: 'Left Lower Back', + descriptionAr: 'أسفل الظهر الأيسر', bodyView: BodyView.back, position: OrganPosition(x: 0.40, y: 0.43), ), OrganModel( id: 'right_lower_back', name: 'lower_back', + nameAr: 'أسفل_الظهر', description: 'Right Lower Back', + descriptionAr: 'أسفل الظهر الأيمن', bodyView: BodyView.back, position: OrganPosition(x: 0.60, y: 0.43), ), @@ -353,21 +441,27 @@ class OrganData { OrganModel( id: 'sacrum', name: 'lower_back', + nameAr: 'أسفل_الظهر', description: 'Sacrum', + descriptionAr: 'العجز', bodyView: BodyView.back, position: OrganPosition(x: 0.50, y: 0.52), ), OrganModel( id: 'left_glute', name: 'buttocks', + nameAr: 'الأرداف', description: 'Left Glute', + descriptionAr: 'الأرداف اليسرى', bodyView: BodyView.back, position: OrganPosition(x: 0.45, y: 0.56), ), OrganModel( id: 'right_glute', name: 'buttocks', + nameAr: 'الأرداف', description: 'Right Glute', + descriptionAr: 'الأرداف اليمنى', bodyView: BodyView.back, position: OrganPosition(x: 0.55, y: 0.56), ), @@ -376,28 +470,36 @@ class OrganData { OrganModel( id: 'left_hamstring', name: 'thigh', + nameAr: 'الفخذ', description: 'Left Hamstring', + descriptionAr: 'عضلة الفخذ الخلفية اليسرى', bodyView: BodyView.back, position: OrganPosition(x: 0.43, y: 0.65), ), OrganModel( id: 'right_hamstring', name: 'thigh', + nameAr: 'الفخذ', description: 'Right Hamstring', + descriptionAr: 'عضلة الفخذ الخلفية اليمنى', bodyView: BodyView.back, position: OrganPosition(x: 0.57, y: 0.65), ), OrganModel( id: 'left_calf', name: 'lower_leg', + nameAr: 'الساق_السفلي', description: 'Left Calf', + descriptionAr: 'ربلة الساق اليسرى', bodyView: BodyView.back, position: OrganPosition(x: 0.43, y: 0.79), ), OrganModel( id: 'right_calf', name: 'lower_leg', + nameAr: 'الساق_السفلي', description: 'Right Calf', + descriptionAr: 'ربلة الساق اليمنى', bodyView: BodyView.back, position: OrganPosition(x: 0.57, y: 0.79), ), diff --git a/lib/features/symptoms_checker/models/organ_model.dart b/lib/features/symptoms_checker/models/organ_model.dart index fab7dff..9a871f3 100644 --- a/lib/features/symptoms_checker/models/organ_model.dart +++ b/lib/features/symptoms_checker/models/organ_model.dart @@ -3,29 +3,47 @@ import 'package:hmg_patient_app_new/core/enums.dart'; class OrganModel { final String id; final String name; + final String nameAr; final String description; + final String descriptionAr; final BodyView bodyView; final OrganPosition position; const OrganModel({ required this.id, required this.name, + required this.nameAr, required this.description, + required this.descriptionAr, required this.bodyView, 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({ String? id, String? name, + String? nameAr, String? description, + String? descriptionAr, BodyView? bodyView, OrganPosition? position, }) { return OrganModel( id: id ?? this.id, name: name ?? this.name, + nameAr: nameAr ?? this.nameAr, description: description ?? this.description, + descriptionAr: descriptionAr ?? this.descriptionAr, bodyView: bodyView ?? this.bodyView, position: position ?? this.position, ); diff --git a/lib/features/symptoms_checker/models/resp_models/risk_and_suggestions_response_model.dart b/lib/features/symptoms_checker/models/resp_models/risk_and_suggestions_response_model.dart index b2be4a2..9928d78 100644 --- a/lib/features/symptoms_checker/models/resp_models/risk_and_suggestions_response_model.dart +++ b/lib/features/symptoms_checker/models/resp_models/risk_and_suggestions_response_model.dart @@ -22,6 +22,8 @@ class RiskAndSuggestionsItemModel { final String? type; final String? name; final String? commonName; + final String? nameAr; + final String? commonNameAr; final String? language; RiskAndSuggestionsItemModel({ @@ -29,6 +31,8 @@ class RiskAndSuggestionsItemModel { this.type, this.name, this.commonName, + this.nameAr, + this.commonNameAr, this.language, }); @@ -38,6 +42,8 @@ class RiskAndSuggestionsItemModel { type: json['type'], name: json['name'], commonName: json['common_name'], + nameAr: json['nameAr'], + commonNameAr: json['common_nameAr'], language: json['language'], ); } @@ -48,12 +54,17 @@ class RiskAndSuggestionsItemModel { 'type': type, 'name': name, 'common_name': commonName, + 'nameAr': nameAr, + 'common_nameAr': commonNameAr, 'language': language, }; } - // Helper method to get display name - String getDisplayName() { + // Helper method to get display name based on locale + String getDisplayName({bool isArabic = false}) { + if (isArabic) { + return commonNameAr ?? nameAr ?? commonName ?? name ?? ''; + } return commonName ?? name ?? ''; } } diff --git a/lib/features/symptoms_checker/models/resp_models/triage_response_model.dart b/lib/features/symptoms_checker/models/resp_models/triage_response_model.dart index 60a3ad3..da0f4b6 100644 --- a/lib/features/symptoms_checker/models/resp_models/triage_response_model.dart +++ b/lib/features/symptoms_checker/models/resp_models/triage_response_model.dart @@ -172,6 +172,8 @@ class TriageCondition { final String? id; final String? name; final String? commonName; + final String? nameAr; + final String? commonNameAr; final double? probability; final ConditionDetails? conditionDetails; @@ -179,6 +181,8 @@ class TriageCondition { this.id, this.name, this.commonName, + this.nameAr, + this.commonNameAr, this.probability, this.conditionDetails, }); @@ -188,6 +192,8 @@ class TriageCondition { id: json['id'], name: json['name'], commonName: json['common_name'], + nameAr: json['nameAr'], + commonNameAr: json['common_nameAr'], probability: json['probability']?.toDouble(), conditionDetails: json['condition_details'] != null ? ConditionDetails.fromJson(json['condition_details']) : null, ); @@ -198,11 +204,21 @@ class TriageCondition { 'id': id, 'name': name, 'common_name': commonName, + 'nameAr': nameAr, + 'common_nameAr': commonNameAr, 'probability': probability, '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 String getProbabilityPercentage() { if (probability == null) return '0%'; diff --git a/lib/features/symptoms_checker/symptoms_checker_view_model.dart b/lib/features/symptoms_checker/symptoms_checker_view_model.dart index 929fe91..ed82451 100644 --- a/lib/features/symptoms_checker/symptoms_checker_view_model.dart +++ b/lib/features/symptoms_checker/symptoms_checker_view_model.dart @@ -23,6 +23,23 @@ class SymptomsCheckerViewModel extends ChangeNotifier { 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 bool isBodyHidden = false; BodyView _currentView = BodyView.front; @@ -440,7 +457,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { await getRiskFactors( age: _selectedAge!, - gender: _selectedGender!.toLowerCase() == "male" ? 1 : 2, + gender: _getGenderAsInt(_selectedGender), evidenceIds: evidenceIds, sessionId: currentSessionId, language: appState.isArabic() ? 'ar' : 'en', @@ -498,6 +515,8 @@ class SymptomsCheckerViewModel extends ChangeNotifier { id: "not_applicable", commonName: "Not Applicable", name: "Not Applicable", + commonNameAr: "لا ينطبق", + nameAr: "لا ينطبق", language: appState.isArabic() ? 'ar' : 'en', type: null, ); @@ -612,7 +631,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { await getSuggestions( age: _selectedAge!, - gender: _selectedGender!.toLowerCase() == "male" ? 1 : 2, + gender: _getGenderAsInt(_selectedGender), evidenceIds: evidenceIds, language: appState.isArabic() ? 'ar' : 'en', onSuccess: (response) { @@ -668,6 +687,8 @@ class SymptomsCheckerViewModel extends ChangeNotifier { id: "not_applicable", commonName: "Not Applicable", name: "Not Applicable", + commonNameAr: "لا ينطبق", + nameAr: "لا ينطبق", language: appState.isArabic() ? 'ar' : 'en', type: null, ); @@ -764,7 +785,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { await getDiagnosisForTriage( age: _selectedAge!, - gender: _selectedGender!.toLowerCase() == "male" ? 1 : 2, + gender: _getGenderAsInt(_selectedGender), evidenceIds: evidenceIds, language: appState.isArabic() ? 'ar' : 'en', onSuccess: (response) { @@ -927,6 +948,22 @@ class SymptomsCheckerViewModel extends ChangeNotifier { 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 Map getUserInfoData() { return { @@ -988,7 +1025,7 @@ class SymptomsCheckerViewModel extends ChangeNotifier { final result = await symptomsCheckerRepo.getBodySymptomsByName( organNames: organNames, userSessionToken: currentSessionAuthToken, - gender: (selectedGender ?? "Male").toLowerCase() == "male" ? 1 : 2, + gender: _getGenderAsInt(selectedGender ?? "Male"), ); result.fold( diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index d6f2d23..41cb64f 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1371,6 +1371,17 @@ abstract class LocaleKeys { static const suggestions = 'suggestions'; static const pleaseGoBackAndSelectOrgansFirst = 'pleaseGoBackAndSelectOrgansFirst'; 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 emergencyEvidenceDetected = 'emergencyEvidenceDetected'; static const noQuestionItemsAvailable = 'noQuestionItemsAvailable'; diff --git a/lib/presentation/symptoms_checker/organ_selector_screen.dart b/lib/presentation/symptoms_checker/organ_selector_screen.dart index cc956dc..e3944c2 100644 --- a/lib/presentation/symptoms_checker/organ_selector_screen.dart +++ b/lib/presentation/symptoms_checker/organ_selector_screen.dart @@ -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/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/route_extensions.dart'; -import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.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'; @@ -44,7 +43,9 @@ class _OrganSelectorPageState extends State { ); return; } - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.pleaseWait.tr(context: context),); + LoaderBottomSheet.showLoader( + loadingText: LocaleKeys.pleaseWait.tr(context: context), + ); final String userName = 'guest_user'; final String password = '123456'; @@ -102,7 +103,7 @@ class _OrganSelectorPageState extends State { width: 32.h, height: 32.h, ), - padding: const EdgeInsets.only(left: 12), + padding: EdgeInsetsDirectional.only(start: 12), onPressed: () => Navigator.pop(context), highlightColor: Colors.transparent, ), @@ -125,21 +126,32 @@ class _OrganSelectorPageState extends State { } Widget _buildBodyViewer(SymptomsCheckerViewModel viewModel) { - return Padding( - padding: EdgeInsets.fromLTRB(16.h, 16.h, 16.h, 60.h), - child: AnimatedSwitcher( - duration: const Duration(milliseconds: 600), - transitionBuilder: (child, animation) => _build3DFlipTransition(child, animation), - switchInCurve: Curves.easeInOut, - switchOutCurve: Curves.easeInOut, - child: InteractiveBodyWidget( - key: ValueKey(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, + return GestureDetector( + onHorizontalDragEnd: (details) { + // Swipe left or right to toggle view + if (details.primaryVelocity != null) { + if (details.primaryVelocity! < -200 || details.primaryVelocity! > 200) { + viewModel.toggleView(); + } + } + }, + child: Padding( + padding: EdgeInsets.fromLTRB(16.h, 16.h, 16.h, 60.h), + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 600), + transitionBuilder: (child, animation) => _build3DFlipTransition(child, animation), + switchInCurve: Curves.easeInOut, + switchOutCurve: Curves.easeInOut, + child: InteractiveBodyWidget( + key: ValueKey(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 { } Widget _buildViewToggleButtons(SymptomsCheckerViewModel viewModel) { - return Positioned( - left: 16.w, + return PositionedDirectional( + start: 16.w, top: 36.h, child: Column( children: [ @@ -275,6 +287,8 @@ class _OrganSelectorPageState extends State { ); } + final isArabic = _appState.isArabic(); + return ConstrainedBox( constraints: BoxConstraints(maxHeight: 150.h), child: SingleChildScrollView( @@ -284,7 +298,7 @@ class _OrganSelectorPageState extends State { runSpacing: 8.h, children: viewModel.selectedOrgans.map((organ) { return AppCustomChipWidget( - labelText: organ.description, + labelText: organ.getLocalizedDescription(isArabic), backgroundColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, deleteIcon: AppAssets.cancel, @@ -313,8 +327,8 @@ class _OrganSelectorPageState extends State { } Widget _buildExpandCollapseButton(SymptomsCheckerViewModel viewModel) { - return Positioned( - right: 24.w, + return PositionedDirectional( + end: 24.w, top: -24.h, child: GestureDetector( onTap: viewModel.toggleBottomSheet, @@ -331,13 +345,16 @@ class _OrganSelectorPageState extends State { borderRadius: 11.r, ), child: Center( - child: AnimatedRotation( - duration: const Duration(milliseconds: 300), - turns: viewModel.isBottomSheetExpanded ? 0.25 : -0.25, - child: Utils.buildSvgWithAssets( - icon: AppAssets.arrowRight, - width: 25.w, - height: 25.h, + child: Transform.flip( + flipX: _appState.isArabic(), + child: AnimatedRotation( + duration: const Duration(milliseconds: 300), + turns: viewModel.isBottomSheetExpanded ? 0.25 : -0.25, + child: Utils.buildSvgWithAssets( + icon: AppAssets.arrowRight, + width: 25.w, + height: 25.h, + ), ), ), ), diff --git a/lib/presentation/symptoms_checker/possible_conditions_screen.dart b/lib/presentation/symptoms_checker/possible_conditions_screen.dart index 858218d..8fb0e0f 100644 --- a/lib/presentation/symptoms_checker/possible_conditions_screen.dart +++ b/lib/presentation/symptoms_checker/possible_conditions_screen.dart @@ -108,25 +108,25 @@ class PossibleConditionsPage extends StatelessWidget { ); } - Widget _buildInfoTile({required PossibleConditionsSeverityEnum severityEnum}) { + Widget _buildInfoTile({required PossibleConditionsSeverityEnum severityEnum, required BuildContext context}) { String title; String description; Color dotColor; switch (severityEnum) { case PossibleConditionsSeverityEnum.monitorOnly: - title = "Monitor".needTranslation; - description = "No need to seek medical advice. Just keep healthy routine.".needTranslation; + title = LocaleKeys.monitor.tr(context: context); + description = LocaleKeys.monitorDescription.tr(context: context); dotColor = AppColors.chipColorMonitor; break; case PossibleConditionsSeverityEnum.seekMedicalAdvice: - title = "Seek Medical Advice".needTranslation; - description = "Not emergency but better to monitor the symptoms.".needTranslation; + title = LocaleKeys.seekMedicalAdvice.tr(context: context); + description = LocaleKeys.seekMedicalAdviceDescription.tr(context: context); dotColor = AppColors.chipColorSeekMedicalAdvice; break; case PossibleConditionsSeverityEnum.emergency: - title = "Emergency".needTranslation; - description = "Need to consult doctor as soon as possible before getting too late.".needTranslation; + title = LocaleKeys.emergency.tr(context: context); + description = LocaleKeys.emergencyDescription.tr(context: context); dotColor = AppColors.chipColorEmergency; break; } @@ -156,7 +156,7 @@ class PossibleConditionsPage extends StatelessWidget { _buildSeverityDetailsBottomsheet({required BuildContext context}) { return showCommonBottomSheetWithoutHeight( - title: "Color Science".needTranslation, + title: LocaleKeys.colorScience.tr(context: context), context, child: Container( padding: EdgeInsets.all(16.w), @@ -164,11 +164,11 @@ class PossibleConditionsPage extends StatelessWidget { decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), child: Column( children: [ - _buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.monitorOnly), + _buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.monitorOnly, context: context), 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), - _buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.emergency), + _buildInfoTile(severityEnum: PossibleConditionsSeverityEnum.emergency, context: context), ], ), ), diff --git a/lib/presentation/symptoms_checker/risk_factors_screen.dart b/lib/presentation/symptoms_checker/risk_factors_screen.dart index da41d78..8264b8b 100644 --- a/lib/presentation/symptoms_checker/risk_factors_screen.dart +++ b/lib/presentation/symptoms_checker/risk_factors_screen.dart @@ -3,6 +3,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.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_state.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/extensions/route_extensions.dart'; @@ -25,11 +26,13 @@ class RiskFactorsScreen extends StatefulWidget { class _RiskFactorsScreenState extends State { late DialogService dialogService; + late AppState _appState; @override void initState() { super.initState(); dialogService = getIt(); + _appState = getIt(); // Fetch risk factors based on selected symptoms WidgetsBinding.instance.addPostFrameCallback((_) { final viewModel = context.read(); @@ -90,6 +93,8 @@ class _RiskFactorsScreenState extends State { } Widget _buildRiskFactorsList(SymptomsCheckerViewModel viewModel) { + final isArabic = _appState.isArabic(); + return Container( key: ValueKey(viewModel.riskFactorsList.length), width: double.infinity, @@ -100,7 +105,7 @@ class _RiskFactorsScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ ...viewModel.riskFactorsList.map((factor) { - return _buildRiskFactorItem(viewModel, factor.id ?? '', factor.getDisplayName()); + return _buildRiskFactorItem(viewModel, factor.id ?? '', factor.getDisplayName(isArabic: isArabic)); }), SizedBox(height: 12.w), Row( diff --git a/lib/presentation/symptoms_checker/suggestions_screen.dart b/lib/presentation/symptoms_checker/suggestions_screen.dart index f09ebd5..8d32b7f 100644 --- a/lib/presentation/symptoms_checker/suggestions_screen.dart +++ b/lib/presentation/symptoms_checker/suggestions_screen.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.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_state.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/extensions/route_extensions.dart'; @@ -24,11 +25,13 @@ class SuggestionsScreen extends StatefulWidget { class _SuggestionsScreenState extends State { late DialogService dialogService; + late AppState _appState; @override void initState() { super.initState(); dialogService = getIt(); + _appState = getIt(); // Initialize symptom groups based on selected organs WidgetsBinding.instance.addPostFrameCallback((_) { final viewModel = context.read(); @@ -92,6 +95,8 @@ class _SuggestionsScreenState extends State { } Widget _buildSuggestionsList(SymptomsCheckerViewModel viewModel) { + final isArabic = _appState.isArabic(); + return Container( key: ValueKey(viewModel.suggestionsList.length), width: double.infinity, @@ -102,7 +107,7 @@ class _SuggestionsScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ ...viewModel.suggestionsList.map((factor) { - return _buildSuggestionItem(viewModel, factor.id ?? '', factor.getDisplayName()); + return _buildSuggestionItem(viewModel, factor.id ?? '', factor.getDisplayName(isArabic: isArabic)); }), SizedBox(height: 12.w), Row( @@ -115,7 +120,7 @@ class _SuggestionsScreenState extends State { ), SizedBox(width: 12.w), 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, ), ) diff --git a/lib/presentation/symptoms_checker/symptoms_selector_screen.dart b/lib/presentation/symptoms_checker/symptoms_selector_screen.dart index b241b44..2bfcb62 100644 --- a/lib/presentation/symptoms_checker/symptoms_selector_screen.dart +++ b/lib/presentation/symptoms_checker/symptoms_selector_screen.dart @@ -1,6 +1,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; +import 'package:hmg_patient_app_new/core/app_state.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/extensions/route_extensions.dart'; @@ -26,11 +27,13 @@ class SymptomsSelectorPage extends StatefulWidget { class _SymptomsSelectorPageState extends State { late DialogService dialogService; + late AppState _appState; @override void initState() { super.initState(); dialogService = getIt(); + _appState = getIt(); // Initialize symptom groups based on selected organs WidgetsBinding.instance.addPostFrameCallback((_) { final viewModel = context.read(); @@ -100,10 +103,11 @@ class _SymptomsSelectorPageState extends State { // Find matching organ ID from selected organs String? organId; String? organName; + final isArabic = _appState.isArabic(); for (var organ in viewModel.selectedOrgans) { if (organ.name == organResult.name) { organId = organ.id; - organName = organ.description; + organName = organ.getLocalizedDescription(isArabic); break; } } @@ -141,6 +145,8 @@ class _SymptomsSelectorPageState extends State { String organName, List symptoms, ) { + final isArabic = _appState.isArabic(); + return Container( width: double.infinity, margin: EdgeInsets.symmetric(horizontal: 24.w), @@ -154,7 +160,7 @@ class _SymptomsSelectorPageState extends State { children: [ Expanded( child: Text( - 'Possible symptoms related to "$organName"', + '${LocaleKeys.possibleSymptomsRelatedTo.tr(context: context)} "$organName"', style: TextStyle(fontSize: 18.f, fontWeight: FontWeight.w600, color: AppColors.textColor), ), ), @@ -166,7 +172,7 @@ class _SymptomsSelectorPageState extends State { spacing: 8.w, children: symptoms.map((symptom) { 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); return GestureDetector( onTap: () => viewModel.toggleSymptomSelection(organId, symptomId), @@ -306,7 +312,7 @@ class _SymptomsSelectorPageState extends State { fontSize: 16.f, ), ), - ], + ], ), SizedBox(height: 24.h), ], diff --git a/lib/presentation/symptoms_checker/triage_screen.dart b/lib/presentation/symptoms_checker/triage_screen.dart index c0d48d6..a7975e2 100644 --- a/lib/presentation/symptoms_checker/triage_screen.dart +++ b/lib/presentation/symptoms_checker/triage_screen.dart @@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.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_state.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/extensions/route_extensions.dart'; @@ -32,12 +33,14 @@ class TriagePage extends StatefulWidget { class _TriagePageState extends State { late SymptomsCheckerViewModel viewModel; late DialogService dialogService; + late AppState _appState; @override void initState() { super.initState(); viewModel = context.read(); dialogService = getIt.get(); + _appState = getIt.get(); // Start triage process when screen loads WidgetsBinding.instance.addPostFrameCallback((_) { @@ -436,7 +439,8 @@ class _TriagePageState extends State { Widget _buildStickyBottomCard(BuildContext context, SymptomsCheckerViewModel viewModel) { // Get the top condition with highest probability final conditions = viewModel.currentConditions ?? []; - String suggestedCondition = "Analyzing..."; + final isArabic = _appState.isArabic(); + String suggestedCondition = LocaleKeys.analyzing.tr(context: context); double probability = 0.0; if (conditions.isNotEmpty) { @@ -445,7 +449,7 @@ class _TriagePageState extends State { sortedConditions.sort((a, b) => (b.probability ?? 0.0).compareTo(a.probability ?? 0.0)); final topCondition = sortedConditions.first; - suggestedCondition = topCondition.commonName ?? topCondition.name ?? "Unknown"; + suggestedCondition = topCondition.getDisplayName(isArabic: isArabic); probability = (topCondition.probability ?? 0.0) * 100; // Convert to percentage } // final bool isHighConfidence = probability >= 70.0; diff --git a/lib/presentation/symptoms_checker/user_info_selection.dart b/lib/presentation/symptoms_checker/user_info_selection.dart index 78eb916..1d05c5a 100644 --- a/lib/presentation/symptoms_checker/user_info_selection.dart +++ b/lib/presentation/symptoms_checker/user_info_selection.dart @@ -43,13 +43,10 @@ class _UserInfoSelectionPageState extends State { if (user == null) return; // Populate gender (gender is int: 1=Male, 2=Female) + // Use internal keys (male/female) for storage if (user.gender != null) { - String genderStr = user.gender == 1 - ? "Male" - : user.gender == 2 - ? "Female" - : "Other"; - viewModel.setGender(genderStr); + String genderKey = user.gender == 1 ? "male" : user.gender == 2 ? "female" : "other"; + viewModel.setGender(genderKey); } if (user.dateofBirth != null && user.dateofBirth!.isNotEmpty) { @@ -84,12 +81,13 @@ class _UserInfoSelectionPageState extends State { child: Row( children: [ Container( - height: 40.h, - width: 40.h, - margin: EdgeInsets.only(right: 10.h), - padding: EdgeInsets.all(8.h), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 12.r, color: AppColors.greyColor), - child: Utils.buildSvgWithAssets(icon: leadingIcon, iconColor: iconColor)), + height: 40.h, + width: 40.h, + margin: EdgeInsetsDirectional.only(end: 10.h), + padding: EdgeInsets.all(8.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(borderRadius: 12.r, color: AppColors.greyColor), + child: Utils.buildSvgWithAssets(icon: leadingIcon, iconColor: iconColor), + ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -112,6 +110,20 @@ class _UserInfoSelectionPageState extends State { ).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 Widget build(BuildContext context) { AppState appState = getIt.get(); @@ -151,7 +163,7 @@ class _UserInfoSelectionPageState extends State { viewModel.selectedWeight == null; // 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) int? displayAge = viewModel.selectedAge ?? userAgeFromDOB; String ageText = displayAge != null ? "$displayAge ${LocaleKeys.years.tr(context: context)}" : LocaleKeys.notSet.tr(context: context); diff --git a/lib/presentation/symptoms_checker/user_info_selection/pages/gender_selection_page.dart b/lib/presentation/symptoms_checker/user_info_selection/pages/gender_selection_page.dart index 6eaae8c..07f44f1 100644 --- a/lib/presentation/symptoms_checker/user_info_selection/pages/gender_selection_page.dart +++ b/lib/presentation/symptoms_checker/user_info_selection/pages/gender_selection_page.dart @@ -15,12 +15,16 @@ class GenderSelectionPage extends StatelessWidget { final String? selectedGender; final Function(String) onGenderSelected; - GenderSelectionPage({ + const GenderSelectionPage({ super.key, required this.selectedGender, 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) { return Container( 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 Widget build(BuildContext context) { @@ -56,16 +80,25 @@ class GenderSelectionPage extends StatelessWidget { children: [ Expanded( child: InkWell( - onTap: () => onGenderSelected(genders[0]), - child: _buildGenderOption(AppAssets.maleIcon, LocaleKeys.malE.tr(context: context), symptomsViewModel.selectedGender == genders[0]), + onTap: () => onGenderSelected(maleKey), + child: _buildGenderOption( + AppAssets.maleIcon, + LocaleKeys.malE.tr(context: context), + _isGenderSelected(maleKey, symptomsViewModel.selectedGender, context), + ), ), ), SizedBox(width: 16.w), Expanded( - child: InkWell( - onTap: () => onGenderSelected(genders[1]), - child: _buildGenderOption(AppAssets.femaleIcon, LocaleKeys.femaleGender.tr(context: context), symptomsViewModel.selectedGender == genders[1]), - )) + child: InkWell( + onTap: () => onGenderSelected(femaleKey), + child: _buildGenderOption( + AppAssets.femaleIcon, + LocaleKeys.femaleGender.tr(context: context), + _isGenderSelected(femaleKey, symptomsViewModel.selectedGender, context), + ), + ), + ) ], ), ], diff --git a/lib/presentation/symptoms_checker/user_info_selection/user_info_flow_manager.dart b/lib/presentation/symptoms_checker/user_info_selection/user_info_flow_manager.dart index b5df05b..fdfe228 100644 --- a/lib/presentation/symptoms_checker/user_info_selection/user_info_flow_manager.dart +++ b/lib/presentation/symptoms_checker/user_info_selection/user_info_flow_manager.dart @@ -4,7 +4,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/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/generated/locale_keys.g.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 { late PageController _pageController; late SymptomsCheckerViewModel _viewModel; - // Page titles - final List _pageTitles = [ - "Your Gender", - "Your Birth Date", - "Your Height", - "Your Weight", - ]; + // Get localized page titles + List _getPageTitles(BuildContext context) { + return [ + LocaleKeys.genderSymptoms.tr(context: context), + LocaleKeys.dateOfBirthSymptoms.tr(context: context), + LocaleKeys.heightSymptoms.tr(context: context), + LocaleKeys.weightSymptoms.tr(context: context), + ]; + } @override void initState() { @@ -187,9 +188,11 @@ class _UserInfoFlowManagerState extends State { ? // Single page edit mode - show only Save button CustomButton( text: LocaleKeys.save.tr(context: context), - onPressed: _onNext, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedColor, + isDisabled: !(viewModel.isCurrentUserInfoPageValid), + onPressed: () => viewModel.isCurrentUserInfoPageValid ? _onNext() : () {}, + 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, fontSize: 16.f, ) @@ -228,6 +231,8 @@ class _UserInfoFlowManagerState extends State { @override Widget build(BuildContext context) { + final pageTitles = _getPageTitles(context); + return Scaffold( backgroundColor: AppColors.bgScaffoldColor, body: Column( @@ -235,7 +240,7 @@ class _UserInfoFlowManagerState extends State { Expanded( child: CollapsingListView( physics: NeverScrollableScrollPhysics(), - title: _pageTitles[_viewModel.userInfoCurrentPage], + title: pageTitles[_viewModel.userInfoCurrentPage], isLeading: true, child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/presentation/symptoms_checker/widgets/condition_card.dart b/lib/presentation/symptoms_checker/widgets/condition_card.dart index b95e55c..e48f41e 100644 --- a/lib/presentation/symptoms_checker/widgets/condition_card.dart +++ b/lib/presentation/symptoms_checker/widgets/condition_card.dart @@ -2,6 +2,8 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.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_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/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; @@ -24,8 +26,11 @@ class ConditionCard extends StatelessWidget { this.onActionPressed, }); - /// Get title from condition - String get title => condition.commonName ?? condition.name ?? ''; + /// Get title from condition (localized) + String get title { + final appState = getIt(); + return condition.getDisplayName(isArabic: appState.isArabic()); + } /// Get percentage from probability (0-1 to 0-100) int get percentage => ((condition.probability ?? 0) * 100).toInt(); @@ -69,14 +74,14 @@ class ConditionCard extends StatelessWidget { return LocaleKeys.emergency.tr(context: context); case TriageLevelEnum.consultation24: case TriageLevelEnum.consultation: - return "Seek Medical Advice".needTranslation; + return LocaleKeys.seekMedicalAdvice.tr(context: context); case TriageLevelEnum.selfCare: return LocaleKeys.monitor.tr(context: context); } } // Default based on probability if (percentage >= 70) { - return "Seek Medical Advice".needTranslation; + return LocaleKeys.seekMedicalAdvice.tr(context: context); } else { return LocaleKeys.monitor.tr(context: context); } @@ -85,7 +90,7 @@ class ConditionCard extends StatelessWidget { /// Get monitor note if applicable String? getMonitorNote(BuildContext context) { if (severityEnum == PossibleConditionsSeverityEnum.monitorOnly) { - return "No need to visit doctor".needTranslation; + return LocaleKeys.noNeedToVisitDoctor.tr(context: context); } return null; } @@ -236,7 +241,7 @@ class ConditionCard extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Common Symptom".needTranslation.toText14(weight: FontWeight.w600, color: AppColors.textColor), + LocaleKeys.commonSymptom.tr(context: context).toText14(weight: FontWeight.w600, color: AppColors.textColor), _buildSymptomsRow(), SizedBox(height: 16.h), 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), if (severityEnum != PossibleConditionsSeverityEnum.monitorOnly) CustomButton( - text: "Book Appointment".needTranslation, + text: LocaleKeys.bookAppointment.tr(context: context), onPressed: () { if (onActionPressed != null) { onActionPressed!(); diff --git a/lib/presentation/symptoms_checker/widgets/interactive_body_widget.dart b/lib/presentation/symptoms_checker/widgets/interactive_body_widget.dart index 8957fb1..62c38f9 100644 --- a/lib/presentation/symptoms_checker/widgets/interactive_body_widget.dart +++ b/lib/presentation/symptoms_checker/widgets/interactive_body_widget.dart @@ -13,6 +13,7 @@ class InteractiveBodyWidget extends StatefulWidget { final bool isBodyHidden; final Function(String organId) onOrganTap; final String? tooltipOrganId; + final bool isArabic; const InteractiveBodyWidget({ super.key, @@ -22,6 +23,7 @@ class InteractiveBodyWidget extends StatefulWidget { required this.onOrganTap, this.isBodyHidden = false, this.tooltipOrganId, + this.isArabic = false, }); @override @@ -118,7 +120,10 @@ class _InteractiveBodyWidgetState extends State { (organ) { final centerX = organ.position.x * imageConstraints.maxWidth; 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), + ); }, ), ], diff --git a/lib/widgets/buttons/custom_button.dart b/lib/widgets/buttons/custom_button.dart index 7fa5c3f..a81f0eb 100644 --- a/lib/widgets/buttons/custom_button.dart +++ b/lib/widgets/buttons/custom_button.dart @@ -74,15 +74,18 @@ class CustomButton extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ if (icon != null) - Padding( - 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), + Flexible( + child: Padding( + 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( - visible: text.isNotEmpty, - child: Text( + if (text.isNotEmpty) + Text( text, - overflow: textOverflow, + overflow: textOverflow ?? TextOverflow.ellipsis, + maxLines: 1, + textAlign: TextAlign.center, style: context.dynamicTextStyle( fontSize: fontS, color: isDisabled ? AppColors.greyTextColor : textColor, @@ -90,7 +93,6 @@ class CustomButton extends StatelessWidget { fontWeight: fontWeight, ), ), - ), ], ), ));