From 2c0d010bac14eadd9b85a349fba7e52f57c2d8c3 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 12 Mar 2026 15:30:36 +0300 Subject: [PATCH 01/17] updates --- assets/images/svg/biometric_lock_icon.svg | 3 +++ lib/core/api/api_client.dart | 5 +++++ lib/core/app_assets.dart | 1 + lib/presentation/authentication/quick_login.dart | 3 ++- 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 assets/images/svg/biometric_lock_icon.svg diff --git a/assets/images/svg/biometric_lock_icon.svg b/assets/images/svg/biometric_lock_icon.svg new file mode 100644 index 00000000..dd123157 --- /dev/null +++ b/assets/images/svg/biometric_lock_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 921e274b..4c252e8f 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -194,6 +194,11 @@ class ApiClientImp implements ApiClient { body['TokenID'] = "@dm!n"; } + if (url == 'https://uat.hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo') { + url = "https://hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo"; + body['TokenID'] = "@dm!n"; + } + // body['TokenID'] = "@dm!n"; // body['PatientID'] = 809289; // body['PatientTypeID'] = 1; diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index efe62775..4f7a0863 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -332,6 +332,7 @@ class AppAssets { static const String changeLanguageHomePageIcon = '$svgBasePath/change_language_home_page.svg'; static const String aiOverView = '$svgBasePath/ai_overview.svg'; static const String darkModeIcon = '$svgBasePath/dark_mode_icon.svg'; + static const String biometricLockIcon = '$svgBasePath/biometric_lock_icon.svg'; // PNGS // static const String hmgLogo = '$pngBasePath/hmg_logo.png'; diff --git a/lib/presentation/authentication/quick_login.dart b/lib/presentation/authentication/quick_login.dart index fbcb17d8..19e90d64 100644 --- a/lib/presentation/authentication/quick_login.dart +++ b/lib/presentation/authentication/quick_login.dart @@ -65,7 +65,8 @@ class QuickLoginState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Image.asset(AppAssets.lockIcon, height: 100), + // Image.asset(AppAssets.lockIcon, height: 100), + Utils.buildSvgWithAssets(icon: AppAssets.biometricLockIcon, iconColor: AppColors.textColor, width: 100.h, height: 100.h), SizedBox(height: 10.h), LocaleKeys.enableQuickLogin.tr(context: context).toText26(isBold: true), // Text( From 1a68ffd500d0f743bc3814323f76598e868642ac Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 12 Mar 2026 17:54:02 +0300 Subject: [PATCH 02/17] Updates --- assets/images/svg/globe_other.svg | 4 ++++ assets/langs/ar-SA.json | 3 ++- assets/langs/en-US.json | 3 ++- lib/core/api_consts.dart | 2 +- lib/core/app_assets.dart | 2 ++ lib/generated/locale_keys.g.dart | 1 + lib/presentation/authentication/saved_login_screen.dart | 3 ++- lib/presentation/lab/lab_results/lab_result_details.dart | 2 +- pubspec.yaml | 3 ++- 9 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 assets/images/svg/globe_other.svg diff --git a/assets/images/svg/globe_other.svg b/assets/images/svg/globe_other.svg new file mode 100644 index 00000000..1b9734b3 --- /dev/null +++ b/assets/images/svg/globe_other.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index f929b1ae..76736da7 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1583,5 +1583,6 @@ "continueCash": "متابعة الدفع نقدًا", "timeFor": "الوقت", "hmgPolicies": "سياسات مجموعة الحبيب الطبية", - "darkMode": "المظهر الداكن" + "darkMode": "المظهر الداكن", + "generateAiAnalysisResult": "قم بإجراء تحليل لهذا المختبر AI" } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index b1cc5b08..b7c8def0 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1576,5 +1576,6 @@ "continueCash": "Continue as cash", "timeFor": "Time For", "hmgPolicies": "HMG Policies", - "darkMode": "Dark Mode" + "darkMode": "Dark Mode", + "generateAiAnalysisResult": "Generate AI analysis for this result" } diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index a529c740..99f62aad 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -233,7 +233,7 @@ class ApiConsts { static String getAiOverViewLabOrder = "Services/Patients.svc/REST/HMGAI_Lab_Analyzer_API"; // ************ static values for Api **************** - static final double appVersionID = 20.2; + static final double appVersionID = 20.3; // static final double appVersionID = 50.7; static final int appChannelId = 3; static final String appIpAddress = "10.20.10.20"; diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index 7e5e9e9b..9d5f28c8 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -17,6 +17,8 @@ class AppAssets { static const String email = '$svgBasePath/email.svg'; static const String globe = '$svgBasePath/globe.svg'; static const String globeOther = '$svgBasePath/globe_other.svg'; + + // static const String globeOther = '$svgBasePath/globe_other.svg'; static const String cancel = '$svgBasePath/cancel.svg'; static const String bell = '$svgBasePath/bell.svg'; static const String login1 = '$svgBasePath/login1.svg'; diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 1a33df93..2ba5dbc4 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1577,5 +1577,6 @@ abstract class LocaleKeys { static const timeFor = 'timeFor'; static const hmgPolicies = 'hmgPolicies'; static const darkMode = 'darkMode'; + static const generateAiAnalysisResult = 'generateAiAnalysisResult'; } diff --git a/lib/presentation/authentication/saved_login_screen.dart b/lib/presentation/authentication/saved_login_screen.dart index e9f201ad..96db5187 100644 --- a/lib/presentation/authentication/saved_login_screen.dart +++ b/lib/presentation/authentication/saved_login_screen.dart @@ -206,7 +206,7 @@ class _SavedLogin extends State { }, backgroundColor: AppColors.primaryRedColor, borderColor: AppColors.primaryRedColor, - textColor: AppColors.whiteColor, + textColor: AppColors.textColor, icon: AppAssets.sms), ), Row( @@ -232,6 +232,7 @@ class _SavedLogin extends State { textColor: AppColors.textColor, icon: AppAssets.whatsapp, iconColor: null, + applyThemeColor: false, ), ), ], diff --git a/lib/presentation/lab/lab_results/lab_result_details.dart b/lib/presentation/lab/lab_results/lab_result_details.dart index d2c1b524..8d5d0042 100644 --- a/lib/presentation/lab/lab_results/lab_result_details.dart +++ b/lib/presentation/lab/lab_results/lab_result_details.dart @@ -104,7 +104,7 @@ class LabResultDetails extends StatelessWidget { padding: EdgeInsets.only(right: 4.w, left: 4.w), child: Utils.buildSvgWithAssets(icon: AppAssets.aiOverView, width: 16.h, height: 16.h, iconColor: Colors.white), ), - LocaleKeys.generateAiAnalysis.tr(context: context).toText16(isBold: true) + LocaleKeys.generateAiAnalysisResult.tr(context: context).toText16(isBold: true) ], ), ).paddingSymmetrical(24.h, 24.h).onPress(() async { diff --git a/pubspec.yaml b/pubspec.yaml index 43969000..27a81c7e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,8 @@ name: hmg_patient_app_new description: "New HMG Patient App" publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 0.0.11+8 +#version: 0.0.11+8 +version: 0.0.1+9 environment: sdk: ">=3.6.0 <4.0.0" From d194b5a45bbe8d032aad13f722c3c97764b7bb3f Mon Sep 17 00:00:00 2001 From: Haroon Amjad <> Date: Thu, 12 Mar 2026 22:15:35 +0300 Subject: [PATCH 03/17] updates --- lib/core/api/api_client.dart | 4 +- .../habib_wallet/habib_wallet_repo.dart | 11 ++-- .../habib_wallet/habib_wallet_view_model.dart | 10 +++- ...atient_advance_balance_response_model.dart | 27 ++++++++++ .../habib_wallet/habib_wallet_page.dart | 54 ++++++++++++++++--- 5 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 lib/features/habib_wallet/models/patient_advance_balance_response_model.dart diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 116e0733..f1a0ed0c 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -199,8 +199,8 @@ class ApiClientImp implements ApiClient { body['TokenID'] = "@dm!n"; } - // body['TokenID'] = "@dm!n"; - // body['PatientID'] = 809289; + body['TokenID'] = "@dm!n"; + body['PatientID'] = 2007395; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; // body['SessionID'] = "45786230487560q"; diff --git a/lib/features/habib_wallet/habib_wallet_repo.dart b/lib/features/habib_wallet/habib_wallet_repo.dart index 659510de..c89a85be 100644 --- a/lib/features/habib_wallet/habib_wallet_repo.dart +++ b/lib/features/habib_wallet/habib_wallet_repo.dart @@ -3,6 +3,7 @@ import 'package:hmg_patient_app_new/core/api/api_client.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; +import 'package:hmg_patient_app_new/features/habib_wallet/models/patient_advance_balance_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; @@ -40,18 +41,22 @@ class HabibWalletRepoImp implements HabibWalletRepo { }, onSuccess: (response, statusCode, {messageStatus, errorMessage}) { try { - // final list = response['ListPLO']; + final list = response['List_PatientAdvanceBalanceAmount']; // if (list == null || list.isEmpty) { // throw Exception("lab list is empty"); // } - // final labOrders = list.map((item) => PatientLabOrdersResponseModel.fromJson(item as Map)).toList().cast(); + final List balanceAmountList = list.map((item) => PatientAdvanceBalanceResponseModel.fromJson(item as Map)).toList().cast(); + + for (var element in balanceAmountList) { + element.totalAmount = response['TotalAdvanceBalanceAmount']; + } apiResponse = GenericApiModel( messageStatus: messageStatus, statusCode: statusCode, errorMessage: null, - data: response["TotalAdvanceBalanceAmount"], + data: balanceAmountList, ); } catch (e) { failure = DataParsingFailure(e.toString()); diff --git a/lib/features/habib_wallet/habib_wallet_view_model.dart b/lib/features/habib_wallet/habib_wallet_view_model.dart index 2f338957..65e8e276 100644 --- a/lib/features/habib_wallet/habib_wallet_view_model.dart +++ b/lib/features/habib_wallet/habib_wallet_view_model.dart @@ -1,6 +1,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_repo.dart'; +import 'package:hmg_patient_app_new/features/habib_wallet/models/patient_advance_balance_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; @@ -30,6 +31,8 @@ class HabibWalletViewModel extends ChangeNotifier { num selectedRechargeType = 1; + List habibWalletBalanceList = []; + HabibWalletViewModel({required this.habibWalletRepo, required this.errorHandlerService}); initHabibWalletProvider() { @@ -39,6 +42,7 @@ class HabibWalletViewModel extends ChangeNotifier { walletRechargeAmount = 0; selectedRechargeType = 1; advancePaymentHospitals.clear(); + habibWalletBalanceList.clear(); selectedHospital = null; fileNumber = ''; depositorName = ''; @@ -103,7 +107,11 @@ class HabibWalletViewModel extends ChangeNotifier { if (apiResponse.messageStatus == 2) { // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); } else if (apiResponse.messageStatus == 1) { - habibWalletAmount = apiResponse.data!; + habibWalletBalanceList = apiResponse.data; + habibWalletAmount = habibWalletBalanceList.first.totalAmount ?? 0.0; + + habibWalletBalanceList.sort((a, b) => b.patientAdvanceBalanceAmount!.compareTo(a.patientAdvanceBalanceAmount!)); + isWalletAmountLoading = false; notifyListeners(); if (onSuccess != null) { diff --git a/lib/features/habib_wallet/models/patient_advance_balance_response_model.dart b/lib/features/habib_wallet/models/patient_advance_balance_response_model.dart new file mode 100644 index 00000000..55594555 --- /dev/null +++ b/lib/features/habib_wallet/models/patient_advance_balance_response_model.dart @@ -0,0 +1,27 @@ +class PatientAdvanceBalanceResponseModel { + num? distanceInKilometers; + num? patientAdvanceBalanceAmount; + String? projectDescription; + int? projectID; + num? totalAmount; + + PatientAdvanceBalanceResponseModel({this.distanceInKilometers, this.patientAdvanceBalanceAmount, this.projectDescription, this.projectID, this.totalAmount}); + + PatientAdvanceBalanceResponseModel.fromJson(Map json) { + distanceInKilometers = json['DistanceInKilometers']; + patientAdvanceBalanceAmount = json['PatientAdvanceBalanceAmount']; + projectDescription = json['ProjectDescription']; + projectID = json['ProjectID']; + totalAmount = json['TotalAmount']; + } + + Map toJson() { + final Map data = Map(); + data['DistanceInKilometers'] = distanceInKilometers; + data['PatientAdvanceBalanceAmount'] = patientAdvanceBalanceAmount; + data['ProjectDescription'] = projectDescription; + data['ProjectID'] = projectID; + data['TotalAmount'] = totalAmount; + return data; + } +} diff --git a/lib/presentation/habib_wallet/habib_wallet_page.dart b/lib/presentation/habib_wallet/habib_wallet_page.dart index c90003a8..780c3d64 100644 --- a/lib/presentation/habib_wallet/habib_wallet_page.dart +++ b/lib/presentation/habib_wallet/habib_wallet_page.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -26,6 +28,16 @@ class HabibWalletPage extends StatefulWidget { class _HabibWalletState extends State { late HabibWalletViewModel habibWalletVM; + @override + void initState() { + scheduleMicrotask(() async { + habibWalletVM.initHabibWalletProvider(); + habibWalletVM.getPatientBalanceAmount(); + }); + + super.initState(); + } + @override Widget build(BuildContext context) { habibWalletVM = Provider.of(context, listen: false); @@ -44,7 +56,7 @@ class _HabibWalletState extends State { width: double.infinity, height: 180.h, decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.blackBgColor, + color: AppColors.whiteColor, borderRadius: 24, ), child: Padding( @@ -59,18 +71,18 @@ class _HabibWalletState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "${_appState.getAuthenticatedUser()!.firstName!} ${_appState.getAuthenticatedUser()!.lastName!}".toText19(isBold: true, color: AppColors.whiteColor), + "${_appState.getAuthenticatedUser()!.firstName!} ${_appState.getAuthenticatedUser()!.lastName!}".toText19(isBold: true, color: AppColors.textColor), "MRN: ${_appState.getAuthenticatedUser()!.patientId!}".toText14(weight: FontWeight.w500, color: AppColors.greyTextColor), ], ).expanded, - Utils.buildSvgWithAssets(icon: AppAssets.habiblogo, width: 24.h, height: 24.h), + Utils.buildSvgWithAssets(icon: AppAssets.habiblogo, width: 24.h, height: 24.h, applyThemeColor: false), ], ), Spacer(), - LocaleKeys.balanceAmount.tr(context: context).toText14(weight: FontWeight.w500, color: AppColors.whiteColor), + LocaleKeys.balanceAmount.tr(context: context).toText14(weight: FontWeight.w500, color: AppColors.textColor), SizedBox(height: 4.h), Consumer(builder: (context, habibWalletVM, child) { - return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, textColor: AppColors.whiteColor, iconColor: AppColors.whiteColor, iconSize: 13, isExpanded: false) + return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, textColor: AppColors.textColor, iconColor: AppColors.textColor, iconSize: 16, isExpanded: false) .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 24.h); }), ], @@ -86,7 +98,7 @@ class _HabibWalletState extends State { icon: AppAssets.recharge_icon, iconSize: 24.w, backgroundColor: AppColors.infoColor, - textColor: AppColors.whiteColor, + textColor: Colors.white, text: LocaleKeys.recharge.tr(context: context), borderWidth: 0.w, fontWeight: FontWeight.w500, @@ -99,12 +111,42 @@ class _HabibWalletState extends State { page: RechargeWalletPage(), )) .then((val) { + habibWalletVM.initHabibWalletProvider(); habibWalletVM.getPatientBalanceAmount(); }); }, ), ], ), + SizedBox(height: 16.h), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: false, + ), + child: Consumer(builder: (context, habibWalletVM, child) { + return ListView.separated( + itemCount: habibWalletVM.habibWalletBalanceList.length, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.only(top: 8, bottom: 8), + shrinkWrap: true, + itemBuilder: (context, index) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: habibWalletVM.habibWalletBalanceList[index].projectDescription!.toText16(weight: FontWeight.w500, color: AppColors.textColor)), + Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletBalanceList[index].patientAdvanceBalanceAmount!, textColor: AppColors.textColor, iconColor: AppColors.textColor, iconSize: 18.h, isExpanded: false, fontSize: 28.f, fontWeight: FontWeight.w500), + ], + ).paddingSymmetrical(0, 12.h); + }, + separatorBuilder: (BuildContext context, int index) { + return Divider(height: 1, color: AppColors.textColor.withAlpha(20)); + }, + ).paddingSymmetrical(16.h, 24.h).toShimmer2(isShow: habibWalletVM.isWalletAmountLoading); + }), + ), + SizedBox(height: 24.h), ], ), ), From 30bdfac44296ae24162d317d2f6c113f92d72185 Mon Sep 17 00:00:00 2001 From: Haroon Amjad <> Date: Fri, 13 Mar 2026 14:24:15 +0300 Subject: [PATCH 04/17] App update page updates --- ios/Runner.xcodeproj/project.pbxproj | 42 +++--- .../AppIcon.appiconset/Contents.json | 129 +----------------- lib/presentation/home/app_update_page.dart | 6 +- 3 files changed, 26 insertions(+), 151 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index e031a976..8ed9d257 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -11,6 +11,12 @@ 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 478CFA942E638C8E0064F3D7 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 478CFA932E638C8E0064F3D7 /* GoogleService-Info.plist */; }; + 47C1AAC72F425ACF00DA1231 /* Penguin.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47C1AAC12F425AC800DA1231 /* Penguin.xcframework */; }; + 47C1AAC82F425ACF00DA1231 /* Penguin.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 47C1AAC12F425AC800DA1231 /* Penguin.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 47C1AAC92F425AD000DA1231 /* PenguinINRenderer.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47C1AAC22F425AC800DA1231 /* PenguinINRenderer.xcframework */; }; + 47C1AACA2F425AD000DA1231 /* PenguinINRenderer.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 47C1AAC22F425AC800DA1231 /* PenguinINRenderer.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 47C1AACB2F425AD100DA1231 /* PenNavUI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47C1AAC32F425AC800DA1231 /* PenNavUI.xcframework */; }; + 47C1AACC2F425AD100DA1231 /* PenNavUI.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 47C1AAC32F425AC800DA1231 /* PenNavUI.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 61243B492EC5FA3700D46FA0 /* PenguinModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B422EC5FA3700D46FA0 /* PenguinModel.swift */; }; 61243B4C2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B3D2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift */; }; 61243B502EC5FA3700D46FA0 /* PenguinView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B452EC5FA3700D46FA0 /* PenguinView.swift */; }; @@ -18,12 +24,6 @@ 61243B562EC5FA3700D46FA0 /* PenguinNavigator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B432EC5FA3700D46FA0 /* PenguinNavigator.swift */; }; 61243B572EC5FA3700D46FA0 /* PenguinViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61243B462EC5FA3700D46FA0 /* PenguinViewFactory.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 765A5A8C2F35CD8B0003FF7D /* Penguin.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 765A5A802F35CD730003FF7D /* Penguin.xcframework */; }; - 765A5A8D2F35CD8B0003FF7D /* Penguin.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 765A5A802F35CD730003FF7D /* Penguin.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 765A5A8E2F35CD8B0003FF7D /* PenguinINRenderer.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 765A5A812F35CD730003FF7D /* PenguinINRenderer.xcframework */; }; - 765A5A8F2F35CD8B0003FF7D /* PenguinINRenderer.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 765A5A812F35CD730003FF7D /* PenguinINRenderer.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 765A5A902F35CD8B0003FF7D /* PenNavUI.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 765A5A822F35CD730003FF7D /* PenNavUI.xcframework */; }; - 765A5A912F35CD8B0003FF7D /* PenNavUI.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 765A5A822F35CD730003FF7D /* PenNavUI.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 76AA18AE2F3B2A4D00DC8DFC /* ring_30Sec.caf in Resources */ = {isa = PBXBuildFile; fileRef = 76AA18AC2F3B2A4D00DC8DFC /* ring_30Sec.caf */; }; 76AA18AF2F3B2A4D00DC8DFC /* ring_30Sec.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 76AA18AD2F3B2A4D00DC8DFC /* ring_30Sec.mp3 */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; @@ -49,9 +49,9 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 765A5A8F2F35CD8B0003FF7D /* PenguinINRenderer.xcframework in Embed Frameworks */, - 765A5A8D2F35CD8B0003FF7D /* Penguin.xcframework in Embed Frameworks */, - 765A5A912F35CD8B0003FF7D /* PenNavUI.xcframework in Embed Frameworks */, + 47C1AACA2F425AD000DA1231 /* PenguinINRenderer.xcframework in Embed Frameworks */, + 47C1AAC82F425ACF00DA1231 /* Penguin.xcframework in Embed Frameworks */, + 47C1AACC2F425AD100DA1231 /* PenNavUI.xcframework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -66,6 +66,9 @@ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 478CFA932E638C8E0064F3D7 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 478CFA952E6E20A60064F3D7 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; + 47C1AAC12F425AC800DA1231 /* Penguin.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = Penguin.xcframework; sourceTree = ""; }; + 47C1AAC22F425AC800DA1231 /* PenguinINRenderer.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = PenguinINRenderer.xcframework; sourceTree = ""; }; + 47C1AAC32F425AC800DA1231 /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = PenNavUI.xcframework; sourceTree = ""; }; 61243B3D2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMGPenguinInPlatformBridge.swift; sourceTree = ""; }; 61243B422EC5FA3700D46FA0 /* PenguinModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinModel.swift; sourceTree = ""; }; 61243B432EC5FA3700D46FA0 /* PenguinNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinNavigator.swift; sourceTree = ""; }; @@ -75,9 +78,6 @@ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7595037DD52211B91157B0F3 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 765A5A802F35CD730003FF7D /* Penguin.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = Penguin.xcframework; sourceTree = ""; }; - 765A5A812F35CD730003FF7D /* PenguinINRenderer.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = PenguinINRenderer.xcframework; sourceTree = ""; }; - 765A5A822F35CD730003FF7D /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = PenNavUI.xcframework; sourceTree = ""; }; 769C9BF82E6F106D009F68A9 /* RunnerDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerDebug.entitlements; sourceTree = ""; }; 76AA18AC2F3B2A4D00DC8DFC /* ring_30Sec.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = ring_30Sec.caf; sourceTree = ""; }; 76AA18AD2F3B2A4D00DC8DFC /* ring_30Sec.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = ring_30Sec.mp3; sourceTree = ""; }; @@ -99,9 +99,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 765A5A8C2F35CD8B0003FF7D /* Penguin.xcframework in Frameworks */, - 765A5A902F35CD8B0003FF7D /* PenNavUI.xcframework in Frameworks */, - 765A5A8E2F35CD8B0003FF7D /* PenguinINRenderer.xcframework in Frameworks */, + 47C1AAC92F425AD000DA1231 /* PenguinINRenderer.xcframework in Frameworks */, + 47C1AACB2F425AD100DA1231 /* PenNavUI.xcframework in Frameworks */, + 47C1AAC72F425ACF00DA1231 /* Penguin.xcframework in Frameworks */, DE1EF78253E64BE86845D2CC /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -140,9 +140,9 @@ 766D8CB22EC60BE600D05E07 /* Frameworks */ = { isa = PBXGroup; children = ( - 765A5A802F35CD730003FF7D /* Penguin.xcframework */, - 765A5A812F35CD730003FF7D /* PenguinINRenderer.xcframework */, - 765A5A822F35CD730003FF7D /* PenNavUI.xcframework */, + 47C1AAC12F425AC800DA1231 /* Penguin.xcframework */, + 47C1AAC22F425AC800DA1231 /* PenguinINRenderer.xcframework */, + 47C1AAC32F425AC800DA1231 /* PenNavUI.xcframework */, D562310E31D1DDEFA02A6C12 /* Pods_Runner.framework */, ); name = Frameworks; @@ -523,7 +523,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 8; DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -709,7 +709,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 8; DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -738,7 +738,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 8; DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index 1eb27a20..65b74d7e 100644 --- a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,128 +1 @@ -{ - "images" : [ - { - "filename" : "Icon-App-20x20@2x.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "20x20" - }, - { - "filename" : "Icon-App-20x20@3x.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "20x20" - }, - { - "filename" : "Icon-App-29x29@1x.png", - "idiom" : "iphone", - "scale" : "1x", - "size" : "29x29" - }, - { - "filename" : "Icon-App-29x29@2x.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "29x29" - }, - { - "filename" : "Icon-App-29x29@3x.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "29x29" - }, - { - "filename" : "Icon-App-40x40@2x.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "40x40" - }, - { - "filename" : "Icon-App-40x40@3x.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "40x40" - }, - { - "filename" : "Icon-App-60x60@2x.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "60x60" - }, - { - "filename" : "Icon-App-60x60@3x.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "60x60" - }, - { - "filename" : "Icon-App-20x20@1x.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "20x20" - }, - { - "filename" : "Icon-App-20x20@2x.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "20x20" - }, - { - "filename" : "Icon-App-29x29@1x.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "29x29" - }, - { - "filename" : "Icon-App-29x29@2x.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "29x29" - }, - { - "filename" : "Icon-App-40x40@1x.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "40x40" - }, - { - "filename" : "Icon-App-40x40@2x.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "40x40" - }, - { - "filename" : "Icon-App-76x76@1x.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "76x76" - }, - { - "filename" : "Icon-App-76x76@2x.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "76x76" - }, - { - "filename" : "Icon-App-83.5x83.5@2x.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "83.5x83.5" - }, - { - "filename" : "icon.jpg", - "idiom" : "ios-marketing", - "scale" : "1x", - "size" : "1024x1024" - }, - { - "filename" : "Icon-App-76x76@2x.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "76x76" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} +{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"}]} \ No newline at end of file diff --git a/lib/presentation/home/app_update_page.dart b/lib/presentation/home/app_update_page.dart index 5e6481bd..18382838 100644 --- a/lib/presentation/home/app_update_page.dart +++ b/lib/presentation/home/app_update_page.dart @@ -83,13 +83,15 @@ class AppUpdatePage extends StatelessWidget { }).catchError((e) { print(e.toString()); Utils.openWebView( - url: "https://play.google.com/store/apps/details?id=com.ejada.hmg", + // url: "https://play.google.com/store/apps/details?id=com.ejada.hmg", + url: "https://play.google.com/store/apps/details?id=com.cloudsolutions.HMGPatientApp", ); }); } if (Platform.isIOS) { Utils.openWebView( - url: "https://itunes.apple.com/app/id733503978", + // url: "https://itunes.apple.com/app/id733503978", + url: "https://itunes.apple.com/app/id6758851027", ); } } From 657f88639131d2b7055e62c4dd52238f7a8e1c64 Mon Sep 17 00:00:00 2001 From: Haroon Amjad <> Date: Sat, 14 Mar 2026 15:06:50 +0300 Subject: [PATCH 05/17] Changes for AI Lab analysis --- PROJECT_ARCHITECTURE.md | 1768 +++++++++++++++++ lib/core/api/api_client.dart | 4 +- lib/features/lab/lab_view_model.dart | 5 + .../book_appointment/doctor_profile_page.dart | 21 +- .../LabResultByClinic.dart | 2 +- .../ai_analysis_widget.dart | 11 + .../lab/lab_results/lab_result_details.dart | 176 +- 7 files changed, 1880 insertions(+), 107 deletions(-) create mode 100644 PROJECT_ARCHITECTURE.md diff --git a/PROJECT_ARCHITECTURE.md b/PROJECT_ARCHITECTURE.md new file mode 100644 index 00000000..00ee9672 --- /dev/null +++ b/PROJECT_ARCHITECTURE.md @@ -0,0 +1,1768 @@ + +You are a senior Flutter developer. You will be given this entire document as your specification. +Your task: generate a complete, compilable Flutter project from scratch following every instruction below. +Do NOT skip any file. Do NOT summarize. Generate FULL, working Dart code for every file listed. +When you see placeholder names like `{{APP_NAME}}`, `{{PACKAGE_NAME}}`, `{{BASE_URL}}`, replace them with the values the user provides. If no values are provided, use the defaults in Section 1. + + +# Flutter Project Generator — Architecture Specification + +> **What this document is:** A precise, machine-readable specification for an AI to generate a greenfield Flutter project. Every file path, every class, every method signature, and every pattern is defined below with copy-ready code. Follow it top-to-bottom. + +--- + +## 1. DEFAULTS — Replace These for Your Project + +``` +APP_NAME = "My App" +DART_PACKAGE = "my_app" +ORG_IDENTIFIER = "com.example.myapp" +BASE_URL = "https://api.example.com/" +PRIMARY_COLOR = 0xFFED1C2B (Red) +FIGMA_WIDTH = 430 +FIGMA_HEIGHT = 927 +SUPPORTED_LOCALES = [en-US, ar-SA] +PRIMARY_FONT = "Poppins" +SECONDARY_FONT = "GESSTwo" (Arabic font) +``` + +When the user asks you to generate this project, first ask them for these values. If they say "use defaults," use the values above. + +--- + +## 2. COMMAND — Create the Flutter Project + +Run this first: +```bash +flutter create --org {{ORG_IDENTIFIER}} --project-name {{DART_PACKAGE}} {{DART_PACKAGE}} +cd {{DART_PACKAGE}} +``` + +--- + +## 3. FILE: `pubspec.yaml` + +Generate this file EXACTLY. Do not add or remove packages. + +```yaml +name: {{DART_PACKAGE}} +description: "{{APP_NAME}}" +publish_to: 'none' +version: 1.0.0+1 + +environment: + sdk: ">=3.6.0 <4.0.0" + +dependencies: + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + + # === Core Architecture === + provider: ^6.1.5+1 + get_it: ^8.2.0 + dartz: ^0.10.1 + equatable: ^2.0.7 + + # === Networking === + http: ^1.5.0 + connectivity_plus: ^6.1.5 + + # === Firebase === + firebase_core: any + firebase_messaging: ^15.2.10 + firebase_analytics: ^11.5.1 + firebase_crashlytics: ^4.3.8 + + # === UI === + cupertino_icons: ^1.0.8 + flutter_svg: ^2.2.0 + cached_network_image: ^3.4.1 + auto_size_text: ^3.0.0 + shimmer: ^3.0.0 + sizer: ^3.1.3 + lottie: ^3.3.1 + smooth_corner: ^1.1.1 + flutter_staggered_animations: ^1.1.1 + fl_chart: 1.0.0 + flutter_rating_bar: ^4.0.1 + + # === Localization === + easy_localization: ^3.0.8 + intl: ^0.20.2 + + # === Storage === + shared_preferences: ^2.5.3 + path_provider: ^2.0.8 + + # === Device === + permission_handler: ^12.0.1 + local_auth: ^2.3.0 + device_info_plus: ^11.5.0 + image_picker: ^1.2.0 + url_launcher: ^6.3.2 + share_plus: ^11.1.0 + + # === Notifications === + flutter_local_notifications: ^19.4.1 + timezone: ^0.10.0 + fluttertoast: ^8.2.12 + + # === Logging === + logger: ^2.6.1 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + +flutter: + uses-material-design: true + assets: + - assets/ + - assets/json/ + - assets/fonts/ + - assets/langs/ + - assets/images/ + - assets/images/svg/ + - assets/images/png/ + - assets/animations/ + - assets/animations/lottie/ + + fonts: + - family: Poppins + fonts: + - asset: assets/fonts/poppins/Poppins-SemiBold.ttf + weight: 600 + - asset: assets/fonts/poppins/Poppins-Medium.ttf + weight: 500 + - asset: assets/fonts/poppins/Poppins-Regular.ttf + weight: 400 + - asset: assets/fonts/poppins/Poppins-Light.ttf + weight: 300 +``` + +> **Note:** If the user provides a SECONDARY_FONT, add its font family block here too. + +--- + +## 4. FILE: `analysis_options.yaml` + +```yaml +include: package:flutter_lints/flutter.yaml + +linter: + rules: + # prefer_single_quotes: true +``` + +--- + +## 5. FOLDER STRUCTURE — Create ALL These Directories + +```bash +mkdir -p lib/core/api +mkdir -p lib/core/common_models +mkdir -p lib/core/exceptions +mkdir -p lib/core/utils +mkdir -p lib/services/analytics +mkdir -p lib/features +mkdir -p lib/presentation/home/widgets +mkdir -p lib/presentation/authentication +mkdir -p lib/presentation/onboarding +mkdir -p lib/routes +mkdir -p lib/theme +mkdir -p lib/extensions +mkdir -p lib/widgets/buttons +mkdir -p lib/widgets/loader +mkdir -p lib/widgets/bottomsheet +mkdir -p lib/widgets/bottom_navigation +mkdir -p lib/widgets/shimmer +mkdir -p lib/widgets/routes +mkdir -p lib/generated +mkdir -p assets/fonts/poppins +mkdir -p assets/images/svg +mkdir -p assets/images/png +mkdir -p assets/animations/lottie +mkdir -p assets/json +mkdir -p assets/langs +mkdir -p assets/sounds +``` + +--- + +## 6. CORE LAYER — Generate Each File Exactly + +### 6.1 FILE: `lib/core/enums.dart` + +```dart +enum ViewStateEnum { hide, idle, busy, error, busyLocal, errorLocal } + +enum AppEnvironmentTypeEnum { dev, uat, preProd, qa, staging, prod } + +enum GenderTypeEnum { male, female } + +enum ChipTypeEnum { success, error, alert, info, warning, lightBg, primaryRed } + +enum LoginTypeEnum { sms, whatsapp, face, fingerprint } + +enum OTPTypeEnum { sms, whatsapp, faceIDFingerprint } +``` + +### 6.2 FILE: `lib/core/exceptions/api_failure.dart` + +```dart +import 'package:equatable/equatable.dart'; + +abstract class Failure extends Equatable implements Exception { + final String message; + const Failure(this.message); +} + +class ServerFailure extends Failure { + final String url; + const ServerFailure(super.message, {this.url = ""}); + @override + List get props => [message]; +} + +class DataParsingFailure extends Failure { + const DataParsingFailure(super.message); + @override + List get props => [message]; +} + +class ConnectivityFailure extends Failure { + const ConnectivityFailure(super.message); + @override + List get props => [message]; +} + +class UnAuthenticatedUserFailure extends Failure { + final String url; + const UnAuthenticatedUserFailure(super.message, {this.url = ""}); + @override + List get props => [message]; +} + +class AppUpdateFailure extends Failure { + const AppUpdateFailure(super.message); + @override + List get props => [message]; +} + +class StatusCodeFailure extends Failure { + const StatusCodeFailure(super.message); + @override + List get props => [message]; +} + +class UnknownFailure extends Failure { + final String url; + const UnknownFailure(super.message, {this.url = ""}); + @override + List get props => [message]; +} + +class UserIntimationFailure extends Failure { + const UserIntimationFailure(super.message); + @override + List get props => [message]; +} + +class MessageStatusFailure extends Failure { + const MessageStatusFailure(super.message); + @override + List get props => [message]; +} + +class InvalidCredentials extends Failure { + const InvalidCredentials(String? message) : super(message ?? ''); + @override + List get props => [message]; +} + +class LocalStorageFailure extends Failure { + const LocalStorageFailure(super.message); + @override + List get props => [message]; +} +``` + +### 6.3 FILE: `lib/core/common_models/generic_api_model.dart` + +```dart +class GenericApiModel { + final int? messageStatus; + final String? errorMessage; + final int? statusCode; + final T? data; + + GenericApiModel({this.messageStatus, this.errorMessage, this.statusCode, this.data}); + + factory GenericApiModel.fromJson( + Map json, + T Function(Object? json)? fromJsonT, + ) { + return GenericApiModel( + messageStatus: json['messageStatus'] as int?, + errorMessage: json['errorMessage'] as String?, + statusCode: json['statusCode'] as int?, + data: fromJsonT != null ? fromJsonT(json['data']) : json['data'] as T?, + ); + } + + Map toJson(Object Function(T value)? toJsonT) { + return { + 'messageStatus': messageStatus, + 'errorMessage': errorMessage, + 'statusCode': statusCode, + 'data': toJsonT != null && data != null ? toJsonT(data as T) : data, + }; + } +} +``` + +### 6.4 FILE: `lib/core/api_consts.dart` + +```dart +import 'package:{{DART_PACKAGE}}/core/enums.dart'; + +const int VERSION_ID = 1; +const int CHANNEL = 3; +const String IP_ADDRESS = "10.20.10.20"; +const String GENERAL_ID = "Aborkan"; +const int PATIENT_TYPE = 1; +const int PATIENT_TYPE_ID = 1; +const String SETUP_ID = "010266"; +const bool IS_DENTAL_ALLOWED_BACKEND = false; + +class ApiConsts { + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; + static String baseUrl = '{{BASE_URL}}'; + + static int appVersionID = VERSION_ID; + static int appChannelId = CHANNEL; + static String appIpAddress = IP_ADDRESS; + static String appGeneralId = GENERAL_ID; + static String sessionID = ""; + + static void setBackendURLs() { + switch (appEnvironmentType) { + case AppEnvironmentTypeEnum.prod: + baseUrl = '{{BASE_URL}}'; + break; + case AppEnvironmentTypeEnum.dev: + case AppEnvironmentTypeEnum.uat: + case AppEnvironmentTypeEnum.preProd: + case AppEnvironmentTypeEnum.qa: + case AppEnvironmentTypeEnum.staging: + baseUrl = '{{BASE_URL}}'; + break; + } + } + + // ── Add endpoint paths here as you build features ── + // static const String login = "api/auth/login"; +} +``` + +### 6.5 FILE: `lib/core/cache_consts.dart` + +```dart +class CacheConst { + static const String firstLaunch = "firstLaunch"; + static const String appAuthToken = "app_auth_token"; + static const String loggedInUserObj = "logged_in_user_obj"; + static const String pushToken = "push_token"; + static const String appLanguage = 'language'; + static const String isDarkMode = 'is_dark_mode'; + + // Add more cache keys as features are built +} +``` + +### 6.6 FILE: `lib/core/app_state.dart` + +```dart +import 'dart:io'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:{{DART_PACKAGE}}/services/navigation_service.dart'; + +class AppState { + final NavigationService navigationService; + + AppState({required this.navigationService}); + + double userLat = 0.0; + double userLong = 0.0; + + bool isArabic() { + final ctx = navigationService.navigatorKey.currentContext; + if (ctx == null) return false; + return EasyLocalization.of(ctx)?.locale.languageCode == "ar"; + } + + int getLanguageID() => isArabic() ? 1 : 2; + String? getLanguageCode() { + final ctx = navigationService.navigatorKey.currentContext; + if (ctx == null) return "en"; + return EasyLocalization.of(ctx)?.locale.languageCode; + } + int getDeviceTypeID() => Platform.isIOS ? 1 : 2; + + bool isAuthenticated = false; + String appAuthToken = ""; + String deviceToken = ""; + String voipToken = ""; + String sessionId = ""; + String deviceTypeID = ""; + + Map? authenticatedUser; + + void setAuthenticatedUser(Map? user) { + authenticatedUser = user; + isAuthenticated = user != null; + } + + void resetLocation() { + userLat = 0.0; + userLong = 0.0; + } +} +``` + +### 6.7 FILE: `lib/core/app_assets.dart` + +```dart +class AppAssets { + static const String svgBasePath = 'assets/images/svg'; + static const String pngBasePath = 'assets/images/png'; + static const String lottieBasePath = 'assets/animations/lottie'; + + // Add asset constants here as you add files. Examples: + // static const String logo = '$svgBasePath/logo.svg'; + // static const String placeholder = '$pngBasePath/placeholder.png'; +} +``` + +### 6.8 FILE: `lib/core/app_export.dart` + +```dart +export '../routes/app_routes.dart'; +export 'utils/size_utils.dart'; +``` + +### 6.9 FILE: `lib/core/utils/size_utils.dart` + +```dart +import 'package:flutter/material.dart'; + +const num figmaDesignWidth = {{FIGMA_WIDTH}}; +const num figmaDesignHeight = {{FIGMA_HEIGHT}}; + +class SizeUtils { + static late double width; + static late double height; + static late DeviceType deviceType; + + static void init(BoxConstraints constraints, Orientation orientation) { + width = constraints.maxWidth; + height = constraints.maxHeight; + deviceType = width > 600 ? DeviceType.tablet : DeviceType.phone; + } +} + +enum DeviceType { phone, tablet } + +bool get isTablet => SizeUtils.deviceType == DeviceType.tablet; + +extension ResponsiveExtension on num { + double get _width => SizeUtils.width; + double get _height => SizeUtils.height; + + double get f { + double scale = (_width < _height ? _width : _height) / figmaDesignWidth; + double clamp = isTablet ? 1.4 : 1.2; + if (scale > clamp) scale = clamp; + return this * scale; + } + + double get w => (this * _width) / figmaDesignWidth; + double get h => (this * _height) / figmaDesignHeight; + double get r => (this * _width) / figmaDesignWidth; +} +``` + +### 6.10 FILE: `lib/core/utils/loading_utils.dart` + +```dart +import 'package:flutter/material.dart'; +import 'package:{{DART_PACKAGE}}/core/dependencies.dart'; +import 'package:{{DART_PACKAGE}}/services/navigation_service.dart'; + +class LoadingUtils { + static bool isLoading = false; + static OverlayEntry? _overlayEntry; + + static void showFullScreenLoader() { + final context = getIt.get().navigatorKey.currentContext; + if (context == null || isLoading) return; + isLoading = true; + _overlayEntry = OverlayEntry( + builder: (_) => Container( + color: Colors.black38, + child: const Center(child: CircularProgressIndicator()), + ), + ); + Overlay.of(context).insert(_overlayEntry!); + } + + static void hideFullScreenLoader() { + _overlayEntry?.remove(); + _overlayEntry = null; + isLoading = false; + } +} +``` + +### 6.11 FILE: `lib/core/api/api_client.dart` + +```dart +import 'dart:convert'; +import 'package:flutter/foundation.dart'; +import 'package:http/http.dart' as http; +import 'package:{{DART_PACKAGE}}/core/api_consts.dart'; +import 'package:{{DART_PACKAGE}}/core/app_state.dart'; +import 'package:{{DART_PACKAGE}}/core/exceptions/api_failure.dart'; + +abstract class ApiClient { + Future post( + String endPoint, { + required Map body, + required Function(dynamic response, int statusCode, {int? messageStatus, String? errorMessage}) onSuccess, + required Function(String error, int statusCode, {int? messageStatus, Failure? failureType}) onFailure, + bool isExternal = false, + Map? apiHeaders, + }); + + Future get( + String endPoint, { + required Function(dynamic response, int statusCode) onSuccess, + required Function(String error, int statusCode) onFailure, + Map? queryParams, + Map? apiHeaders, + bool isExternal = false, + }); +} + +class ApiClientImp implements ApiClient { + final AppState _appState; + + ApiClientImp({required AppState appState}) : _appState = appState; + + Map _defaultHeaders() => {'Content-Type': 'application/json', 'Accept': 'application/json'}; + + void _injectCommonFields(Map body) { + body['VersionID'] = ApiConsts.appVersionID.toString(); + body['Channel'] = ApiConsts.appChannelId.toString(); + body['IPAdress'] = ApiConsts.appIpAddress; + body['generalid'] = ApiConsts.appGeneralId; + body['LanguageID'] = _appState.getLanguageID().toString(); + body['Latitude'] = _appState.userLat.toString(); + body['Longitude'] = _appState.userLong.toString(); + body['DeviceTypeID'] = _appState.deviceTypeID; + if (_appState.appAuthToken.isNotEmpty) { + body[_appState.isAuthenticated ? 'TokenID' : 'LogInTokenID'] = _appState.appAuthToken; + } + } + + @override + Future post( + String endPoint, { + required Map body, + required Function(dynamic response, int statusCode, {int? messageStatus, String? errorMessage}) onSuccess, + required Function(String error, int statusCode, {int? messageStatus, Failure? failureType}) onFailure, + bool isExternal = false, + Map? apiHeaders, + }) async { + final url = isExternal ? endPoint : ApiConsts.baseUrl + endPoint; + final headers = apiHeaders ?? _defaultHeaders(); + if (!isExternal) _injectCommonFields(body); + + try { + final response = await http.post(Uri.parse(url), headers: headers, body: jsonEncode(body)); + final statusCode = response.statusCode; + + if (statusCode == 401) { + onFailure('Unauthenticated', statusCode, failureType: UnAuthenticatedUserFailure('Session expired', url: url)); + return; + } + if (statusCode == 426) { + onFailure('App update required', statusCode, failureType: const AppUpdateFailure('Please update the app')); + return; + } + + if (statusCode >= 200 && statusCode < 300) { + final decoded = jsonDecode(response.body); + final int? messageStatus = decoded['MessageStatus']; + final String? errorMessage = decoded['ErrorEndUserMessage'] ?? decoded['ErrorMessage']; + + if (messageStatus == 1 || messageStatus == null) { + onSuccess(decoded, statusCode, messageStatus: messageStatus, errorMessage: errorMessage); + } else { + onFailure(errorMessage ?? 'Request failed', statusCode, + messageStatus: messageStatus, + failureType: MessageStatusFailure(errorMessage ?? 'Request failed with status $messageStatus')); + } + } else { + onFailure('Server error: $statusCode', statusCode, failureType: ServerFailure('Server error: $statusCode', url: url)); + } + } catch (e) { + if (kDebugMode) print('API POST error ($url): $e'); + onFailure(e.toString(), 0, failureType: UnknownFailure(e.toString(), url: url)); + } + } + + @override + Future get( + String endPoint, { + required Function(dynamic response, int statusCode) onSuccess, + required Function(String error, int statusCode) onFailure, + Map? queryParams, + Map? apiHeaders, + bool isExternal = false, + }) async { + final baseUrl = isExternal ? endPoint : ApiConsts.baseUrl + endPoint; + final uri = Uri.parse(baseUrl).replace(queryParameters: queryParams?.map((k, v) => MapEntry(k, v.toString()))); + final headers = apiHeaders ?? _defaultHeaders(); + + try { + final response = await http.get(uri, headers: headers); + if (response.statusCode >= 200 && response.statusCode < 300) { + onSuccess(jsonDecode(response.body), response.statusCode); + } else { + onFailure('GET failed: ${response.statusCode}', response.statusCode); + } + } catch (e) { + onFailure(e.toString(), 0); + } + } +} +``` + +--- + +## 7. SERVICES LAYER — Generate Each File Exactly + +### 7.1 FILE: `lib/services/logger_service.dart` + +```dart +import 'package:logger/logger.dart'; + +abstract class LoggerService { + void logError(String message); + void logInfo(String message); +} + +class LoggerServiceImp implements LoggerService { + final Logger logger; + LoggerServiceImp({required this.logger}); + + @override + void logError(String message) => logger.e(message); + @override + void logInfo(String message) => logger.d(message); +} +``` + +### 7.2 FILE: `lib/services/navigation_service.dart` + +```dart +import 'package:flutter/material.dart'; + +class NavigationService { + final GlobalKey navigatorKey = GlobalKey(); + + BuildContext? get context => navigatorKey.currentContext; + + Future push(Route route) => navigatorKey.currentState!.push(route); + + Future pushAndRemoveUntil(Route route, RoutePredicate predicate) => + navigatorKey.currentState!.pushAndRemoveUntil(route, predicate); + + void pop([T? result]) => navigatorKey.currentState!.pop(result); + + void popUntilNamed(String routeName) => + navigatorKey.currentState?.popUntil(ModalRoute.withName(routeName)); + + void replaceAllRoutesAndNavigateTo(String routeName) { + navigatorKey.currentState?.pushNamedAndRemoveUntil(routeName, (route) => false); + } + + void pushAndReplace(String routeName) => + navigatorKey.currentState?.pushReplacementNamed(routeName); + + void pushNamed(String routeName, {Object? arguments}) => + navigatorKey.currentState?.pushNamed(routeName, arguments: arguments); + + Future pushPage({required Widget page, bool fullscreenDialog = false}) => + navigatorKey.currentState!.push( + MaterialPageRoute(builder: (_) => page, fullscreenDialog: fullscreenDialog), + ); +} +``` + +### 7.3 FILE: `lib/services/cache_service.dart` + +```dart +import 'dart:convert'; +import 'package:{{DART_PACKAGE}}/services/logger_service.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +abstract class CacheService { + Future saveString({required String key, required String value}); + Future saveInt({required String key, required int value}); + Future saveBool({required String key, required bool value}); + String? getString({required String key}); + int? getInt({required String key}); + bool? getBool({required String key}); + Future getObject({required String key}); + Future saveObject({required String key, required dynamic value}); + Future remove({required String key}); + Future clear(); +} + +class CacheServiceImp implements CacheService { + final SharedPreferences sharedPreferences; + final LoggerService loggerService; + + CacheServiceImp({required this.sharedPreferences, required this.loggerService}); + + @override + Future saveString({required String key, required String value}) async => await sharedPreferences.setString(key, value); + @override + Future saveInt({required String key, required int value}) async => await sharedPreferences.setInt(key, value); + @override + Future saveBool({required String key, required bool value}) async => await sharedPreferences.setBool(key, value); + @override + String? getString({required String key}) => sharedPreferences.getString(key); + @override + int? getInt({required String key}) => sharedPreferences.getInt(key); + @override + bool? getBool({required String key}) => sharedPreferences.getBool(key); + + @override + Future getObject({required String key}) async { + try { + await sharedPreferences.reload(); + final s = sharedPreferences.getString(key); + return s == null ? null : json.decode(s); + } catch (e) { + loggerService.logError(e.toString()); + return null; + } + } + + @override + Future saveObject({required String key, required dynamic value}) async => + await sharedPreferences.setString(key, json.encode(value)); + @override + Future remove({required String key}) async => await sharedPreferences.remove(key); + @override + Future clear() async => await sharedPreferences.clear(); +} +``` + +### 7.4 FILE: `lib/services/dialog_service.dart` + +```dart +import 'package:flutter/material.dart'; +import 'package:{{DART_PACKAGE}}/services/navigation_service.dart'; +import 'package:{{DART_PACKAGE}}/theme/colors.dart'; + +abstract class DialogService { + Future showErrorBottomSheet({String title, required String message, Function()? onOkPressed}); + Future showConfirmBottomSheet({required String message, required Function() onOkPressed, Function()? onCancelPressed}); +} + +class DialogServiceImp implements DialogService { + final NavigationService navigationService; + bool _isSheetShowing = false; + + DialogServiceImp({required this.navigationService}); + + @override + Future showErrorBottomSheet({String title = "", required String message, Function()? onOkPressed}) async { + if (_isSheetShowing) return; + final context = navigationService.navigatorKey.currentContext; + if (context == null) return; + _isSheetShowing = true; + await showModalBottomSheet( + context: context, + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(16))), + builder: (_) => Padding( + padding: const EdgeInsets.all(24), + child: Column(mainAxisSize: MainAxisSize.min, children: [ + if (title.isNotEmpty) ...[Text(title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600)), const SizedBox(height: 12)], + Text(message, textAlign: TextAlign.center), + const SizedBox(height: 24), + SizedBox( + width: double.infinity, + child: ElevatedButton( + style: ElevatedButton.styleFrom(backgroundColor: AppColors.primaryRedColor), + onPressed: () { Navigator.pop(context); onOkPressed?.call(); }, + child: const Text('OK', style: TextStyle(color: Colors.white)), + ), + ), + ]), + ), + ); + _isSheetShowing = false; + } + + @override + Future showConfirmBottomSheet({required String message, required Function() onOkPressed, Function()? onCancelPressed}) async { + final context = navigationService.navigatorKey.currentContext; + if (context == null) return; + await showModalBottomSheet( + context: context, + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(16))), + builder: (_) => Padding( + padding: const EdgeInsets.all(24), + child: Column(mainAxisSize: MainAxisSize.min, children: [ + Text(message, textAlign: TextAlign.center), + const SizedBox(height: 24), + Row(children: [ + Expanded(child: OutlinedButton(onPressed: () { Navigator.pop(context); onCancelPressed?.call(); }, child: const Text('Cancel'))), + const SizedBox(width: 12), + Expanded(child: ElevatedButton( + style: ElevatedButton.styleFrom(backgroundColor: AppColors.primaryRedColor), + onPressed: () { Navigator.pop(context); onOkPressed(); }, + child: const Text('OK', style: TextStyle(color: Colors.white)), + )), + ]), + ]), + ), + ); + } +} +``` + +### 7.5 FILE: `lib/services/error_handler_service.dart` + +```dart +import 'package:{{DART_PACKAGE}}/core/exceptions/api_failure.dart'; +import 'package:{{DART_PACKAGE}}/core/utils/loading_utils.dart'; +import 'package:{{DART_PACKAGE}}/services/dialog_service.dart'; +import 'package:{{DART_PACKAGE}}/services/logger_service.dart'; +import 'package:{{DART_PACKAGE}}/services/navigation_service.dart'; +import 'package:{{DART_PACKAGE}}/routes/app_routes.dart'; + +abstract class ErrorHandlerService { + Future handleError({required Failure failure, Function()? onOkPressed, Function(Failure)? onUnHandledFailure, Function(Failure)? onMessageStatusFailure}); +} + +class ErrorHandlerServiceImp implements ErrorHandlerService { + final DialogService dialogService; + final LoggerService loggerService; + final NavigationService navigationService; + + ErrorHandlerServiceImp({required this.dialogService, required this.loggerService, required this.navigationService}); + + @override + Future handleError({required Failure failure, Function()? onOkPressed, Function(Failure)? onUnHandledFailure, Function(Failure)? onMessageStatusFailure}) async { + if (LoadingUtils.isLoading) LoadingUtils.hideFullScreenLoader(); + + if (failure is ServerFailure) { + loggerService.logError("Server: ${failure.message}"); + await _show(failure); + } else if (failure is ConnectivityFailure) { + loggerService.logError("Connectivity: ${failure.message}"); + await _show(failure, title: "No Internet"); + } else if (failure is UnAuthenticatedUserFailure) { + loggerService.logError("Unauth: ${failure.message}"); + await _show(failure, title: "Session Expired", onOk: () => navigationService.replaceAllRoutesAndNavigateTo(AppRoutes.landingScreen)); + } else if (failure is AppUpdateFailure) { + await _show(failure, title: "Update Required"); + } else if (failure is DataParsingFailure) { + loggerService.logError("Parse: ${failure.message}"); + await _show(failure, title: "Data Error"); + } else if (failure is UserIntimationFailure) { + onUnHandledFailure != null ? onUnHandledFailure(failure) : await _show(failure, onOk: onOkPressed); + } else if (failure is MessageStatusFailure) { + onMessageStatusFailure != null ? onMessageStatusFailure(failure) : await _show(failure, onOk: onOkPressed); + } else { + loggerService.logError("Unhandled: $failure"); + await _show(failure, onOk: onOkPressed); + } + } + + Future _show(Failure f, {String? title, Function()? onOk}) async => + await dialogService.showErrorBottomSheet(title: title ?? "", message: f.message, onOkPressed: onOk); +} +``` + +### 7.6 FILE: `lib/services/firebase_service.dart` + +```dart +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:{{DART_PACKAGE}}/core/app_state.dart'; +import 'package:{{DART_PACKAGE}}/services/logger_service.dart'; + +abstract class FirebaseService { + Future getDeviceToken(); +} + +class FirebaseServiceImpl implements FirebaseService { + final FirebaseMessaging firebaseMessaging; + final LoggerService loggerService; + final AppState appState; + + FirebaseServiceImpl({required this.firebaseMessaging, required this.loggerService, required this.appState}); + + @override + Future getDeviceToken() async { + try { + final token = await firebaseMessaging.getToken(); + appState.deviceToken = token ?? ""; + return appState.deviceToken; + } catch (e) { + loggerService.logError(e.toString()); + return ""; + } + } +} +``` + +### 7.7 FILE: `lib/services/notification_service.dart` + +```dart +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:{{DART_PACKAGE}}/services/logger_service.dart'; +import 'package:timezone/data/latest_all.dart' as tz; + +abstract class NotificationService { + Future initialize({Function(String payload)? onNotificationClick}); + Future showNotification({required String title, required String body, String? payload}); + Future cancelAllNotifications(); +} + +class NotificationServiceImp implements NotificationService { + final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin; + final LoggerService loggerService; + + NotificationServiceImp({required this.flutterLocalNotificationsPlugin, required this.loggerService}); + + @override + Future initialize({Function(String payload)? onNotificationClick}) async { + tz.initializeTimeZones(); + const android = AndroidInitializationSettings('app_icon'); + const ios = DarwinInitializationSettings(requestAlertPermission: true, requestBadgePermission: true, requestSoundPermission: true); + await flutterLocalNotificationsPlugin.initialize( + const InitializationSettings(android: android, iOS: ios), + onDidReceiveNotificationResponse: (r) => onNotificationClick?.call(r.payload ?? ''), + ); + } + + @override + Future showNotification({required String title, required String body, String? payload}) async { + const details = NotificationDetails( + android: AndroidNotificationDetails('general', 'General', importance: Importance.high, priority: Priority.high), + iOS: DarwinNotificationDetails(), + ); + await flutterLocalNotificationsPlugin.show(DateTime.now().millisecondsSinceEpoch ~/ 1000, title, body, details, payload: payload); + } + + @override + Future cancelAllNotifications() async => await flutterLocalNotificationsPlugin.cancelAll(); +} +``` + +### 7.8 FILE: `lib/services/analytics/analytics_service.dart` + +```dart +import 'package:firebase_analytics/firebase_analytics.dart'; + +class GAnalytics { + final _analytics = FirebaseAnalytics.instance; + + Future logEvent(String name, {Map? parameters}) async { + try { + await _analytics.logEvent(name: name.trim().toLowerCase(), parameters: parameters?.map((k, v) => MapEntry(k, v as Object))); + } catch (_) {} + } + + Future setUser({String? userId, String? language}) async { + if (userId != null) _analytics.setUserProperty(name: 'userid', value: userId); + if (language != null) _analytics.setUserProperty(name: 'user_language', value: language); + } +} +``` + +--- + +## 8. THEME LAYER + +### 8.1 FILE: `lib/theme/colors.dart` + +```dart +import 'package:flutter/material.dart'; + +class AppColors { + static bool isDarkMode = false; + static const transparent = Colors.transparent; + + static Color get scaffoldBgColor => isDarkMode ? dark.scaffoldBgColor : const Color(0xFFF8F8F8); + static Color get whiteColor => isDarkMode ? dark.whiteColor : const Color(0xFFFFFFFF); + static Color get primaryRedColor => isDarkMode ? dark.primaryRedColor : const Color({{PRIMARY_COLOR}}); + static Color get secondaryLightRedColor => isDarkMode ? dark.secondaryLightRedColor : const Color(0xFFFEE9EA); + static const Color successColor = Color(0xFF18C273); + static Color get textColor => isDarkMode ? dark.textColor : const Color(0xFF2E3039); + static Color get iconColor => isDarkMode ? dark.iconColor : const Color(0xFF2E3039); + static Color get greyColor => isDarkMode ? dark.greyColor : const Color(0xFFEFEFF0); + static Color get textColorLight => isDarkMode ? dark.textColorLight : const Color(0xFF5E5E5E); + static Color get dividerColor => isDarkMode ? dark.dividerColor : const Color(0x40D2D2D2); + static Color get borderGrayColor => isDarkMode ? dark.borderGrayColor : const Color(0x332E3039); + static Color get greyTextColor => isDarkMode ? dark.greyTextColor : const Color(0xFF8F9AA3); + static Color get inputLabelTextColor => isDarkMode ? dark.inputLabelTextColor : const Color(0xFF898A8D); + static Color get errorColor => isDarkMode ? dark.errorColor : const Color(0xFFED1C2B); + static Color get warningColor => isDarkMode ? dark.warningColor : const Color(0xFFFFCC00); + static Color get infoColor => isDarkMode ? dark.infoColor : const Color(0xFF0B85F7); + static Color get shimmerBaseColor => isDarkMode ? dark.shimmerBaseColor : const Color(0xFFE0E0E0); + static Color get shimmerHighlightColor => isDarkMode ? dark.shimmerHighlightColor : const Color(0xFFF5F5F5); + + static Color get blackColor => textColor; + static Color get bgScaffoldColor => scaffoldBgColor; + + static const AppColorsDark dark = AppColorsDark(); +} + +class AppColorsDark { + const AppColorsDark(); + Color get scaffoldBgColor => const Color(0xFF191919); + Color get whiteColor => const Color(0xFF1E1E1E); + Color get primaryRedColor => const Color(0xFFDE5C5D); + Color get secondaryLightRedColor => const Color(0xFF3A1015); + Color get textColor => const Color(0xFFFFFFFF); + Color get iconColor => const Color(0xFFFFFFFF); + Color get greyColor => const Color(0xFF2C2C2E); + Color get textColorLight => const Color(0xFFB0B0B0); + Color get dividerColor => const Color(0x33FFFFFF); + Color get borderGrayColor => const Color(0x55ECECEC); + Color get greyTextColor => const Color(0xFF8F9AA3); + Color get inputLabelTextColor => const Color(0xFF9E9E9E); + Color get errorColor => const Color(0xFFD63D48); + Color get warningColor => const Color(0xFFFFCC00); + Color get infoColor => const Color(0xFF4DA6FF); + Color get shimmerBaseColor => const Color(0xFF2C2C2E); + Color get shimmerHighlightColor => const Color(0xFF3A3A3C); +} +``` + +### 8.2 FILE: `lib/theme/app_theme.dart` + +```dart +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:{{DART_PACKAGE}}/theme/colors.dart'; + +class AppTheme { + static ThemeData getTheme(bool isArabic) => ThemeData( + fontFamily: isArabic ? '{{SECONDARY_FONT}}' : '{{PRIMARY_FONT}}', + primarySwatch: Colors.red, + brightness: Brightness.light, + visualDensity: VisualDensity.adaptivePlatformDensity, + pageTransitionsTheme: const PageTransitionsTheme(builders: { + TargetPlatform.android: ZoomPageTransitionsBuilder(), + TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), + }), + canvasColor: Colors.white, + splashColor: Colors.transparent, + appBarTheme: const AppBarTheme(elevation: 0, systemOverlayStyle: SystemUiOverlayStyle.light, surfaceTintColor: Colors.transparent), + ); + + static ThemeData getDarkTheme(bool isArabic) => ThemeData( + fontFamily: isArabic ? '{{SECONDARY_FONT}}' : '{{PRIMARY_FONT}}', + primarySwatch: Colors.red, + brightness: Brightness.dark, + visualDensity: VisualDensity.adaptivePlatformDensity, + pageTransitionsTheme: const PageTransitionsTheme(builders: { + TargetPlatform.android: ZoomPageTransitionsBuilder(), + TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), + }), + canvasColor: AppColors.dark.scaffoldBgColor, + scaffoldBackgroundColor: AppColors.dark.scaffoldBgColor, + splashColor: Colors.transparent, + appBarTheme: AppBarTheme(color: AppColors.dark.scaffoldBgColor, elevation: 0, systemOverlayStyle: SystemUiOverlayStyle.light, surfaceTintColor: Colors.transparent), + ); +} +``` + +--- + +## 9. EXTENSIONS + +### 9.1 FILE: `lib/extensions/int_extensions.dart` + +```dart +import 'package:flutter/material.dart'; + +extension IntExtensions on int { + Widget get height => SizedBox(height: toDouble()); + Widget get width => SizedBox(width: toDouble()); + Widget get divider => Divider(height: toDouble(), thickness: toDouble(), color: const Color(0x30D2D2D2)); +} +``` + +### 9.2 FILE: `lib/extensions/string_extensions.dart` + +```dart +import 'package:flutter/material.dart'; +import 'package:{{DART_PACKAGE}}/core/utils/size_utils.dart'; +import 'package:{{DART_PACKAGE}}/theme/colors.dart'; + +extension CapExtension on String { + String get inCaps => isEmpty ? '' : '${this[0].toUpperCase()}${substring(1)}'; + String get capitalizeFirstOfEach => trim().isEmpty ? '' : trim().toLowerCase().split(' ').map((s) => s.inCaps).join(' '); +} + +extension StringToWidget on String { + Widget _text(double size, {Color? color, FontWeight? fontWeight, bool isBold = false, bool isCenter = false, bool isUnderLine = false, int? maxLines, TextOverflow? overflow, double letterSpacing = 0}) { + return Text(this, + textAlign: isCenter ? TextAlign.center : null, + maxLines: maxLines, + overflow: overflow, + style: TextStyle(fontSize: size.f, fontWeight: fontWeight ?? (isBold ? FontWeight.bold : FontWeight.normal), color: color ?? AppColors.blackColor, letterSpacing: letterSpacing, decoration: isUnderLine ? TextDecoration.underline : null, decorationColor: color ?? AppColors.blackColor), + ); + } + + Widget toText8({Color? color, FontWeight? fontWeight, bool isBold = false, int? maxLines, TextOverflow? overflow}) => _text(8, color: color, fontWeight: fontWeight, isBold: isBold, maxLines: maxLines, overflow: overflow); + Widget toText10({Color? color, FontWeight? fontWeight, bool isBold = false, bool isCenter = false, int? maxLines, TextOverflow? overflow}) => _text(10, color: color, fontWeight: fontWeight, isBold: isBold, isCenter: isCenter, maxLines: maxLines, overflow: overflow); + Widget toText11({Color? color, FontWeight? fontWeight, bool isBold = false, bool isCenter = false, int? maxLines}) => _text(11, color: color, fontWeight: fontWeight, isBold: isBold, isCenter: isCenter, maxLines: maxLines); + Widget toText12({Color? color, FontWeight? fontWeight, bool isBold = false, bool isCenter = false, int? maxLines, TextOverflow? overflow}) => _text(12, color: color, fontWeight: fontWeight, isBold: isBold, isCenter: isCenter, maxLines: maxLines, overflow: overflow); + Widget toText13({Color? color, FontWeight? fontWeight, bool isBold = false, bool isCenter = false, int? maxLines, TextOverflow? overflow}) => _text(13, color: color, fontWeight: fontWeight, isBold: isBold, isCenter: isCenter, maxLines: maxLines, overflow: overflow); + Widget toText14({Color? color, FontWeight? fontWeight, bool isBold = false, bool isCenter = false, int? maxLines, TextOverflow? overflow}) => _text(14, color: color, fontWeight: fontWeight, isBold: isBold, isCenter: isCenter, maxLines: maxLines, overflow: overflow); + Widget toText16({Color? color, FontWeight? fontWeight, bool isBold = false, bool isCenter = false, int? maxLines, TextOverflow? overflow}) => _text(16, color: color, fontWeight: fontWeight, isBold: isBold, isCenter: isCenter, maxLines: maxLines, overflow: overflow); + Widget toText18({Color? color, FontWeight? fontWeight, bool isBold = false, bool isCenter = false, int? maxLines}) => _text(18, color: color, fontWeight: fontWeight, isBold: isBold, isCenter: isCenter, maxLines: maxLines); + Widget toText20({Color? color, FontWeight? fontWeight, bool isBold = false, bool isCenter = false}) => _text(20, color: color, fontWeight: fontWeight, isBold: isBold, isCenter: isCenter); + Widget toText24({Color? color, FontWeight? fontWeight, bool isBold = false, bool isCenter = false}) => _text(24, color: color, fontWeight: fontWeight, isBold: isBold, isCenter: isCenter); + Widget toText30({Color? color, FontWeight? fontWeight, bool isBold = false, bool isCenter = false}) => _text(30, color: color, fontWeight: fontWeight, isBold: isBold, isCenter: isCenter); +} +``` + +### 9.3 FILE: `lib/extensions/widget_extensions.dart` + +```dart +import 'package:flutter/material.dart'; +import 'package:shimmer/shimmer.dart'; +import 'package:{{DART_PACKAGE}}/theme/colors.dart'; + +extension WidgetExtensions on Widget { + Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this); + Widget get expanded => Expanded(child: this); + Widget get center => Center(child: this); + Widget circle(double v) => ClipRRect(borderRadius: BorderRadius.circular(v), child: this); + Widget paddingAll(double v) => Padding(padding: EdgeInsets.all(v), child: this); + Widget paddingSymmetrical(double h, double v) => Padding(padding: EdgeInsets.symmetric(horizontal: h, vertical: v), child: this); + Widget paddingOnly({double left = 0, double right = 0, double top = 0, double bottom = 0}) => Padding(padding: EdgeInsetsDirectional.only(start: left, end: right, top: top, bottom: bottom), child: this); + Widget toShimmer({bool isShow = true}) => isShow ? Shimmer.fromColors(baseColor: AppColors.shimmerBaseColor, highlightColor: AppColors.shimmerHighlightColor, child: this) : this; + Widget objectContainerView({double radius = 15}) => Container( + padding: const EdgeInsets.all(15), + decoration: BoxDecoration(color: AppColors.whiteColor, borderRadius: BorderRadius.circular(radius), boxShadow: [BoxShadow(color: const Color(0xff000000).withOpacity(.15), blurRadius: 26, offset: const Offset(0, -3))]), + child: this, + ); +} +``` + +### 9.4 FILE: `lib/extensions/context_extensions.dart` + +```dart +import 'package:flutter/material.dart'; + +extension ContextUtils on BuildContext { + double get screenHeight => MediaQuery.of(this).size.height; + double get screenWidth => MediaQuery.of(this).size.width; + ThemeData get theme => Theme.of(this); + TextTheme get textTheme => theme.textTheme; +} + +extension ShowBottomSheetExt on BuildContext { + Future showSheet({required Widget child, bool isScrollControlled = true, bool isDismissible = true}) { + return showModalBottomSheet(context: this, isScrollControlled: isScrollControlled, isDismissible: isDismissible, backgroundColor: Colors.transparent, builder: (_) => child); + } +} +``` + +### 9.5 FILE: `lib/extensions/route_extensions.dart` + +```dart +import 'package:flutter/material.dart'; + +extension NavigationExtensions on BuildContext { + void navigateWithName(String routeName, {Object? arguments}) => Navigator.pushNamed(this, routeName, arguments: arguments); + Future navigateReplaceWithName(String routeName, {Object? arguments}) async => await Navigator.pushReplacementNamed(this, routeName, arguments: arguments); + void navigateAndRemoveAll(String routeName) => Navigator.pushNamedAndRemoveUntil(this, routeName, (route) => false); + void pop() => Navigator.of(this).pop(); + void pushTo(Widget page) => Navigator.push(this, MaterialPageRoute(builder: (_) => page)); +} +``` + +--- + +## 10. WIDGETS — Starter Widgets + +### 10.1 FILE: `lib/widgets/buttons/custom_button.dart` + +```dart +import 'package:flutter/material.dart'; +import 'package:{{DART_PACKAGE}}/core/utils/size_utils.dart'; +import 'package:{{DART_PACKAGE}}/theme/colors.dart'; + +class CustomButton extends StatelessWidget { + final String label; + final VoidCallback? onPressed; + final Color? color; + final Color? textColor; + final double? width; + final bool isOutlined; + final bool isLoading; + + const CustomButton({super.key, required this.label, this.onPressed, this.color, this.textColor, this.width, this.isOutlined = false, this.isLoading = false}); + + @override + Widget build(BuildContext context) { + final bg = color ?? AppColors.primaryRedColor; + return SizedBox( + width: width ?? double.infinity, + height: 48.h, + child: isOutlined + ? OutlinedButton(onPressed: isLoading ? null : onPressed, style: OutlinedButton.styleFrom(side: BorderSide(color: bg), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.r))), child: _child(bg)) + : ElevatedButton(onPressed: isLoading ? null : onPressed, style: ElevatedButton.styleFrom(backgroundColor: bg, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.r))), child: _child(textColor ?? Colors.white)), + ); + } + + Widget _child(Color c) => isLoading ? SizedBox(height: 20, width: 20, child: CircularProgressIndicator(strokeWidth: 2, color: c)) : Text(label, style: TextStyle(fontSize: 14.f, fontWeight: FontWeight.w600, color: c)); +} +``` + +### 10.2 FILE: `lib/widgets/routes/fade_page.dart` + +```dart +import 'package:flutter/material.dart'; + +class FadePage extends PageRouteBuilder { + final Widget page; + FadePage({required this.page}) : super( + pageBuilder: (_, __, ___) => page, + transitionsBuilder: (_, a, __, child) => FadeTransition(opacity: a, child: child), + transitionDuration: const Duration(milliseconds: 300), + ); +} +``` + +--- + +## 11. DEPENDENCY INJECTION — `lib/core/dependencies.dart` + +```dart +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:get_it/get_it.dart'; +import 'package:logger/logger.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import 'package:{{DART_PACKAGE}}/core/api/api_client.dart'; +import 'package:{{DART_PACKAGE}}/core/app_state.dart'; +import 'package:{{DART_PACKAGE}}/services/analytics/analytics_service.dart'; +import 'package:{{DART_PACKAGE}}/services/cache_service.dart'; +import 'package:{{DART_PACKAGE}}/services/dialog_service.dart'; +import 'package:{{DART_PACKAGE}}/services/error_handler_service.dart'; +import 'package:{{DART_PACKAGE}}/services/firebase_service.dart'; +import 'package:{{DART_PACKAGE}}/services/logger_service.dart'; +import 'package:{{DART_PACKAGE}}/services/navigation_service.dart'; +import 'package:{{DART_PACKAGE}}/services/notification_service.dart'; + +final GetIt getIt = GetIt.instance; + +class AppDependencies { + static Future addDependencies() async { + final logger = Logger(printer: PrettyPrinter(methodCount: 2, errorMethodCount: 5, lineLength: 1000, colors: true, printEmojis: true)); + + getIt.registerLazySingleton(() => LoggerServiceImp(logger: logger)); + getIt.registerLazySingleton(() => NavigationService()); + getIt.registerLazySingleton(() => AppState(navigationService: getIt())); + getIt.registerLazySingleton(() => GAnalytics()); + getIt.registerLazySingleton(() => DialogServiceImp(navigationService: getIt())); + getIt.registerLazySingleton(() => ErrorHandlerServiceImp(dialogService: getIt(), loggerService: getIt(), navigationService: getIt())); + + final sp = await SharedPreferences.getInstance(); + getIt.registerLazySingleton(() => CacheServiceImp(sharedPreferences: sp, loggerService: getIt())); + getIt.registerLazySingleton(() => ApiClientImp(appState: getIt())); + getIt.registerLazySingleton(() => FirebaseServiceImpl(firebaseMessaging: FirebaseMessaging.instance, loggerService: getIt(), appState: getIt())); + + final flnp = FlutterLocalNotificationsPlugin(); + getIt.registerLazySingleton(() => NotificationServiceImp(flutterLocalNotificationsPlugin: flnp, loggerService: getIt())); + + // ═══ Register feature repos & ViewModels below as you add them ═══ + } +} +``` + +--- + +## 12. ROUTING — `lib/routes/app_routes.dart` + +```dart +import 'package:flutter/material.dart'; +import 'package:{{DART_PACKAGE}}/presentation/home/navigation_screen.dart'; +import 'package:{{DART_PACKAGE}}/splash_page.dart'; + +class AppRoutes { + static const String initialRoute = '/'; + static const String landingScreen = '/landingScreen'; + + // Add route names as you build features: + // static const String loginScreen = '/loginScreen'; + + static Map get routes => { + initialRoute: (_) => const SplashPage(), + landingScreen: (_) => const LandingNavigation(), + }; +} +``` + +--- + +## 13. LOCALIZATION FILES + +### FILE: `assets/langs/en-US.json` + +```json +{ + "appName": "{{APP_NAME}}", + "home": "Home", + "services": "Services", + "medicalFile": "Medical File", + "bookAppointment": "Book Appointment", + "login": "Login", + "register": "Register", + "cancel": "Cancel", + "confirm": "Confirm", + "done": "Done", + "ok": "OK", + "loading": "Loading...", + "noDataAvailable": "No data available", + "noInternetConnection": "No internet connection", + "settings": "Settings", + "language": "Language", + "darkMode": "Dark Mode", + "logout": "Logout", + "search": "Search" +} +``` + +### FILE: `assets/langs/ar-SA.json` + +```json +{ + "appName": "{{APP_NAME}}", + "home": "الرئيسية", + "services": "الخدمات", + "medicalFile": "الملف الطبي", + "bookAppointment": "حجز موعد", + "login": "تسجيل الدخول", + "register": "التسجيل", + "cancel": "إلغاء", + "confirm": "تأكيد", + "done": "تم", + "ok": "حسنا", + "loading": "جاري التحميل...", + "noDataAvailable": "لا توجد بيانات", + "noInternetConnection": "لا يوجد اتصال بالإنترنت", + "settings": "الإعدادات", + "language": "اللغة", + "darkMode": "الوضع الداكن", + "logout": "تسجيل الخروج", + "search": "بحث" +} +``` + +--- + +## 14. PRESENTATION — Starter Screens + +### FILE: `lib/splash_page.dart` + +```dart +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:{{DART_PACKAGE}}/core/api_consts.dart'; +import 'package:{{DART_PACKAGE}}/core/dependencies.dart'; +import 'package:{{DART_PACKAGE}}/presentation/home/navigation_screen.dart'; +import 'package:{{DART_PACKAGE}}/services/notification_service.dart'; +import 'package:{{DART_PACKAGE}}/theme/colors.dart'; +import 'package:{{DART_PACKAGE}}/widgets/routes/fade_page.dart'; + +class SplashPage extends StatefulWidget { + const SplashPage({super.key}); + @override + State createState() => _SplashPageState(); +} + +class _SplashPageState extends State { + @override + void initState() { + super.initState(); + _init(); + } + + Future _init() async { + ApiConsts.setBackendURLs(); + await getIt.get().initialize(); + Timer(const Duration(seconds: 2), () { + Navigator.of(context).pushReplacement(FadePage(page: const LandingNavigation())); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.whiteColor, + body: Center(child: Text('{{APP_NAME}}', style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold, color: AppColors.primaryRedColor))), + ); + } +} +``` + +### FILE: `lib/presentation/home/navigation_screen.dart` + +```dart +import 'package:flutter/material.dart'; +import 'package:{{DART_PACKAGE}}/presentation/home/landing_page.dart'; +import 'package:{{DART_PACKAGE}}/theme/colors.dart'; + +class LandingNavigation extends StatefulWidget { + const LandingNavigation({super.key}); + @override + State createState() => _LandingNavigationState(); +} + +class _LandingNavigationState extends State { + int _idx = 0; + final _pc = PageController(); + + final _pages = const [ + LandingPage(), + Center(child: Text('Medical File')), + Center(child: Text('Book Appointment')), + Center(child: Text('Services')), + ]; + + @override + Widget build(BuildContext context) { + return Scaffold( + body: PageView(controller: _pc, physics: const NeverScrollableScrollPhysics(), children: _pages), + bottomNavigationBar: BottomNavigationBar( + currentIndex: _idx, + type: BottomNavigationBarType.fixed, + selectedItemColor: AppColors.primaryRedColor, + unselectedItemColor: AppColors.greyTextColor, + onTap: (i) { setState(() => _idx = i); _pc.jumpToPage(i); }, + items: const [ + BottomNavigationBarItem(icon: Icon(Icons.home_outlined), activeIcon: Icon(Icons.home), label: 'Home'), + BottomNavigationBarItem(icon: Icon(Icons.folder_outlined), activeIcon: Icon(Icons.folder), label: 'File'), + BottomNavigationBarItem(icon: Icon(Icons.calendar_today_outlined), activeIcon: Icon(Icons.calendar_today), label: 'Book'), + BottomNavigationBarItem(icon: Icon(Icons.grid_view_outlined), activeIcon: Icon(Icons.grid_view), label: 'Services'), + ], + ), + ); + } +} +``` + +### FILE: `lib/presentation/home/landing_page.dart` + +```dart +import 'package:flutter/material.dart'; +import 'package:{{DART_PACKAGE}}/extensions/int_extensions.dart'; +import 'package:{{DART_PACKAGE}}/extensions/string_extensions.dart'; +import 'package:{{DART_PACKAGE}}/theme/colors.dart'; + +class LandingPage extends StatelessWidget { + const LandingPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.scaffoldBgColor, + body: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + 24.height, + 'Welcome'.toText24(isBold: true), + 8.height, + 'What would you like to do today?'.toText14(color: AppColors.greyTextColor), + 24.height, + Expanded(child: Center(child: 'Home content goes here'.toText16(color: AppColors.textColorLight, isCenter: true))), + ]), + ), + ), + ); + } +} +``` + +--- + +## 15. ENTRY POINT — `lib/main.dart` + +```dart +import 'dart:io'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:provider/provider.dart'; +import 'package:sizer/sizer.dart'; +import 'package:{{DART_PACKAGE}}/core/dependencies.dart'; +import 'package:{{DART_PACKAGE}}/routes/app_routes.dart'; +import 'package:{{DART_PACKAGE}}/services/navigation_service.dart'; +import 'package:{{DART_PACKAGE}}/theme/app_theme.dart'; +import 'package:{{DART_PACKAGE}}/theme/colors.dart'; + +class MyHttpOverrides extends HttpOverrides { + @override + HttpClient createHttpClient(SecurityContext? context) => + super.createHttpClient(context)..badCertificateCallback = (cert, host, port) => true; +} + +Future _init() async { + WidgetsFlutterBinding.ensureInitialized(); + await EasyLocalization.ensureInitialized(); + // Uncomment when Firebase is configured: + // await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); + await AppDependencies.addDependencies(); + SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); + HttpOverrides.global = MyHttpOverrides(); +} + +void main() async { + await _init(); + runApp( + EasyLocalization( + supportedLocales: const [Locale('en', 'US'), Locale('ar', 'SA')], + path: 'assets/langs', + fallbackLocale: const Locale('en', 'US'), + child: MultiProvider( + providers: [ + // ═══ Add ChangeNotifierProviders as you build features ═══ + ], + child: const MyApp(), + ), + ), + ); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return SafeArea( + top: false, + bottom: !Platform.isIOS, + child: LayoutBuilder(builder: (context, constraints) { + return Sizer(builder: (context, orientation, deviceType) { + final isArabic = EasyLocalization.of(context)?.locale.languageCode == "ar"; + return MaterialApp( + title: '{{APP_NAME}}', + debugShowCheckedModeBanner: false, + localizationsDelegates: context.localizationDelegates, + supportedLocales: context.supportedLocales, + locale: context.locale, + initialRoute: AppRoutes.initialRoute, + routes: AppRoutes.routes, + theme: AppTheme.getTheme(isArabic), + darkTheme: AppTheme.getDarkTheme(isArabic), + themeMode: AppColors.isDarkMode ? ThemeMode.dark : ThemeMode.light, + navigatorKey: getIt.get().navigatorKey, + builder: (context, child) => MediaQuery( + data: MediaQuery.of(context).copyWith(textScaler: TextScaler.noScaling, alwaysUse24HourFormat: true), + child: child!, + ), + ); + }); + }), + ); + } +} +``` + +--- + +## 16. FEATURE MODULE TEMPLATE + +When asked to **add a new feature**, create these four files. Replace `{{feature}}` (snake_case) and `{{Feature}}` (PascalCase). + +### `lib/features/{{feature}}/{{feature}}_repo.dart` + +```dart +import 'package:dartz/dartz.dart'; +import 'package:{{DART_PACKAGE}}/core/api/api_client.dart'; +import 'package:{{DART_PACKAGE}}/core/common_models/generic_api_model.dart'; +import 'package:{{DART_PACKAGE}}/core/exceptions/api_failure.dart'; +import 'package:{{DART_PACKAGE}}/services/logger_service.dart'; + +abstract class {{Feature}}Repo { + // Future>>> getItems(); +} + +class {{Feature}}RepoImp implements {{Feature}}Repo { + final ApiClient apiClient; + final LoggerService loggerService; + {{Feature}}RepoImp({required this.loggerService, required this.apiClient}); + + // @override + // Future>>> getItems() async { + // Map body = {}; + // try { + // GenericApiModel>? result; + // Failure? failure; + // await apiClient.post('endpoint', body: body, + // onFailure: (e, s, {messageStatus, failureType}) => failure = failureType, + // onSuccess: (r, s, {messageStatus, errorMessage}) { + // try { result = GenericApiModel(data: (r['Key'] as List).map((e) => YourModel.fromJson(e)).toList()); } + // catch (e) { failure = DataParsingFailure(e.toString()); } + // }); + // if (failure != null) return Left(failure!); + // return Right(result!); + // } catch (e) { return Left(UnknownFailure(e.toString())); } + // } +} +``` + +### `lib/features/{{feature}}/{{feature}}_view_model.dart` + +```dart +import 'package:flutter/material.dart'; +import 'package:{{DART_PACKAGE}}/features/{{feature}}/{{feature}}_repo.dart'; +import 'package:{{DART_PACKAGE}}/services/error_handler_service.dart'; +import 'package:{{DART_PACKAGE}}/services/navigation_service.dart'; + +class {{Feature}}ViewModel extends ChangeNotifier { + final {{Feature}}Repo _repo; + final ErrorHandlerService _errorHandler; + final NavigationService _nav; + + {{Feature}}ViewModel({required {{Feature}}Repo repo, required ErrorHandlerService errorHandler, required NavigationService nav}) + : _repo = repo, _errorHandler = errorHandler, _nav = nav; + + bool isLoading = false; + + // void init() { isLoading = true; notifyListeners(); _fetch(); } + // void _fetch() async { + // final r = await _repo.getItems(); + // r.fold((f) { isLoading = false; _errorHandler.handleError(failure: f); notifyListeners(); }, + // (d) { /* items = d.data ?? []; */ isLoading = false; notifyListeners(); }); + // } +} +``` + +### `lib/presentation/{{feature}}/{{feature}}_page.dart` + +```dart +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:{{DART_PACKAGE}}/features/{{feature}}/{{feature}}_view_model.dart'; +import 'package:{{DART_PACKAGE}}/theme/colors.dart'; + +class {{Feature}}Page extends StatefulWidget { + const {{Feature}}Page({super.key}); + @override + State<{{Feature}}Page> createState() => _{{Feature}}PageState(); +} + +class _{{Feature}}PageState extends State<{{Feature}}Page> { + @override + void initState() { + super.initState(); + // Provider.of<{{Feature}}ViewModel>(context, listen: false).init(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.scaffoldBgColor, + appBar: AppBar(title: const Text('{{Feature}}')), + body: Consumer<{{Feature}}ViewModel>( + builder: (_, vm, __) { + if (vm.isLoading) return const Center(child: CircularProgressIndicator()); + return const Center(child: Text('Content here')); + }, + ), + ); + } +} +``` + +### After creating, REGISTER: + +**`dependencies.dart`:** +```dart +getIt.registerLazySingleton<{{Feature}}Repo>(() => {{Feature}}RepoImp(loggerService: getIt(), apiClient: getIt())); +getIt.registerLazySingleton<{{Feature}}ViewModel>(() => {{Feature}}ViewModel(repo: getIt(), errorHandler: getIt(), nav: getIt())); +``` + +**`main.dart` providers list:** +```dart +ChangeNotifierProvider<{{Feature}}ViewModel>(create: (_) => getIt.get<{{Feature}}ViewModel>()), +``` + +**`app_routes.dart`:** +```dart +static const String {{feature}}Page = '/{{feature}}'; +// in routes map: {{feature}}Page: (_) => const {{Feature}}Page(), +``` + +--- + +## 17. RULES — ALWAYS FOLLOW + +1. **Every service/repo = abstract class + implementation.** Never use concrete directly. +2. **All DI in `dependencies.dart`.** Only use `getIt.get()` elsewhere. +3. **All repos return `Future>>`.** +4. **All ViewModels extend `ChangeNotifier`.** Call `notifyListeners()` after state changes. +5. **ViewModels NEVER import widgets.** Use `NavigationService` for navigation. +6. **Pages use `Consumer` or `Provider.of` to read ViewModel state.** +7. **Colors from `AppColors`** — never hardcode hex in widgets. +8. **Text via string extensions** — `'Hello'.toText16()` not `Text('Hello')`. +9. **Spacing via int extensions** — `16.height` not `SizedBox(height: 16)`. +10. **Sizes via responsive extensions** — `16.f`, `16.w`, `16.h`, `16.r`. +11. **Assets via `AppAssets`** — never hardcode paths. +12. **Cache keys in `CacheConst`** — never raw strings for SharedPreferences. +13. **Endpoints in `ApiConsts`** — never hardcode URLs. +14. **Errors through `ErrorHandlerService`** — VMs never show dialogs. +15. **User-facing strings use `.tr()`** from easy_localization. + +--- + +## 18. CHECKLIST — Verify Before Delivering + +- [ ] `flutter pub get` succeeds +- [ ] All imports use `package:{{DART_PACKAGE}}/...` +- [ ] Every file in this spec exists +- [ ] `dependencies.dart` registers all existing services/repos/VMs +- [ ] `main.dart` providers list includes all registered VMs +- [ ] `app_routes.dart` includes all existing pages +- [ ] `pubspec.yaml` declares all existing asset directories +- [ ] Both `en-US.json` and `ar-SA.json` exist +- [ ] No circular imports +- [ ] `AppColors` used everywhere (no raw `Color()` in widgets) +- [ ] Extensions used for text, spacing, widget wrapping + +--- + +*End of specification. Generate all files above. When asked to add a feature, use Section 16.* + diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index f1a0ed0c..71d30372 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -199,8 +199,8 @@ class ApiClientImp implements ApiClient { body['TokenID'] = "@dm!n"; } - body['TokenID'] = "@dm!n"; - body['PatientID'] = 2007395; + // body['TokenID'] = "@dm!n"; + // body['PatientID'] = 2007395; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; // body['SessionID'] = "45786230487560q"; diff --git a/lib/features/lab/lab_view_model.dart b/lib/features/lab/lab_view_model.dart index 07cbbde3..4c689ab7 100644 --- a/lib/features/lab/lab_view_model.dart +++ b/lib/features/lab/lab_view_model.dart @@ -106,6 +106,11 @@ class LabViewModel extends ChangeNotifier { notifyListeners(); } + closeAILabResultAnalysis() { + labOrderResponseByAi = null; + notifyListeners(); + } + void setIsSortByClinic(bool value) { isSortByClinic = value; patientLabOrdersViewList = isSortByClinic ? patientLabOrdersByClinic : patientLabOrdersByHospital; diff --git a/lib/presentation/book_appointment/doctor_profile_page.dart b/lib/presentation/book_appointment/doctor_profile_page.dart index 549b8b0d..9fb6ee1d 100644 --- a/lib/presentation/book_appointment/doctor_profile_page.dart +++ b/lib/presentation/book_appointment/doctor_profile_page.dart @@ -1,4 +1,3 @@ - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -101,18 +100,12 @@ class DoctorProfilePage extends StatelessWidget { children: [ Column( children: [ - Utils.buildSvgWithAssets( - icon: AppAssets.doctor_profile_rating_icon, - width: 48.w, - height: 48.h, - fit: BoxFit.contain, - applyThemeColor: false - ), + Utils.buildSvgWithAssets(icon: AppAssets.doctor_profile_rating_icon, width: 48.w, height: 48.h, fit: BoxFit.contain, applyThemeColor: false), SizedBox(height: 16.h), "Ratings".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), bookAppointmentsViewModel.doctorsProfileResponseModel.decimalDoctorRate .toString() - .toText16(isBold: true, color: AppColors.textColor, isUnderLine: true, decorationColor: AppColors.textColor), + .toText16(isBold: true, color: AppColors.textColor, isUnderLine: true, decorationColor: AppColors.textColor, fontFamily: "Poppins"), ], ).onPress(() { bookAppointmentsViewModel.getDoctorRatingDetails(); @@ -128,18 +121,12 @@ class DoctorProfilePage extends StatelessWidget { SizedBox(width: 36.w), Column( children: [ - Utils.buildSvgWithAssets( - icon: AppAssets.doctor_profile_reviews_icon, - width: 48.w, - height: 48.h, - fit: BoxFit.contain, - applyThemeColor: false - ), + Utils.buildSvgWithAssets(icon: AppAssets.doctor_profile_reviews_icon, width: 48.w, height: 48.h, fit: BoxFit.contain, applyThemeColor: false), SizedBox(height: 16.h), "Reviews".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), bookAppointmentsViewModel.doctorsProfileResponseModel.noOfPatientsRate .toString() - .toText16(isBold: true, color: AppColors.textColor, isUnderLine: true, decorationColor: AppColors.textColor), + .toText16(isBold: true, color: AppColors.textColor, isUnderLine: true, decorationColor: AppColors.textColor, fontFamily: "Poppins"), ], ).onPress(() { bookAppointmentsViewModel.getDoctorRatingDetails(); diff --git a/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart b/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart index af6c97f8..c883c863 100644 --- a/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart +++ b/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart @@ -164,7 +164,7 @@ class LabResultByClinic extends StatelessWidget { padding: EdgeInsets.only(right: 4.w, left: 4.w), child: Utils.buildSvgWithAssets(icon: AppAssets.aiOverView, width: 16.h, height: 16.h, iconColor: Colors.white), ), - LocaleKeys.generateAiAnalysis.tr(context: context).toText16(isBold: true) + LocaleKeys.generateAiAnalysis.tr(context: context).toText16(isBold: true, color: Colors.white) ], ), ).paddingSymmetrical(24.h, 24.h).onPress(() async { diff --git a/lib/presentation/lab/lab_result_via_clinic/ai_analysis_widget.dart b/lib/presentation/lab/lab_result_via_clinic/ai_analysis_widget.dart index 7a477761..2c552bc7 100644 --- a/lib/presentation/lab/lab_result_via_clinic/ai_analysis_widget.dart +++ b/lib/presentation/lab/lab_result_via_clinic/ai_analysis_widget.dart @@ -2,11 +2,14 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/string_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_order_response_by_ai_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/buttons/custom_button.dart'; class AiAnalysisWidget extends StatelessWidget { final LabOrderResponseByAi data; @@ -71,6 +74,14 @@ class AiAnalysisWidget extends StatelessWidget { ), ], ), + SizedBox(height: 16.h), + CustomButton( + height: 50.h, + text: LocaleKeys.close.tr(context: context), + onPressed: () { + getIt.get().closeAILabResultAnalysis(); + }, + ), ], ), ), diff --git a/lib/presentation/lab/lab_results/lab_result_details.dart b/lib/presentation/lab/lab_results/lab_result_details.dart index 8d5d0042..69254f69 100644 --- a/lib/presentation/lab/lab_results/lab_result_details.dart +++ b/lib/presentation/lab/lab_results/lab_result_details.dart @@ -35,97 +35,99 @@ class LabResultDetails extends StatelessWidget { LabViewModel labViewModel = Provider.of(context, listen: false); final appState = getIt.get(); return Scaffold( - body: Column( - children: [ - Expanded( - child: CollapsingListView( - title: LocaleKeys.labResultDetails.tr(context: context), - // aiOverview: () async { - // final _dialogService = getIt.get(); - // await _dialogService.showCommonBottomSheetWithoutH( - // message: LocaleKeys.aiDisclaimer.tr(), - // label: LocaleKeys.consent.tr(), - // okLabel: LocaleKeys.acceptLbl.tr(), - // cancelLabel: LocaleKeys.rejectView.tr(), - // onOkPressed: () { - // context.pop(); - // labViewModel.getAiOverviewSingleLabResult(langId: appState.getLanguageID().toString(), recentLabResult: recentLabResult, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); - // }, - // onCancelPressed: () { - // context.pop(); - // }); - // }, - child: SingleChildScrollView( - child: Column( - spacing: 16.h, - children: [ - LabNameAndStatus(context), - getLabDescription(context), - LabGraph(context), - Selector( - selector: (_, model) => model.labOrderResponseByAi, - builder: (_, aiData, __) { - if (aiData != null) { - return AiAnalysisWidget(data: aiData).paddingOnly(bottom: 16.h); - } - return const SizedBox.shrink(); - }, - ), - ], - ).paddingAll(24.h), + body: Consumer(builder: (context, labVM, child) { + return Column( + children: [ + Expanded( + child: CollapsingListView( + title: LocaleKeys.labResultDetails.tr(context: context), + // aiOverview: () async { + // final _dialogService = getIt.get(); + // await _dialogService.showCommonBottomSheetWithoutH( + // message: LocaleKeys.aiDisclaimer.tr(), + // label: LocaleKeys.consent.tr(), + // okLabel: LocaleKeys.acceptLbl.tr(), + // cancelLabel: LocaleKeys.rejectView.tr(), + // onOkPressed: () { + // context.pop(); + // labViewModel.getAiOverviewSingleLabResult(langId: appState.getLanguageID().toString(), recentLabResult: recentLabResult, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); + // }, + // onCancelPressed: () { + // context.pop(); + // }); + // }, + child: SingleChildScrollView( + child: Column( + spacing: 16.h, + children: [ + LabNameAndStatus(context), + getLabDescription(context), + LabGraph(context), + Selector( + selector: (_, model) => model.labOrderResponseByAi, + builder: (_, aiData, __) { + if (aiData != null) { + return AiAnalysisWidget(data: aiData).paddingOnly(bottom: 16.h); + } + return const SizedBox.shrink(); + }, + ), + ], + ).paddingAll(24.h), + ), ), ), - ), - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.h, - hasShadow: true, - ), - child: Container( - height: 56.h, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12.r), - gradient: LinearGradient( - begin: Alignment.centerLeft, - end: Alignment.centerRight, - stops: [0.236, 1.0], // 53.6% and 100% - colors: [ - Color(0xFF8A38F5), // Transparent - Color(0xFFE20BBB), // Solid #F8F8F8 - ], - ), + labVM.labOrderResponseByAi == null ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.h, + hasShadow: true, ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: EdgeInsets.only(right: 4.w, left: 4.w), - child: Utils.buildSvgWithAssets(icon: AppAssets.aiOverView, width: 16.h, height: 16.h, iconColor: Colors.white), + child: Container( + height: 56.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.r), + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: [0.236, 1.0], // 53.6% and 100% + colors: [ + Color(0xFF8A38F5), // Transparent + Color(0xFFE20BBB), // Solid #F8F8F8 + ], ), - LocaleKeys.generateAiAnalysisResult.tr(context: context).toText16(isBold: true) - ], - ), - ).paddingSymmetrical(24.h, 24.h).onPress(() async { - final _dialogService = getIt.get(); - await _dialogService.showCommonBottomSheetWithoutH( - message: LocaleKeys.aiDisclaimer.tr(), - label: LocaleKeys.consent.tr(), - okLabel: LocaleKeys.acceptLbl.tr(), - cancelLabel: LocaleKeys.rejectView.tr(), - onOkPressed: () { - context.pop(); - labViewModel.getAiOverviewSingleLabResult( - langId: appState.getLanguageID().toString(), recentLabResult: recentLabResult, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); - }, - onCancelPressed: () { - context.pop(); - }); - }), - ), - ], - ), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.only(right: 4.w, left: 4.w), + child: Utils.buildSvgWithAssets(icon: AppAssets.aiOverView, width: 16.h, height: 16.h, iconColor: Colors.white), + ), + LocaleKeys.generateAiAnalysisResult.tr(context: context).toText16(isBold: true, color: Colors.white) + ], + ), + ).paddingSymmetrical(24.h, 24.h).onPress(() async { + final _dialogService = getIt.get(); + await _dialogService.showCommonBottomSheetWithoutH( + message: LocaleKeys.aiDisclaimer.tr(), + label: LocaleKeys.consent.tr(), + okLabel: LocaleKeys.acceptLbl.tr(), + cancelLabel: LocaleKeys.rejectView.tr(), + onOkPressed: () { + context.pop(); + labViewModel.getAiOverviewSingleLabResult( + langId: appState.getLanguageID().toString(), recentLabResult: recentLabResult, loadingText: LocaleKeys.loadingAIAnalysis.tr(context: context)); + }, + onCancelPressed: () { + context.pop(); + }); + }), + ) : SizedBox.shrink(), + ], + ); + }), ); } From 08928ddd289d22b2b592ea79284a9f7b4e4b188f Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 16 Mar 2026 14:32:07 +0300 Subject: [PATCH 06/17] Habib Wallet updates --- assets/langs/translations.json | 6290 +++++++++++++++++ lib/core/api/api_client.dart | 18 +- .../habib_wallet/habib_wallet_view_model.dart | 2 + .../habib_wallet/habib_wallet_page.dart | 12 +- .../ai_analysis_widget.dart | 2 + 5 files changed, 6310 insertions(+), 14 deletions(-) create mode 100644 assets/langs/translations.json diff --git a/assets/langs/translations.json b/assets/langs/translations.json new file mode 100644 index 00000000..9750d779 --- /dev/null +++ b/assets/langs/translations.json @@ -0,0 +1,6290 @@ +{ + "english": { + "en": "English", + "ar": "الإنجليزية" + }, + "arabic": { + "en": "Arabic", + "ar": "العربية" + }, + "login": { + "en": "Login", + "ar": "تسجيل الدخول" + }, + "noDataAvailable": { + "en": "No Data Available", + "ar": "لا توجد بيانات متاحة" + }, + "confirm": { + "en": "Confirm", + "ar": "تأكيد" + }, + "loadingText": { + "en": "Loading, please wait...", + "ar": "جاري التحميل، يرجى الانتظار..." + }, + "kilometerUnit": { + "en": "KM", + "ar": "كم" + }, + "dashboardScreenToolbarTitle": { + "en": "Home", + "ar": "الرئيسية" + }, + "settings": { + "en": "Settings", + "ar": "الإعدادات" + }, + "language": { + "en": "App Language", + "ar": "لغة التطبيق" + }, + "lanEnglish": { + "en": "English", + "ar": "الإنجليزية" + }, + "lanArabic": { + "en": "العربية", + "ar": "العربية" + }, + "cancel": { + "en": "Cancel", + "ar": "إلغاء" + }, + "done": { + "en": "Done", + "ar": "تم" + }, + "replay2": { + "en": "Replay", + "ar": "إعادة التشغيل" + }, + "home": { + "en": "Home", + "ar": "الرئيسية" + }, + "services": { + "en": "SERVICES", + "ar": "الخدمات" + }, + "mySchedule": { + "en": "My Schedule", + "ar": "جدولي" + }, + "logout": { + "en": "Logout", + "ar": "تسجيل الخروج" + }, + "respirationRate": { + "en": "Respiration Rate", + "ar": "معدل التنفس" + }, + "bookAppo": { + "en": "Book Appointment", + "ar": "حجز موعد" + }, + "searchBy": { + "en": "Search By:", + "ar": "البحث بواسطة:" + }, + "clinic": { + "en": "Clinic", + "ar": "عيادة" + }, + "byClinic": { + "en": "By Clinic", + "ar": "حسب العيادة" + }, + "hospital": { + "en": "Hospital", + "ar": "مستشفى" + }, + "byHospital": { + "en": "By Hospital", + "ar": "حسب المستشفى" + }, + "name": { + "en": "Name", + "ar": "الاسم" + }, + "doctor": { + "en": "Doctor", + "ar": "طبيب" + }, + "clinicName": { + "en": "Clinic Name", + "ar": "اسم العيادة" + }, + "hospitalName": { + "en": "Hospital Name", + "ar": "اسم المستشفى" + }, + "noClinicFound": { + "en": "No Clinic Found", + "ar": "لم يتم العثور على عيادة" + }, + "doctorName": { + "en": "Doctor Name", + "ar": "اسم الطبيب" + }, + "nearestAppo": { + "en": "Nearest Appointment", + "ar": "أقرب موعد" + }, + "searchByDocText": { + "en": "Type the name of the doctor to help you find him", + "ar": "اكتب اسم الطبيب لمساعدتك في العثور عليه" + }, + "enterDocName": { + "en": "Enter Doctor name", + "ar": "أدخل اسم الطبيب" + }, + "search": { + "en": "Search", + "ar": "بحث" + }, + "noResultFound": { + "en": "No Result Found", + "ar": "لم يتم العثور على نتائج" + }, + "noSearchResultFound": { + "en": "No Result Found", + "ar": "لم يتم العثور على نتائج" + }, + "pleaseEnterProductName": { + "en": "Please Enter Product Name", + "ar": "يرجى إدخال اسم المنتج" + }, + "bookNow": { + "en": "Book Now", + "ar": "احجز الآن" + }, + "docInfo": { + "en": "Doctor Information", + "ar": "معلومات الطبيب" + }, + "appoInfo": { + "en": "Appointment Information", + "ar": "معلومات الموعد" + }, + "availableAppo": { + "en": "Available Appointments", + "ar": "المواعيد المتاحة" + }, + "gender": { + "en": "Gender", + "ar": "الجنس" + }, + "nationality": { + "en": "Nationality", + "ar": "الجنسية" + }, + "neverWait": { + "en": "Never wait in queue", + "ar": "لا تنتظر في الطابور أبدًا" + }, + "reminderTitle": { + "en": "You have appointment with Dr. ", + "ar": "لديك موعد مع الدكتور." + }, + "appointmentCalendar": { + "en": "Would you like to set a reminder for this appointment in your calendar?", + "ar": "هل ترغب في تعيين تذكير لهذا الموعد في التقويم الخاص بك؟" + }, + "appointmentSuccess": { + "en": "Appointment is successfully booked", + "ar": "تم حجز الموعد بنجاح" + }, + "docQualifications": { + "en": "Doctor Qualifications", + "ar": "مؤهلات الطبيب" + }, + "pressAgain": { + "en": "Press again to exit the app", + "ar": "اضغط مرة أخرى للخروج من التطبيق" + }, + "laserMaxLimitReach": { + "en": "Maximum limit is 90 minutes", + "ar": "الحد الأقصى هو 90 دقيقة" + }, + "confirmAppoHeading": { + "en": "Kindly review your Appointment", + "ar": "يرجى مراجعة موعدك" + }, + "patientInfo": { + "en": "Patient Information", + "ar": "معلومات المريض" + }, + "doctorFilter": { + "en": "Doctors will be filtered based on your gender and age", + "ar": "سيتم تصفية الأطباء بناءً على جنسك وعمرك" + }, + "bookSuccess": { + "en": "Book Success", + "ar": "تم الحجز بنجاح" + }, + "patientShare": { + "en": "Patient Share", + "ar": "نسبة المريض" + }, + "patientShareWithTax": { + "en": "Patient Share with Tax", + "ar": "نسبة المريض مع الضريبة" + }, + "confirmAppo": { + "en": "Confirm Appointment", + "ar": "تأكيد الموعد" + }, + "confirmLiveCare": { + "en": "Confirm LiveCare", + "ar": "تأكيد ال لايف كير" + }, + "waitingForDoctor": { + "en": "Waiting for doctor", + "ar": "في انتظار الطبيب" + }, + "appointment": { + "en": "Appointment", + "ar": "موعد" + }, + "confirmLater": { + "en": "Confirm Later", + "ar": "تأكيد لاحقًا" + }, + "todoList": { + "en": "Todo List", + "ar": "قائمة المهام" + }, + "appoActions": { + "en": "Appointment Actions", + "ar": "إجراءات الموعد" + }, + "date": { + "en": "Date", + "ar": "التاريخ" + }, + "time": { + "en": "Time", + "ar": "الوقت" + }, + "pendingPayment": { + "en": "Pending for payment", + "ar": "معلق للدفع" + }, + "payNow": { + "en": "Pay Now", + "ar": "ادفع الآن" + }, + "viewQR": { + "en": "View QR Code", + "ar": "عرض رمز الاستجابة السريعة" + }, + "instruction": { + "en": "Instructions", + "ar": "تعليمات" + }, + "livecare": { + "en": "LiveCare", + "ar": "لايف كير" + }, + "livecareAppo": { + "en": "LiveCare Appointment", + "ar": "موعد لايف كير" + }, + "agreeTo": { + "en": "I agree to the", + "ar": "أوافق على" + }, + "termsConditoins": { + "en": "Terms and Conditions", + "ar": "الشروط والأحكام" + }, + "cancelAppoMsg": { + "en": "Are you sure you want to cancel this appointment?", + "ar": "هل أنت متأكد أنك تريد إلغاء هذا الموعد؟" + }, + "changePayment": { + "en": "Change Payment Method", + "ar": "تغيير طريقة الدفع" + }, + "upcomingNoAction": { + "en": "No Action Required", + "ar": "لا يتطلب أي إجراء" + }, + "upcomingConfirm": { + "en": "Please confirm the appointment to avoid cancellation", + "ar": "يرجى تأكيد الموعد لتجنب الإلغاء" + }, + "bookSuccessConfirmMore2412": { + "en": "The online payment process will be available 24 hours before the appointment.", + "ar": "ستكون عملية الدفع عبر الإنترنت متاحة قبل 24 ساعة من الموعد." + }, + "upcomingPaymentPending": { + "en": "Online Payment will be Activated before 24 Hours of Appointment Time", + "ar": "سيتم تفعيل الدفع عبر الإنترنت قبل 24 ساعة من موعد الموعد" + }, + "upcomingPaymentNow": { + "en": "Pay Online now to avoid long waiting queue", + "ar": "ادفع عبر الإنترنت الآن لتجنب الانتظار الطويل" + }, + "upcomingQR": { + "en": "Use the QR Code to Check-In in hospital", + "ar": "استخدم رمز الاستجابة السريعة لتسجيل الوصول في المستشفى" + }, + "upcomingVirtual": { + "en": "This is a virtual appointment, Please adhere to the instructions for a seamless experience.", + "ar": "هذا موعد افتراضي، يرجى الالتزام بالتعليمات لتجربة سلسة." + }, + "upcomingLivecare": { + "en": "This is a LiveCare appointment", + "ar": "هذا موعد لايف كير" + }, + "upcomingDetails": { + "en": "More Details", + "ar": "المزيد من التفاصيل" + }, + "reschedule": { + "en": "Reschedule", + "ar": "إعادة جدولة" + }, + "raise": { + "en": "Raise", + "ar": "رفع" + }, + "complaint": { + "en": "Complaint", + "ar": "شكوى" + }, + "add": { + "en": "Add", + "ar": "إضافة" + }, + "reminder": { + "en": "Reminder", + "ar": "تذكير" + }, + "location": { + "en": "Locations", + "ar": "المواقع" + }, + "online": { + "en": "Online", + "ar": "عبر الإنترنت" + }, + "payment": { + "en": "Payment", + "ar": "الدفع" + }, + "onlinePayment": { + "en": "Online", + "ar": "عبر الإنترنت" + }, + "onlinePaymentSubtitle": { + "en": "Payment", + "ar": "الدفع" + }, + "cancelNocaps": { + "en": "Cancel", + "ar": "إلغاء" + }, + "setReminder": { + "en": "Set Reminder", + "ar": "ضبط تذكير" + }, + "nationalIdNumber": { + "en": "National ID Number", + "ar": "رقم الهوية الوطنية" + }, + "medicalFileNumber": { + "en": "Medical File Number", + "ar": "رقم الملف الطبي" + }, + "loginregister": { + "en": "Login / Register", + "ar": "تسجيل الدخول / التسجيل" + }, + "poweredBy": { + "en": "Powered by", + "ar": "مدعوم من" + }, + "welcome": { + "en": "Welcome", + "ar": "مرحبًا" + }, + "welcomeToDrSulaiman": { + "en": "Welcome to Dr. Sulaiman Al Habib Medical Group", + "ar": "مرحباً بكم في مجموعة الدكتور سليمان الحبيب الطبية" + }, + "patientApp": { + "en": "Patient App", + "ar": "تطبيق المريض" + }, + "welcomeText": { + "en": "Dr. Sulaiman Al Habib Mobile Application", + "ar": "تطبيق الدكتور سليمان الحبيب للهاتف المحمول" + }, + "drSulaimanText": { + "en": "Dr. Sulaiman Al Habib", + "ar": "الدكتور سليمان الحبيب" + }, + "welcomeText2": { + "en": "Have you previously visited the hospitals or medical centers of Dr. Sulaiman Al Habib?", + "ar": "هل زرت مستشفيات أو مراكز الدكتور سليمان الحبيب من قبل؟" + }, + "yes": { + "en": "Yes", + "ar": "نعم" + }, + "no": { + "en": "No", + "ar": "لا" + }, + "logintyperadio": { + "en": " Choose from the below options to login to your medical file.", + "ar": "اختر من الخيارات أدناه لتسجيل الدخول إلى ملفك الطبي." + }, + "registernow": { + "en": "Register Now", + "ar": "سجل الآن" + }, + "nationalID": { + "en": "Enter the Identification Number", + "ar": "أدخل رقم الهوية" + }, + "nationalId": { + "en": "National ID", + "ar": "الهوية الوطنية" + }, + "fileNo": { + "en": "File Number", + "ar": "رقم الملف" + }, + "fileno": { + "en": "File No", + "ar": "رقم الملف" + }, + "forgotFileNo": { + "en": "Forgot file Number?", + "ar": "نسيت رقم الملف؟" + }, + "forgotFileNoTitle": { + "en": "Forgot medical file", + "ar": "نسيت الملف الطبي" + }, + "enterNationalId": { + "en": "Please enter mobile number and identification number", + "ar": "يرجى إدخال رقم الهاتف المحمول ورقم الهوية" + }, + "profileInfo": { + "en": "Please enter profile information", + "ar": "يرجى إدخال معلومات الملف الشخصي" + }, + "submit": { + "en": "Submit", + "ar": "إرسال" + }, + "forgotDesc": { + "en": "Enter the mobile number to receive the Medical File Number via SMS", + "ar": "أدخل رقم الهاتف المحمول لاستلام رقم الملف الطبي عبر الرسائل القصيرة" + }, + "dob": { + "en": "Birth Date:", + "ar": "تاريخ الميلاد:" + }, + "hijriDate": { + "en": "Hijri Date", + "ar": "التاريخ الهجري" + }, + "gregorianDate": { + "en": "Gregorian Date", + "ar": "التاريخ الميلادي" + }, + "verifyLoginWith": { + "en": "Please choose one of the following options to verify", + "ar": "يرجى اختيار واحدة من الخيارات التالية للتحقق" + }, + "registerUser": { + "en": "Register", + "ar": "تسجيل" + }, + "verifyWithFingerprint": { + "en": "Biometric", + "ar": "البيومترية" + }, + "verifyWithFaceid": { + "en": "Face ID", + "ar": "معرف الوجه" + }, + "verifyWithSms": { + "en": "SMS", + "ar": "رسالة قصيرة" + }, + "verifyWithWhatsapp": { + "en": "Whatsapp", + "ar": "واتساب" + }, + "verifyThrough": { + "en": "Verify Through", + "ar": "التحقق من خلال" + }, + "lastLogin": { + "en": "LAST LOGIN AT:", + "ar": "آخر تسجيل دخول في:" + }, + "lastLoginWith": { + "en": "VERIFICATION TYPE:", + "ar": "نوع التحقق:" + }, + "verifyFingerprint": { + "en": "To activate the fingerprint login service, please verify data by using one of the following options.", + "ar": "لتفعيل خدمة تسجيل الدخول ببصمة الإصبع، يرجى التحقق من البيانات باستخدام واحدة من الخيارات التالية." + }, + "searchMedicine": { + "en": "Search Medicine", + "ar": "ابحث عن دواء" + }, + "pharmaciesList": { + "en": "Pharmacies List", + "ar": "قائمة الصيدليات" + }, + "searchMedicineHere": { + "en": "Search Medicine Here", + "ar": "ابحث عن دواء هنا" + }, + "description": { + "en": "Description", + "ar": "الوصف" + }, + "howToUse": { + "en": "How to Use", + "ar": "كيفية الاستخدام" + }, + "price": { + "en": "Price", + "ar": "السعر" + }, + "youCanFindItIn": { + "en": "You can find it in", + "ar": "يمكنك العثور عليه في" + }, + "pleaseEnterMedicineName": { + "en": "Please Enter Medicine Name", + "ar": "يرجى إدخال اسم الدواء" + }, + "verificationMessage": { + "en": "Please enter the Verification Code sent to", + "ar": "يرجى إدخال رمز التحقق المرسل إلى" + }, + "validationMessage": { + "en": "The verification code expires in", + "ar": "ينتهي رمز التحقق في" + }, + "notification": { + "en": "Notifications", + "ar": "الإشعارات" + }, + "appSettings": { + "en": "App Settings", + "ar": "إعدادات التطبيق" + }, + "rateApp": { + "en": "Rate Our App", + "ar": "قيم تطبيقنا" + }, + "before": { + "en": "Before", + "ar": "قبل" + }, + "minute": { + "en": "Minutes", + "ar": "دقائق" + }, + "hour": { + "en": "Hour", + "ar": "ساعة" + }, + "reminderSuccess": { + "en": "The reminder has been added successfully", + "ar": "تمت إضافة التذكير بنجاح" + }, + "reminderCancelSuccess": { + "en": "The reminder has been cancelled successfully", + "ar": "تم إلغاء التذكير بنجاح" + }, + "patientShareToDo": { + "en": "Amount before tax: ", + "ar": "المبلغ قبل الضريبة: " + }, + "patientTaxToDo": { + "en": "Tax amount: ", + "ar": "قيمة الضريبة: " + }, + "patientShareTotalToDo": { + "en": "Total amount due: ", + "ar": "إجمالي المبلغ المستحق: " + }, + "paymentMethod": { + "en": "Payment Method", + "ar": "طريقة الدفع" + }, + "noNeedToWaitInLine": { + "en": "No need to stand in line.", + "ar": "لا حاجة للانتظار في الطابور." + }, + "useQRAppoAttend": { + "en": "Use the QR code to register the appointment attendance.", + "ar": "استخدم رمز الاستجابة السريعة لتسجيل حضور الموعد." + }, + "passQRAppoAttend": { + "en": "Pass the QR code through the attendance devices available in the Hospital.", + "ar": "مرر رمز الاستجابة السريعة عبر أجهزة الحضور المتاحة في المستشفى." + }, + "sitWaitingQR": { + "en": "Sit in the waiting rooms until called by the nurse.", + "ar": "اجلس في غرف الانتظار حتى يتم استدعاؤك من قبل الممرضة." + }, + "attendRegisterCode": { + "en": "Attendance registration code", + "ar": "رمز تسجيل الحضور" + }, + "scanQRHospital": { + "en": "Approach the Online Check-In board in the hospital & scan via NFC or QR Code to Check-In", + "ar": "توجّه إلى لوحة تسجيل الوصول الإلكتروني في المستشفى، وقم بالمسح عبر تقنية NFC أو رمز الاستجابة السريعة (QR) لإتمام تسجيل الوصول." + }, + "scanNFC": { + "en": "Scan NFC to Check-In", + "ar": "امسح NFC لتسجيل الوصول" + }, + "sendEmail": { + "en": "Send Email", + "ar": "إرسال بريد إلكتروني" + }, + "success": { + "en": "Done successfully", + "ar": "تم بنجاح" + }, + "emailSentSuccessfully": { + "en": "Email Sent Successfully", + "ar": "تم إرسال البريد الإلكتروني بنجاح" + }, + "emailSentError": { + "en": "Error Sending Email", + "ar": "خطأ في إرسال البريد الإلكتروني" + }, + "close": { + "en": "Close", + "ar": "إغلاق" + }, + "closeIt": { + "en": "Close", + "ar": "أغلق" + }, + "booked": { + "en": "Booked", + "ar": "محجوز" + }, + "confirmed": { + "en": "Confirmed", + "ar": "مؤكد" + }, + "arrived": { + "en": "Arrived", + "ar": "وصل" + }, + "payNowBookSuccess": { + "en": "Pay now via Al Habib App", + "ar": "ادفع الآن عبر تطبيق الحبيب" + }, + "payNowBookSuccesstext1": { + "en": "Pay Now using online payment service from secure payment gateways", + "ar": "ادفع الآن باستخدام خدمة الدفع عبر الإنترنت من بوابات الدفع الآمنة" + }, + "payNowBookSuccesstext2": { + "en": "You can also Pay Later via online payment or in Hospital", + "ar": "يمكنك أيضًا الدفع لاحقًا عبر الدفع الإلكتروني أو في المستشفى." + }, + "payLater": { + "en": "Pay Later", + "ar": "ادفع لاحقًا" + }, + "askDocNotAllowed": { + "en": "This service will be available for last 15 days’ doctor Visit only", + "ar": "هذه الخدمة ستكون متاحة فقط لزيارة الطبيب قبل 15 يومًا" + }, + "moreVerify": { + "en": "More Verification Options", + "ar": "خيارات تحقق إضافية" + }, + "welcomeBack": { + "en": "Welcome back!", + "ar": "مرحبًا بعودتك!" + }, + "accountInfo": { + "en": "Would you like to login with current username?", + "ar": "هل ترغب في تسجيل الدخول باستخدام اسم المستخدم الحالي؟" + }, + "anotherAcc": { + "en": "Use Another Account", + "ar": "استخدم حسابًا آخر" + }, + "next": { + "en": "Next", + "ar": "التالي" + }, + "firstName": { + "en": "First Name", + "ar": "الاسم الأول" + }, + "middleName": { + "en": "Middle Name", + "ar": "اسم الأب" + }, + "lastName": { + "en": "Last Name", + "ar": "اسم العائلة" + }, + "female": { + "en": "Female", + "ar": "أنثى" + }, + "male": { + "en": "Male", + "ar": "ذكر" + }, + "preferredLanguage": { + "en": "Preferred Language *", + "ar": "اللغة المفضلة *" + }, + "locationsRegister": { + "en": "Where do you want to create this file?", + "ar": "أين ترغب في إنشاء هذا الملف؟" + }, + "ksa": { + "en": "KSA", + "ar": "السعودية" + }, + "dubai": { + "en": "Dubai", + "ar": "دبي" + }, + "enterEmail": { + "en": "Please Enter Email", + "ar": "يرجى إدخال البريد الإلكتروني" + }, + "family": { + "en": "My Family", + "ar": "عائلتي" + }, + "familyTitle": { + "en": "My Family Files", + "ar": "ملفات عائلتي" + }, + "myFamily": { + "en": "MY FAMILY", + "ar": "عائلتي" + }, + "addNewMember": { + "en": "Add Family Member", + "ar": "إضافة فرد جديد للعائلة" + }, + "sentRequests": { + "en": "Sent Requests", + "ar": "الطلبات المرسلة" + }, + "recievedRequests": { + "en": "Recieved Requests", + "ar": "الطلبات المستلمة" + }, + "manageFiles": { + "en": "Manage Family Files", + "ar": "إدارة ملفات العائلة" + }, + "oxygenation": { + "en": "Oxygenation", + "ar": "تشبع الأكسجين" + }, + "bodyMeasurements": { + "en": "body Mass Index", + "ar": "مؤشر كتلة الجسم" + }, + "temperature": { + "en": "Temperature", + "ar": "درجة الحرارة" + }, + "pulse": { + "en": "Pulse", + "ar": "النبض" + }, + "respiration": { + "en": "Respiration", + "ar": "التنفس" + }, + "bloodPressure": { + "en": "Blood Pressure", + "ar": "ضغط الدم" + }, + "painScale": { + "en": "Pain Scale", + "ar": "مقياس الألم" + }, + "weight": { + "en": "Weight", + "ar": "الوزن" + }, + "height": { + "en": "Height", + "ar": "الطول" + }, + "heart": { + "en": "Heart Rate", + "ar": "معدل ضربات القلب" + }, + "heightUnit": { + "en": "height unit", + "ar": "وحدة الطول" + }, + "weightUnit": { + "en": "Weight Unit", + "ar": "وحدة الوزن" + }, + "unit": { + "en": "Unit", + "ar": "الوحدة" + }, + "request": { + "en": "Request", + "ar": "طلب" + }, + "memberName": { + "en": "Member Name", + "ar": "اسم العضو" + }, + "switchLogin": { + "en": "Switch", + "ar": "تبديل" + }, + "removeMember": { + "en": "Remove", + "ar": "إزالة" + }, + "allowView": { + "en": "Allow", + "ar": "السماح" + }, + "rejectView": { + "en": "Reject", + "ar": "رفض" + }, + "deleteView": { + "en": "Delete", + "ar": "حذف" + }, + "approvals": { + "en": "Approvals", + "ar": "الموافقات" + }, + "approvalNo": { + "en": "Approval No:", + "ar": "رقم الموافقة:" + }, + "companyName": { + "en": "Company Name:", + "ar": "اسم الشركة:" + }, + "receiptOn": { + "en": "Receipt on:", + "ar": "الإيصال على:" + }, + "expiryDate": { + "en": "Expiry Date:", + "ar": "تاريخ الانتهاء:" + }, + "expiryPoints": { + "en": "Expired", + "ar": "منتهي الصلاحية" + }, + "expiryOn": { + "en": "Expiry on:", + "ar": "ينتهي في:" + }, + "procedureName": { + "en": "Procedure Name:", + "ar": "اسم الإجراء:" + }, + "procedure": { + "en": "Procedure", + "ar": "الإجراء" + }, + "procedureStatus": { + "en": "Procedure Status: ", + "ar": "حالة الإجراء: " + }, + "usageStatus": { + "en": "Usage Status", + "ar": "حالة الاستخدام" + }, + "unusedCount": { + "en": "Unused Count:", + "ar": "عدد غير المستخدم:" + }, + "totalApproval": { + "en": "Total approval unused", + "ar": "إجمالي الموافقة غير المستخدمة" + }, + "category": { + "en": "Category: ", + "ar": "الفئة: " + }, + "expirationDate": { + "en": "Expiration Date: ", + "ar": "تاريخ انتهاء الصلاحية: " + }, + "patientCard": { + "en": "Patient Card ID: ", + "ar": "رقم بطاقة المريض: " + }, + "policyNumber": { + "en": "Policy Number: ", + "ar": "رقم الوثيقة: " + }, + "seeDetails": { + "en": "SEE DETAILS", + "ar": "عرض التفاصيل" + }, + "insuranceCards": { + "en": "Insurance Cards", + "ar": "بطاقات التأمين" + }, + "requestType": { + "en": "Request Type", + "ar": "نوع الطلب" + }, + "registerInfoFamily": { + "en": "How would like to add the new member?", + "ar": "كيف تود إضافة عضو جديد؟" + }, + "removeFamilyMember": { + "en": "Remove this member?", + "ar": "هل تريد إزالة هذا العضو؟" + }, + "myMedicalFile": { + "en": "My Medical File", + "ar": "ملفي الطبي" + }, + "myMedicalFileSubTitle": { + "en": "All your medical records", + "ar": "جميع سجلاتك الطبية" + }, + "viewMore": { + "en": "View More", + "ar": "عرض المزيد" + }, + "homeHealthCareService": { + "en": "Home Health Care Service", + "ar": "خدمة الرعاية الصحية المنزلية" + }, + "onlinePharmacy": { + "en": "Online Pharmacy", + "ar": "الصيدلية الإلكترونية" + }, + "emergencyService": { + "en": "Emergency Service", + "ar": "خدمة الطوارئ" + }, + "onlinePaymentService": { + "en": "Online Payment Service", + "ar": "خدمة الدفع عبر الإنترنت" + }, + "offersAndPackages": { + "en": "Online transfer request", + "ar": "طلب تحويل عبر الإنترنت" + }, + "comprehensiveMedicalCheckup": { + "en": "Comprehensive Medical Check-up", + "ar": "فحص طبي شامل" + }, + "hmgService": { + "en": "HMG Service", + "ar": "خدمة HMG" + }, + "viewAllHabibMedicalService": { + "en": "View All Habib Medical Service", + "ar": "عرض جميع خدمات الحبيب الطبية" + }, + "viewAll": { + "en": "View All", + "ar": "عرض الكل" + }, + "view": { + "en": "View", + "ar": "عرض" + }, + "contactUs": { + "en": "Contact Us", + "ar": "اتصل بنا" + }, + "contactUsLocation": { + "en": "P.O.Box: 91877 - Riyadh 11643, King Fahad Road - Olaya - Kingdom of Saudi Arabia", + "ar": "ص.ب: 91877 - الرياض 11643، طريق الملك فهد - العليا - المملكة العربية السعودية" + }, + "contactUsTime": { + "en": "Saturday - Wednesday 8:00 AM - 10 PM, Thursday 8:00 AM- 8:00 PM, Friday 2:00 PM - 8:00 PM", + "ar": "السبت - الأربعاء 8:00 صباحًا - 10 مساءً، الخميس 8:00 صباحًا- 8:00 مساءً، الجمعة 2:00 مساءً - 8:00 مساءً" + }, + "viewAllWaysReachUs": { + "en": "View All Ways Reach Us", + "ar": "عرض جميع طرق التواصل معنا" + }, + "medicalProfile": { + "en": "Medical Profile", + "ar": "الملف الطبي" + }, + "consultation": { + "en": "Consultation", + "ar": "استشارة" + }, + "logs": { + "en": "Logs", + "ar": "السجلات" + }, + "textToSpeech": { + "en": "How May I Help You?", + "ar": "كيف يمكنني مساعدتك؟" + }, + "locationDialogMessage": { + "en": "Allow the HMG app to access your location will assist you in showing the hospitals according to the nearest to you.", + "ar": "السماح لتطبيق HMG بالوصول إلى موقعك سيساعدك في عرض المستشفيات الأقرب إليك." + }, + "userViewRequester": { + "en": "User Wants to View Your Medical File", + "ar": "يريد المستخدم عرض ملفك الطبي" + }, + "userView": { + "en": "User Can View Your Medical File", + "ar": "يمكن للمستخدم عرض ملفك الطبي" + }, + "parking": { + "en": "Parking", + "ar": "موقف السيارات" + }, + "alhabiServices": { + "en": "HMG Service", + "ar": "خدمة HMG" + }, + "parkingTitle": { + "en": "Car service, car service, service to save parking information, return to it later, 1- By clicking on (Read the code), save the parking data. 2- By clicking on the button (view my car park), it shows you the car’s location in Google Maps. 3- Read another position by pressing the Clear Position Data button.", + "ar": "خدمة السيارة، خدمة السيارة، خدمة لحفظ معلومات الموقف، العودة إليها لاحقًا، 1- من خلال النقر على (قراءة الرمز)، حفظ بيانات الموقف. 2- من خلال النقر على زر (عرض موقف سيارتي)، يظهر لك موقع السيارة في خرائط Google. 3- قراءة موضع آخر بالضغط على زر مسح بيانات الموضع." + }, + "parkingDescription": { + "en": "Parking service is for you to scan the car location so you can find it easy on you way out. click on (scan parking) button to save the parking location, then (show my park) button will appear to show you the way for the parking. if you want to rescan parking QR just click on (Clear My Data).", + "ar": "خدمة المواقف هي لك لمسح موقع السيارة حتى تتمكن من العثور عليها بسهولة عند مغادرتك. انقر على زر (مسح الموقف) لحفظ موقع الموقف، ثم سيظهر زر (عرض موقفي) لإظهار الطريق إلى الموقف. إذا كنت ترغب في إعادة مسح موقف السيارة QR فقط انقر على (مسح بياناتي)." + }, + "appointments": { + "en": "Appointments", + "ar": "المواعيد" + }, + "all2": { + "en": "All", + "ar": "الكل" + }, + "checkinOption": { + "en": "Check-In", + "ar": "تسجيل الوصول" + }, + "readBarcode": { + "en": "Read Barcode", + "ar": "قراءة الكود" + }, + "showMyPark": { + "en": "Show My Park", + "ar": "عرض الموقف" + }, + "clearMyData": { + "en": "Clear My Data", + "ar": "امسح البيانات" + }, + "floor": { + "en": "Floor:", + "ar": "الطابق:" + }, + "gate": { + "en": "Gate:", + "ar": "البوابة:" + }, + "building": { + "en": "Building:", + "ar": "المبنى:" + }, + "branch": { + "en": "Branch:", + "ar": "الفرع:" + }, + "emergencyServices": { + "en": "Emergency Services", + "ar": "خدمات الطوارئ" + }, + "nearester": { + "en": "Nearest ER", + "ar": "أقرب طوارئ" + }, + "locationa": { + "en": "Location", + "ar": "الموقع" + }, + "callNow": { + "en": "Call now", + "ar": "اتصل الآن" + }, + "ambulancerequest": { + "en": "Ambulance", + "ar": "طلب إسعاف" + }, + "requestA": { + "en": "Request", + "ar": "طلب" + }, + "noBookedAppointments": { + "en": "No Booked Appointments", + "ar": "لا توجد مواعيد محجوزة" + }, + "noConfirmedAppointments": { + "en": "No Confirmed Appointments", + "ar": "لا توجد مواعيد مؤكدة" + }, + "noArrivedAppointments": { + "en": "No Arrived Appointments", + "ar": "لا توجد مواعيد تم تسجيل الوصول إليها" + }, + "myAppointmentsList": { + "en": "Appointments", + "ar": "المواعيد" + }, + "myAppointments": { + "en": "My", + "ar": "مواعيدي" + }, + "radiology": { + "en": "Radiology", + "ar": "الأشعة" + }, + "radiologySubtitle": { + "en": "Result", + "ar": "النتيجة" + }, + "lab": { + "en": "Lab", + "ar": "المختبر" + }, + "labSubtitle": { + "en": "Results", + "ar": "النتائج" + }, + "medicines": { + "en": "Medicines", + "ar": "الأدوية" + }, + "medicinesSubtitle": { + "en": "Prescriptions", + "ar": "الوصفات" + }, + "vitalSigns": { + "en": "Vital Signs", + "ar": "علامات حيوية" + }, + "vitalSignsSubTitle": { + "en": "Reports", + "ar": "التقارير" + }, + "myMedical": { + "en": "Active", + "ar": "نشط" + }, + "myMedicalSubtitle": { + "en": "Medications", + "ar": "الأدوية" + }, + "myDoctor": { + "en": "My Doctor", + "ar": "طبيبي" + }, + "myDoctorSubtitle": { + "en": "List", + "ar": "القائمة" + }, + "eye": { + "en": "Eye", + "ar": "العين" + }, + "eyeSubtitle": { + "en": "Measurement", + "ar": "القياس" + }, + "insurance": { + "en": "Insurance", + "ar": "التأمين" + }, + "insuranceSubtitle": { + "en": "Card", + "ar": "البطاقة" + }, + "updateInsurance": { + "en": "Update", + "ar": "تحديث" + }, + "updateInsuranceSubtitle": { + "en": "Insurance", + "ar": "التأمين" + }, + "insuranceApproval": { + "en": "Insurance", + "ar": "التأمين" + }, + "insuranceApprovalSubtitle": { + "en": "Approvals", + "ar": "الموافقات" + }, + "allergies": { + "en": "Allergies", + "ar": "الحساسية" + }, + "allergiesSubtitle": { + "en": "List", + "ar": "القائمة" + }, + "myVaccines": { + "en": "My Vaccines", + "ar": "لقاحاتي" + }, + "myVaccinesSubtitle": { + "en": "List", + "ar": "القائمة" + }, + "medical": { + "en": "Medical", + "ar": "طبي" + }, + "medicalSubtitle": { + "en": "Report", + "ar": "التقرير" + }, + "monthly": { + "en": "Monthly", + "ar": "شهري" + }, + "monthlySubtitle": { + "en": "Report", + "ar": "التقرير" + }, + "sick": { + "en": "Sick", + "ar": "مريض" + }, + "sickSubtitle": { + "en": "Leaves", + "ar": "الإجازات" + }, + "myBalance": { + "en": "My Balance", + "ar": "رصيدي" + }, + "myBalanceSubtitle": { + "en": "Credit", + "ar": "الرصيد" + }, + "patientCall": { + "en": "Patient Call", + "ar": "مكالمة المريض" + }, + "patientCallSubtitle": { + "en": "Service", + "ar": "الخدمة" + }, + "smartWatches": { + "en": "Smart Watches", + "ar": "الساعات الذكية" + }, + "smartWatchesSubtitle": { + "en": "Pairing", + "ar": "الاقتران" + }, + "myTrackers": { + "en": "My Trackers", + "ar": "متعقباتي" + }, + "myTrackersSubtitle": { + "en": "Service", + "ar": "الخدمة" + }, + "askYour": { + "en": "Ask Your", + "ar": "اسأل" + }, + "askYourSubtitle": { + "en": "Doctor", + "ar": "طبيبك" + }, + "internet": { + "en": "Internet", + "ar": "الإنترنت" + }, + "internetSubtitle": { + "en": "Pairing", + "ar": "الاقتران" + }, + "chatbot": { + "en": "Chatbot", + "ar": "الدردشة الآلية" + }, + "chatbotSubtitle": { + "en": "", + "ar": "" + }, + "timeLine": { + "en": "Timeline", + "ar": "الخط الزمني" + }, + "labOrders": { + "en": "Lab Orders", + "ar": "طلبات المختبر" + }, + "billNo": { + "en": "Bill No:", + "ar": "رقم الفاتورة:" + }, + "prescriptions": { + "en": "Prescriptions", + "ar": "الوصفات" + }, + "history": { + "en": "History", + "ar": "التاريخ" + }, + "orderNo": { + "en": "Order No", + "ar": "رقم الطلب" + }, + "orderDetails": { + "en": "Order Details", + "ar": "تفاصيل الطلب" + }, + "deliveryDriverTrack": { + "en": "Driver Tracking", + "ar": "تتبع السائق" + }, + "deliveryLocation": { + "en": "Delivery Location", + "ar": "موقع التسليم" + }, + "driver": { + "en": "Driver", + "ar": "السائق" + }, + "vitalSign": { + "en": "Vital Sign", + "ar": "علامة حيوية" + }, + "monthlyReports": { + "en": "Monthly Reports", + "ar": "تقارير شهرية" + }, + "km": { + "en": "KMs:", + "ar": "كم:" + }, + "km_": { + "en": "KM", + "ar": "كم" + }, + "patientHealthSummaryReport": { + "en": "Patient Health Summary Report", + "ar": "تقرير ملخص صحة المريض" + }, + "toViewTheTermsAndConditions": { + "en": "To View the Terms and Conditions Report", + "ar": "لعرض الشروط والأحكام" + }, + "clickHere": { + "en": "Click here", + "ar": "انقر هنا" + }, + "iAgreeToTheTermsAndConditions": { + "en": "I agree to the terms and conditions ", + "ar": "أوافق على الشروط والأحكام " + }, + "iAgreeToTheTermsAndConditionsSubtitle": { + "en": "I agree to the terms and conditions ", + "ar": "أوافق على الشروط والأحكام " + }, + "save": { + "en": "Save", + "ar": "حفظ" + }, + "userAgreement": { + "en": "User Agreement", + "ar": "اتفاقية المستخدم" + }, + "updateSuccessfully": { + "en": "Update Successfully", + "ar": "تم التحديث بنجاح" + }, + "checkVaccineAvailability": { + "en": "CHECK VACCINE AVAILABILITY", + "ar": "تحقق من توفر اللقاح" + }, + "myVaccinesAvailability": { + "en": "My Vaccines Availability", + "ar": "توفر اللقاحات الخاصة بي" + }, + "paymentService": { + "en": "Payment Service", + "ar": "خدمة الدفع" + }, + "paymentOnline": { + "en": "Service", + "ar": "الخدمة" + }, + "onlineCheckIn": { + "en": "Online Check-In", + "ar": "تسجيل الوصول عبر الإنترنت" + }, + "myBalances": { + "en": "My Balances", + "ar": "رصيدي" + }, + "myWallet": { + "en": "My Wallet", + "ar": "محفظتي" + }, + "balanceAmount": { + "en": "Wallet Amount", + "ar": "مبلغ المحفظة" + }, + "totalBalance": { + "en": "Total Balance", + "ar": "إجمالي الرصيد" + }, + "createAdvancedPayment": { + "en": "Recharge Wallet", + "ar": "إعادة شحن المحفظة" + }, + "advancePayment": { + "en": "Advance Payment", + "ar": "دفع مسبق" + }, + "advancePaymentLabel": { + "en": "You can create and add an Advanced Payment for your account or other accounts.", + "ar": "يمكنك إنشاء وإضافة دفعة مقدمة لحسابك أو حسابات أخرى." + }, + "fileNumber": { + "en": "File Number", + "ar": "رقم الملف" + }, + "amount": { + "en": "Amount *", + "ar": "المبلغ *" + }, + "depositorEmail": { + "en": "Depositor Email *", + "ar": "البريد الإلكتروني للودائع *" + }, + "notes": { + "en": "Notes", + "ar": "ملاحظات" + }, + "selectPatientName": { + "en": "Select Patient Name", + "ar": "اختر اسم المريض" + }, + "selectFamilyPatientName": { + "en": "Family Members", + "ar": "أفراد العائلة" + }, + "selectHospital": { + "en": "Select Hospital", + "ar": "اختر المستشفى" + }, + "selectCity": { + "en": "Select City", + "ar": "اختر المدينة" + }, + "city": { + "en": "City", + "ar": "المدينة" + }, + "distance": { + "en": "Distance", + "ar": "المسافة" + }, + "myAccount": { + "en": "My Account", + "ar": "حسابي" + }, + "otherAccount": { + "en": "Other Account", + "ar": "حساب آخر" + }, + "selectBeneficiary": { + "en": "Select Beneficiary", + "ar": "اختر المستفيد" + }, + "confirmThePayment": { + "en": "Confirm The Payment", + "ar": "تأكيد الدفع" + }, + "depositorName": { + "en": "Depositor Name", + "ar": "اسم مُقدِّم الإيداع" + }, + "mobileNumber": { + "en": "Mobile Number", + "ar": "رقم الجوال" + }, + "phoneNumber": { + "en": "Phone Number", + "ar": "رقم الهاتف" + }, + "country": { + "en": "Country", + "ar": "البلد" + }, + "ok": { + "en": "Ok", + "ar": "حسنا" + }, + "averageWaitingTime": { + "en": "Average Waiting Time:", + "ar": "متوسط وقت الانتظار:" + }, + "waitingTime": { + "en": "Expected waiting time:", + "ar": "وقت الانتظار المتوقع:" + }, + "waterConsumedInWeek": { + "en": "Water consumed in a week", + "ar": "الماء المستهلك في أسبوع" + }, + "waterConsumedInMonth": { + "en": "Water consumed in a month", + "ar": "الماء المستهلك في شهر" + }, + "theVerificationCodeExpiresIn": { + "en": "The Verification Code Expires in", + "ar": "ينتهي رمز التحقق في" + }, + "pleaseEnterTheVerificationCode": { + "en": "Please enter the verification code send to", + "ar": "يرجى إدخال رمز التحقق المرسل إلى" + }, + "eyeMeasurements": { + "en": "Eye Measurements", + "ar": "قياسات العين" + }, + "measurements": { + "en": "Measurements", + "ar": "قياسات" + }, + "classes": { + "en": "Glasses", + "ar": "نظارات" + }, + "contactLens": { + "en": "Contact Lens", + "ar": "عدسات لاصقة" + }, + "rightEye": { + "en": "Right Eye", + "ar": "العين اليمنى" + }, + "sphere": { + "en": "Sphere", + "ar": "الكرة" + }, + "cylinder": { + "en": "Cylinder", + "ar": "الأسطوانة" + }, + "axis": { + "en": "Axis", + "ar": "المحور" + }, + "prism": { + "en": "Prism", + "ar": "الهرم" + }, + "va": { + "en": "VA", + "ar": "VA" + }, + "leftEye": { + "en": "Left Eye", + "ar": "العين اليسرى" + }, + "brand": { + "en": "Brand", + "ar": "العلامة التجارية" + }, + "power": { + "en": "Power", + "ar": "القوة" + }, + "diameter": { + "en": "Diameter", + "ar": "القطر" + }, + "remarks": { + "en": "", + "ar": "ملاحظات: " + }, + "activeMedications": { + "en": "Active Medications", + "ar": "الأدوية النشطة" + }, + "expDate": { + "en": "Active Exp Date :", + "ar": "تاريخ انتهاء الصلاحية:" + }, + "route": { + "en": "", + "ar": "الطريق" + }, + "frequency": { + "en": "", + "ar": "التكرار" + }, + "dailyQuantity": { + "en": "Daily Quantity :", + "ar": "الكمية اليومية:" + }, + "addReminder": { + "en": "Add Reminder", + "ar": "إضافة تذكير" + }, + "cancelReminder": { + "en": "Cancel Reminder", + "ar": "إلغاء التذكير" + }, + "reminderDes": { + "en": "Please select treatment start day and time to be notified when it's time to take the medicine", + "ar": "يرجى تحديد يوم ووقت بدء العلاج ليتم إعلامك عندما يحين وقت تناول الدواء" + }, + "pleaseSelectAllQuestionToContinue": { + "en": "Please answer all questions to continue...", + "ar": "يرجى الإجابة على جميع الأسئلة للمتابعة..." + }, + "startDay": { + "en": "Start Day", + "ar": "يوم البدء" + }, + "endDay": { + "en": "End Day", + "ar": "يوم الانتهاء" + }, + "days": { + "en": "Days ", + "ar": "أيام " + }, + "pleaseVerify": { + "en": "Please Verify ", + "ar": "يرجى التحقق " + }, + "scheduleTime": { + "en": "Schedule time", + "ar": "وقت الجدولة" + }, + "askDoctor": { + "en": "Ask Doctor", + "ar": "اسأل الطبيب" + }, + "doctorResponses": { + "en": "Doctor Responses", + "ar": "ردود الطبيب" + }, + "ne_w": { + "en": "New", + "ar": "جديد" + }, + "all": { + "en": "All", + "ar": "الكل" + }, + "dailyWater": { + "en": "Daily Water Check", + "ar": "متابعة الماء اليومية" + }, + "questionHere": { + "en": "Enter the question here...", + "ar": "أدخل السؤال هنا..." + }, + "viewDoctorResponses": { + "en": "View Doctor Responses", + "ar": "عرض ردود الطبيب" + }, + "serviceInformationButton": { + "en": "LOGIN / REGISTER", + "ar": "تسجيل الدخول / التسجيل" + }, + "serviceInformationTitle": { + "en": "Service Information", + "ar": "معلومات الخدمة" + }, + "serviceInformation": { + "en": "Service Information", + "ar": "معلومات الخدمة" + }, + "homeHealthCare": { + "en": "Home Health Care", + "ar": "الرعاية الصحية المنزلية" + }, + "noAppointmentAvailable": { + "en": "No Available Appointments", + "ar": "لا توجد مواعيد متاحة" + }, + "homeHealthCareText": { + "en": "This service provides a set of home health care services, continuous and comprehensive follow-up in their places of residence for those who cannot access health facilities, such as (laboratory analyzes - radiology - vaccinations - physical therapy), etc.", + "ar": "تقدم هذه الخدمة مجموعة من خدمات الرعاية الصحية المنزلية، والمتابعة المستمرة والشاملة في أماكن إقامتهم لأولئك الذين لا يمكنهم الوصول إلى المرافق الصحية، مثل (تحليلات المختبر - الأشعة - التطعيمات - العلاج الطبيعي)، إلخ." + }, + "loginRegister": { + "en": "Login/Register", + "ar": "تسجيل الدخول / التسجيل" + }, + "orderLog": { + "en": "Order Log", + "ar": "سجل الطلب" + }, + "infoLab": { + "en": "This service allows you to view the results of all laboratory tests performed in Al Habib Medical Group as well as sending the report via e-mail.", + "ar": "تتيح لك هذه الخدمة عرض نتائج جميع الفحوصات المخبرية التي أجريت في مجموعة الحبيب الطبية بالإضافة إلى إرسال التقرير عبر البريد الإلكتروني." + }, + "infoRadiology": { + "en": "This service allows you to view the reports and photos of radiology in Al Habib Medical Group as well as send the report by e-mail.", + "ar": "تتيح لك هذه الخدمة عرض تقارير وصور الأشعة في مجموعة الحبيب الطبية بالإضافة إلى إرسال التقرير عبر البريد الإلكتروني." + }, + "noReviewsAvailable": { + "en": "No Reviews Available", + "ar": "لا توجد تقييمات متاحة" + }, + "noLocationAvailable": { + "en": "No Location Available", + "ar": "لا توجد مواقع متاحة" + }, + "orders": { + "en": "Orders", + "ar": "الطلبات" + }, + "lakum": { + "en": "", + "ar": "لكم" + }, + "lakumMsg": { + "en": "", + "ar": "لا توجد تفاصيل عن النقاط" + }, + "lakumPoint": { + "en": "Lakum Points", + "ar": "نقاط لكم" + }, + "wishlist": { + "en": "Wishlist", + "ar": "قائمة الرغبات" + }, + "products": { + "en": "Products", + "ar": "المنتجات" + }, + "reviews": { + "en": "Reviews", + "ar": "التقييمات" + }, + "brands": { + "en": "Brands", + "ar": "العلامات التجارية" + }, + "productDetails": { + "en": "Product Details", + "ar": "تفاصيل المنتج" + }, + "medicationRefill": { + "en": "Medication Refill", + "ar": "إعادة تعبئة الدواء" + }, + "pillReminder": { + "en": "Pill Reminder", + "ar": "تذكير بالدواء" + }, + "shippingAddresses": { + "en": "Shipping Addresses", + "ar": "عناوين الشحن" + }, + "reachUs": { + "en": "Reach Us", + "ar": "تواصل معنا" + }, + "ourLocations": { + "en": "Our Locations", + "ar": "مواقعنا" + }, + "edit": { + "en": "Edit", + "ar": "تعديل" + }, + "whatsApp": { + "en": "Whats App", + "ar": "واتساب" + }, + "phone": { + "en": "Phone", + "ar": "الهاتف" + }, + "delete": { + "en": "Delete", + "ar": "حذف" + }, + "deleteAddress": { + "en": "Are you sure want to delete", + "ar": "هل أنت متأكد أنك تريد الحذف" + }, + "deletedAddres": { + "en": "Address has been deleted", + "ar": "تم حذف العنوان" + }, + "addAddress": { + "en": "ADD A NEW ADDRESS", + "ar": "إضافة عنوان جديد" + }, + "addNewAddress": { + "en": "Add New Address", + "ar": "إضافة عنوان جديد" + }, + "order": { + "en": "My Order", + "ar": "طلبي" + }, + "delivered": { + "en": "Delivered", + "ar": "تم التوصيل" + }, + "pending": { + "en": "Pending", + "ar": "قيد الانتظار" + }, + "enterNameHere": { + "en": "Enter Your Name", + "ar": "أدخل اسمك هنا" + }, + "processing": { + "en": "Processing", + "ar": "جاري المعالجة" + }, + "cancelled": { + "en": "Cancelled", + "ar": "ملغى" + }, + "writeReview": { + "en": "Write Review", + "ar": "اكتب تقييمًا" + }, + "shareReview": { + "en": "SHARE REVIEW", + "ar": "شارك التقييم" + }, + "review": { + "en": " reviews", + "ar": " التقييمات" + }, + "viewMedicalFile": { + "en": "View Details", + "ar": "عرض التفاصيل" + }, + "viewAllServices": { + "en": "View All Services", + "ar": "عرض جميع الخدمات" + }, + "medicalFile": { + "en": "Medical File", + "ar": "الملف الطبي" + }, + "verified": { + "en": "Verified", + "ar": "تم التحقق" + }, + "checkup": { + "en": "Checkup", + "ar": "فحص" + }, + "hhcHome": { + "en": "Home", + "ar": "الرئيسية" + }, + "refferal": { + "en": "E-Refferal", + "ar": "إحالة إلكترونية" + }, + "refferalTitle": { + "en": "E-Refferal", + "ar": "إحالة إلكترونية" + }, + "refferalSubTitle": { + "en": "Service", + "ar": "الخدمة" + }, + "healthCare": { + "en": "Health Care", + "ar": "الرعاية الصحية" + }, + "emergency": { + "en": "Emergency", + "ar": "حالة طوارئ" + }, + "erservices": { + "en": "Emergency", + "ar": "خدمات الطوارئ" + }, + "services2": { + "en": "Services", + "ar": "الخدمات" + }, + "cantSeeProfile": { + "en": "To view your medical profile, please log in or register now", + "ar": "لرؤية ملفك الطبي، يرجى تسجيل الدخول أو التسجيل الآن" + }, + "loginRegisterNow": { + "en": "Login or Register Now", + "ar": "تسجيل الدخول أو التسجيل الآن" + }, + "hmgPharmacy": { + "en": "HMG Pharmacy", + "ar": "صيدلية مجموعة الحبيب الطبية" + }, + "ecommerceSolution": { + "en": "Ecommerce Solution", + "ar": "حلول التجارة الإلكترونية" + }, + "comprehensive": { + "en": "Comprehensive", + "ar": "شامل" + }, + "onlineConsulting": { + "en": "Online Consulting", + "ar": "استشارات عبر الإنترنت" + }, + "pendingOrder": { + "en": " PENDING", + "ar": " قيد الانتظار" + }, + "deliveredOrder": { + "en": " DELIVERED", + "ar": " تم التوصيل" + }, + "processingOrder": { + "en": " PROCESSING", + "ar": " جارٍ المعالجة" + }, + "cancelledOrder": { + "en": " CANCELLED", + "ar": " ملغى" + }, + "compare": { + "en": " Compare", + "ar": " قارن" + }, + "medicationsRefill": { + "en": " Medication Refill", + "ar": " إعادة تعبئة الأدوية" + }, + "recommended": { + "en": " Recommended for You", + "ar": " موصى به لك" + }, + "myPrescription": { + "en": " My Prescriptions", + "ar": " وصفتي" + }, + "quantity": { + "en": " QTY ", + "ar": " الكمية " + }, + "reviewAppointment": { + "en": " Review Appointment ", + "ar": " مراجعة الموعد " + }, + "backMyAccount": { + "en": "BACK TO MY ACCOUNT ", + "ar": "العودة إلى حسابي " + }, + "reviewSuccessful": { + "en": "Review Successful", + "ar": "تمت مراجعة الطلب بنجاح" + }, + "reviewShared": { + "en": "Your review has been shared on product review section", + "ar": "تمت مشاركة تقييمك في قسم تقييم المنتج" + }, + "reviewComment": { + "en": "Your reviews help other to choose better product", + "ar": "تساعد تقييماتك الآخرين على اختيار منتج أفضل" + }, + "shippedMethod": { + "en": "SHIP BY:", + "ar": "الشحن بواسطة:" + }, + "orderDetail": { + "en": "Order Details", + "ar": "تفاصيل الطلب" + }, + "orderSummary": { + "en": "Order Summary", + "ar": "ملخص الطلب" + }, + "subtotal": { + "en": "Subtotal", + "ar": "المجموع الفرعي" + }, + "shipping": { + "en": "Shipping", + "ar": "الشحن" + }, + "shipBy": { + "en": "SHIP BY:", + "ar": "الشحن بواسطة:" + }, + "lakumPoints": { + "en": "Lakum Points", + "ar": "نقاط لكم" + }, + "useLakumPoints": { + "en": "Use Lakum points", + "ar": "استخدم نقاط لكم" + }, + "use": { + "en": "USE", + "ar": "استخدم" + }, + "proceedPay": { + "en": "PROCEED TO PAY", + "ar": "المتابعة للدفع" + }, + "vat": { + "en": "VAT (15%)", + "ar": "ضريبة القيمة المضافة (15%)" + }, + "inclusiveVat": { + "en": "(inclusive VAT)", + "ar": "(شاملة ضريبة القيمة المضافة)" + }, + "items": { + "en": "item(s)", + "ar": "عنصر(عناصر)" + }, + "checkOut": { + "en": "CHECK OUT", + "ar": "الدفع" + }, + "sar": { + "en": "SAR", + "ar": "ريال سعودي" + }, + "aed": { + "en": "AED", + "ar": "درهم إماراتي" + }, + "payOnline": { + "en": "PAY ONLINE", + "ar": "الدفع عبر الإنترنت" + }, + "cancelOrder": { + "en": "CANCEL ORDER", + "ar": "إلغاء الطلب" + }, + "confirmAddress": { + "en": "CONFIRM ADDRESS ", + "ar": "تأكيد العنوان " + }, + "confirmLocation": { + "en": "CONFIRM LOCATION ", + "ar": "أكد الموقع " + }, + "conditionsHMG": { + "en": "Terms & Conditions ", + "ar": "الشروط والأحكام " + }, + "conditions": { + "en": "Terms & Conditions of Lakum", + "ar": "الشروط والأحكام لكوم" + }, + "confirmDeleteMsg": { + "en": "Are you sure! want to delete ", + "ar": "هل أنت متأكد! تريد الحذف " + }, + "confirmDelete": { + "en": "DELETE", + "ar": "حذف" + }, + "confirmCancellation": { + "en": "Are you sure! want to cancel this order ", + "ar": "هل أنت متأكد! تريد إلغاء هذا الطلب " + }, + "orderNumber": { + "en": "Order#: ", + "ar": "رقم الطلب: " + }, + "orderDate": { + "en": "Date", + "ar": "التاريخ" + }, + "itemsNo": { + "en": "items(s)", + "ar": "عنصر(عناصر)" + }, + "noOrder": { + "en": "You Don't have any orders.", + "ar": "ليس لديك أي طلبات." + }, + "noResult": { + "en": "No Result.", + "ar": "لا توجد نتيجة." + }, + "nonRecommended": { + "en": "No Recommended Products.", + "ar": "لا توجد منتجات موصى بها." + }, + "termsService": { + "en": "Terms of Service", + "ar": "شروط الخدمة" + }, + "beforeusing": { + "en": "Before using the checkup, please read Terms of Service.", + "ar": "قبل استخدام الفحص، يرجى قراءة شروط الخدمة." + }, + "accept": { + "en": "I read and accept Terms of Service and Privacy Policy", + "ar": "أقرأ وأقبل شروط الخدمة وسياسة الخصوصية" + }, + "dataSafeInfo": { + "en": "Information that you provide is anonymous and not shared with anyone.", + "ar": "المعلومات التي تقدمها مجهولة الهوية وليست مشتركة مع أي شخص." + }, + "dataSafe": { + "en": " Your data is safe.", + "ar": " بياناتك آمنة." + }, + "informational": { + "en": "Checkup is for informational purposes and is not a qualified medical opinion", + "ar": "الفحص لأغراض معلوماتية وليس رأيًا طبيًا مؤهلاً" + }, + "notUseInEmerbency": { + "en": "Do not use in emergencies.", + "ar": "لا تستخدم في حالات الطوارئ." + }, + "notUseInEmerbencyDetails": { + "en": "In case of health emergency, ", + "ar": "في حالة الطوارئ الصحية، " + }, + "notUseInEmerbencyDetailsCall": { + "en": "call the nearest emergency number immediately", + "ar": "اتصل بأقرب رقم طوارئ على الفور" + }, + "checkDiagnosis": { + "en": "Checkup is not a diagnosis.", + "ar": "الفحص ليس تشخيصًا." + }, + "remeberthat": { + "en": "Remember that", + "ar": "تذكر أن" + }, + "loginToUseService": { + "en": "You need to login to use this service", + "ar": "تحتاج إلى تسجيل الدخول لاستخدام هذه الخدمة" + }, + "offersAndPromotions": { + "en": "OFFERS & SPECIAL PROMOTIONS", + "ar": "عروض وترويجيات خاصة" + }, + "offers": { + "en": "OFFERS", + "ar": "عروض" + }, + "myPrescriptions": { + "en": "MY PRESCRIPTIONS", + "ar": "وصفاتي" + }, + "searchAndScanMedication": { + "en": "SEARCH & SCAN FOR MEDICATION", + "ar": "البحث والمسح الضوئي للدواء" + }, + "shopByBrands": { + "en": "Shop by Brands", + "ar": "تسوق حسب العلامات التجارية" + }, + "recentlyViewed": { + "en": "Recently Viewed", + "ar": "تمت مشاهدته مؤخرًا" + }, + "bestSellers": { + "en": "Best Seller", + "ar": "الأكثر مبيعًا" + }, + "deleteAllItems": { + "en": "Delete All Items", + "ar": "حذف جميع العناصر" + }, + "total": { + "en": "Total", + "ar": "الإجمالي" + }, + "totalWithColonRight": { + "en": "Total:", + "ar": "الإجمالي:" + }, + "selectAddress": { + "en": "Select Address", + "ar": "اختر العنوان" + }, + "shippingAddress": { + "en": "SHIPPING ADDRESS", + "ar": "عنوان الشحن" + }, + "changeAddress": { + "en": "Change Address", + "ar": "تغيير العنوان" + }, + "selectPaymentOption": { + "en": "Select Payment Option", + "ar": "اختر طريقة الدفع" + }, + "selectTamaraPlan": { + "en": "Select Tamara Payment Plan", + "ar": "اختر خطة دفع تمارا" + }, + "changeMethod": { + "en": "Change Method", + "ar": "تغيير الطريقة" + }, + "reviewOrder": { + "en": "Review Order", + "ar": "مراجعة الطلب" + }, + "active": { + "en": "Active", + "ar": "نشط" + }, + "inactive": { + "en": "InActive", + "ar": "غير نشط" + }, + "balance": { + "en": "Balance", + "ar": "الرصيد" + }, + "gained": { + "en": "GAINED", + "ar": "المكتسب" + }, + "consumed": { + "en": "Consumed", + "ar": "المستهلك" + }, + "transferred": { + "en": "Transferred", + "ar": "المحول" + }, + "riyal": { + "en": "RIYAL", + "ar": "ريال" + }, + "membersince": { + "en": "MEMBER SINCE", + "ar": "عضو منذ" + }, + "identification": { + "en": "Identification Number", + "ar": "رقم الهوية" + }, + "lakumMobile": { + "en": "Mobile Number", + "ar": "رقم الجوال" + }, + "waitinggained": { + "en": "Waiting gained", + "ar": "انتظار المكتسب" + }, + "expired": { + "en": "Expired", + "ar": "منتهي" + }, + "willBeExpired": { + "en": "Will Be Expired", + "ar": "سينتهي" + }, + "activateLAKUMAccount": { + "en": "Activate LAKUM Account", + "ar": "تفعيل حساب لكم" + }, + "checkBeneficiary": { + "en": "CHECK BENEFICIARY", + "ar": "تحقق من المستفيد" + }, + "beneficiaryName": { + "en": "Beneficiary Name", + "ar": "اسم المستفيد" + }, + "accountActivation": { + "en": "Account Activation", + "ar": "تفعيل الحساب" + }, + "lakumTransfer": { + "en": "Lakum Transfer", + "ar": "تحويل لكم" + }, + "acceptLbl": { + "en": "Accept", + "ar": "قبول" + }, + "declineLbl": { + "en": "Decline", + "ar": "رفض" + }, + "selectGender": { + "en": "Select Gender", + "ar": "اختر الجنس" + }, + "iAmA": { + "en": "I am a ...", + "ar": "أنا ..." + }, + "selectAge": { + "en": "Select Your Age", + "ar": "اختر عمرك" + }, + "select": { + "en": "Select", + "ar": "اختر" + }, + "iAm": { + "en": "I am", + "ar": "أنا" + }, + "yearsOld": { + "en": "years old", + "ar": "سنوات" + }, + "dragPoint": { + "en": "Drag point to change your age", + "ar": "اسحب النقطة لتغيير عمرك" + }, + "refine": { + "en": "Refine", + "ar": "تنقيح" + }, + "subGroup": { + "en": "Subgroup", + "ar": "مجموعة فرعية" + }, + "max": { + "en": "Max", + "ar": "الحد الأقصى" + }, + "compeleteOrderMsg": { + "en": "Order has been placed successfully!!", + "ar": "تم تقديم الطلب بنجاح!!" + }, + "addToCompareMsg": { + "en": "You have added a product to the Compare list", + "ar": "لقد أضفت منتجًا إلى قائمة المقارنة" + }, + "itInListMsg": { + "en": "Item is already in the list", + "ar": "العنصر موجود بالفعل في القائمة" + }, + "compareListFull": { + "en": "Your compare list is full", + "ar": "قائمة المقارنة ممتلئة" + }, + "addQuantity": { + "en": "You should add quantity", + "ar": "يجب عليك إضافة الكمية" + }, + "addToCartMsg": { + "en": "You have added a product to the cart", + "ar": "لقد أضفت منتجًا إلى عربة التسوق" + }, + "addToWishlistMsg": { + "en": "You have added a product to the Wishlist", + "ar": "لقد أضفت منتجًا إلى قائمة الرغبات" + }, + "notifyMeMsg": { + "en": "You will be notified when product available", + "ar": "سوف يتم إبلاغك عند توفر المنتج" + }, + "removeFromWishlistMsg": { + "en": "You have removed a product from the Wishlist", + "ar": "لقد أزلت منتجًا من قائمة الرغبات" + }, + "min": { + "en": "Min", + "ar": "الحد الأدنى" + }, + "reset": { + "en": "Reset", + "ar": "إعادة تعيين" + }, + "apply": { + "en": "Apply", + "ar": "تطبيق" + }, + "viewCategorise": { + "en": "View All Categories", + "ar": "عرض جميع الفئات" + }, + "viewSubCategorise": { + "en": "View All Sub Categories", + "ar": "عرض جميع الفئات الفرعية" + }, + "categorise": { + "en": "Categories", + "ar": "الفئات" + }, + "wishList": { + "en": "WishList", + "ar": "قائمة الرغبات" + }, + "cart": { + "en": "Cart", + "ar": "عربة التسوق" + }, + "alhabibapp": { + "en": "Al Habib app", + "ar": "تطبيق الحبيب" + }, + "searchProductHere": { + "en": "Search Product here", + "ar": "ابحث عن المنتج هنا" + }, + "hhcNotAuthMsg": { + "en": "This service provides a set of home health care services, continuous and comprehensive follow-up in their places of residence for those who cannot access health facilities, such as (laboratory analyzes - radiology - vaccinations - physical therapy), etc.", + "ar": "تقدم هذه الخدمة مجموعة من خدمات الرعاية الصحية المنزلية، والمتابعة المستمرة والشاملة في أماكن إقامتهم لأولئك الذين لا يمكنهم الوصول إلى المرافق الصحية، مثل (تحليلات المختبر - الأشعة - التطعيمات - العلاج الطبيعي)، إلخ." + }, + "email": { + "en": "Email *", + "ar": "البريد الإلكتروني *" + }, + "book": { + "en": "Book", + "ar": "احجز" + }, + "appointmentLabel": { + "en": "Appointment", + "ar": "موعد" + }, + "bloodType": { + "en": "Blood Type", + "ar": "فصيلة الدم" + }, + "maritalStatus": { + "en": "Marital status", + "ar": "الحالة الاجتماعية" + }, + "general": { + "en": "General", + "ar": "عام" + }, + "profile": { + "en": "My Profile", + "ar": "ملفي" + }, + "notifications": { + "en": "Notifications", + "ar": "إشعارات" + }, + "notificationDetails": { + "en": "Notification Details", + "ar": "تفاصيل الإشعار" + }, + "notificationDetailsa": { + "en": "Notification Details", + "ar": "تفاصيل الإشعار" + }, + "infoMyDoctor": { + "en": "This service allows you to see all the doctors you have visited in Al Habib Medical Group, and through this service:", + "ar": "تتيح لك هذه الخدمة رؤية جميع الأطباء الذين زرتهم في مجموعة الحبيب الطبية، ومن خلال هذه الخدمة:" + }, + "infoPrescriptions": { + "en": "This service allows you to view all the medical prescriptions issued by Al Habib Medical Group, and through this service, you can:", + "ar": "تتيح لك هذه الخدمة عرض جميع الوصفات الطبية التي أصدرتها مجموعة الحبيب الطبية، ومن خلال هذه الخدمة، يمكنك:" + }, + "infoInsuranceCards": { + "en": "This service allows you to view all the insurance cards that recorded during your visits to Al Habib Medical Group in addition to:", + "ar": "تتيح لك هذه الخدمة عرض جميع بطاقات التأمين التي تم تسجيلها خلال زياراتك لمجموعة الحبيب الطبية بالإضافة إلى:" + }, + "infoAllergies": { + "en": "This service allows you to view all types of allergies recorded during your visits to Al Habib Medical Group.", + "ar": "تتيح لك هذه الخدمة عرض جميع أنواع الحساسية المسجلة خلال زياراتك لمجموعة الحبيب الطبية." + }, + "infoSickLeaves": { + "en": "This service allows you to view all sick leaves that were taken in Al Habib Medical Group in addition to:", + "ar": "تتيح لك هذه الخدمة عرض جميع الاجازات المرضيه التي تم أخذها في مجموعة الحبيب الطبية بالإضافة إلى:" + }, + "infoApprovals": { + "en": "This service allows you to view all approvals requests that have been sent to the insurance companies in addition to:", + "ar": "تتيح لك هذه الخدمة عرض جميع طلبات الموافقة التي تم إرسالها إلى شركات التأمين بالإضافة إلى:" + }, + "infoMonthReport": { + "en": "Upon activation of this service, the system will send a monthly report automatically to the registered email which lists the vital signs and the results for the last visits made in AlHabib Medical Group.", + "ar": "عند تفعيل هذه الخدمة، سيقوم النظام بإرسال تقرير شهري تلقائيًا إلى البريد الإلكتروني المسجل يتضمن العلامات الحيوية والنتائج لآخر الزيارات التي تمت في مجموعة الحبيب الطبية." + }, + "languageSetting": { + "en": "SMS, WhatsApp and Confirmation Calls Language", + "ar": "الرسائل القصيرة، واتساب، لغة مكالمات التأكيد" + }, + "alert": { + "en": "Alerts", + "ar": "تنبيهات" + }, + "emailAlert": { + "en": "Alert by Email", + "ar": "تنبيه عبر البريد الإلكتروني" + }, + "smsAlert": { + "en": "Alert by SMS", + "ar": "تنبيه عبر الرسائل القصيرة" + }, + "contactInfo": { + "en": "Contact Information", + "ar": "معلومات الاتصال" + }, + "emrgName": { + "en": "Emergency Contact Name", + "ar": "اسم جهة الاتصال في حالات الطوارئ" + }, + "emrgNo": { + "en": "Emergency Contact Number", + "ar": "رقم جهة الاتصال في حالات الطوارئ" + }, + "modes": { + "en": "Modes", + "ar": "الأوضاع" + }, + "vibration": { + "en": "Vibration Touch Feedback", + "ar": "اهتزاز عند اللمس" + }, + "blindModes": { + "en": "Modes for Partially Blind", + "ar": "أوضاع للمكفوفين جزئيًا" + }, + "invertTheme": { + "en": "Invert", + "ar": "عكس" + }, + "offTheme": { + "en": "Off", + "ar": "إيقاف" + }, + "dimTheme": { + "en": "Dim", + "ar": "خافت" + }, + "bwTheme": { + "en": "Black and White", + "ar": "أسود وأبيض" + }, + "permissions": { + "en": "Permission", + "ar": "إذن" + }, + "cameraPermission": { + "en": "Camera", + "ar": "الكاميرا" + }, + "locationPermission": { + "en": "Location", + "ar": "الموقع" + }, + "needPrescription": { + "en": "This product requires a prescription", + "ar": "يتطلب هذا المنتج وصفة طبية" + }, + "outOfStockMsg": { + "en": "You have added product which is out of stock now, Please remove that!", + "ar": "لقد أضفت منتجًا غير متوفر حاليًا، يرجى إزالته!" + }, + "noArabicLetters": { + "en": "It Is Not Allow to Use Arabic Letters", + "ar": "لا يُسمح باستخدام الحروف العربية" + }, + "noOffersAvailable": { + "en": "No Offers Available!", + "ar": "لا توجد عروض متاحة!" + }, + "accessibility": { + "en": "Accessibility Mode", + "ar": "وضع الوصول" + }, + "orderStatus": { + "en": "Order Status", + "ar": "حالة الطلب" + }, + "findUs": { + "en": "Find Us", + "ar": "اعثر علينا" + }, + "liveChat": { + "en": "Live Chat", + "ar": "دردشة مباشرة" + }, + "service": { + "en": "Service", + "ar": "خدمة" + }, + "hmgServiceLabel": { + "en": "HMG Service", + "ar": "خدمة مجموعة الحبيب الطبية" + }, + "healthWeatherIndicators": { + "en": "Health Weather Indicators", + "ar": "مؤشرات الطقس الصحية" + }, + "healthTipsBasedOnCurrentWeather": { + "en": "Health Tips Based On Current Weather", + "ar": "نصائح صحية بناءً على الطقس الحالي" + }, + "moreDetails": { + "en": "More details", + "ar": "المزيد من التفاصيل" + }, + "resendOrder": { + "en": "Refill and Delivery", + "ar": "إعادة التعبئة والتوصيل" + }, + "ports": { + "en": "Ports", + "ar": "المنافذ" + }, + "way": { + "en": "Way", + "ar": "الطريقة" + }, + "dailyDoses": { + "en": "Daily Doses", + "ar": "الجرعات اليومية" + }, + "period": { + "en": "Period", + "ar": "الفترة" + }, + "duration": { + "en": "المدة", + "ar": "المدة" + }, + "cm": { + "en": "CM", + "ar": "سم" + }, + "ft": { + "en": "ft", + "ar": "قدم" + }, + "kg": { + "en": "kg", + "ar": "كجم" + }, + "lb": { + "en": "lb", + "ar": "رطل" + }, + "birthDate": { + "en": "Birth Date", + "ar": "تاريخ الميلاد" + }, + "dateOfBirth": { + "en": "Date of Birth", + "ar": "تاريخ الميلاد" + }, + "mass": { + "en": "Mass", + "ar": "الكتلة" + }, + "tempC": { + "en": "°C", + "ar": "°م" + }, + "bpm": { + "en": "bpm", + "ar": "نبضة في الدقيقة" + }, + "respirationSigns": { + "en": "Respiration", + "ar": "التنفس" + }, + "sysDias": { + "en": "SBP/DBP", + "ar": "SBP/DBP" + }, + "body": { + "en": "Body Mass", + "ar": "مؤشر كتلة الجسم" + }, + "bodyString": { + "en": "Body", + "ar": "الجسم" + }, + "face": { + "en": "Face", + "ar": "وجه" + }, + "retouch": { + "en": "Re-touch", + "ar": "روتوش" + }, + "bikini": { + "en": "Bikini", + "ar": "بيكيني" + }, + "totalMinutes": { + "en": "Total Minutes", + "ar": "إجمالي الدقائق" + }, + "feedback": { + "en": "Feedback", + "ar": "ملاحظات" + }, + "likeToHear": { + "en": "We would love to hear the feedback, concerns on healthcare services and eServices experience. Please use the below form", + "ar": "نود سماع ملاحظاتك، ومخاوفك بشأن خدمات الرعاية الصحية وتجربة الخدمات الإلكترونية. يرجى استخدام النموذج أدناه" + }, + "emptySubject": { + "en": "Please enter the subject", + "ar": "يرجى إدخال الموضوع" + }, + "emptyMessage": { + "en": "Please enter message", + "ar": "يرجى إدخال الرسالة" + }, + "selectAttachment": { + "en": "Select Attachment", + "ar": "اختر المرفق" + }, + "complainAppo": { + "en": "Complaint for appointment", + "ar": "شكوى بخصوص الموعد" + }, + "complainAppoAlt": { + "en": "Complaint without appointment", + "ar": "شكوى بدون موعد" + }, + "messageType": { + "en": "Message Type", + "ar": "نوع الرسالة" + }, + "feedbackType": { + "en": "Feedback Type", + "ar": "نوع الملاحظات" + }, + "compliment": { + "en": "Appreciation", + "ar": "تقدير" + }, + "suggestion": { + "en": "Suggestion", + "ar": "اقتراح" + }, + "yourFeedback": { + "en": "Your feedback was sent", + "ar": "تم إرسال ملاحظاتك" + }, + "selectPart": { + "en": "Please select the part that complain about", + "ar": "يرجى اختيار الجزء الذي تشتكي منه" + }, + "number": { + "en": "Number", + "ar": "رقم" + }, + "notClassified": { + "en": "Not classified", + "ar": "غير مصنف" + }, + "selectClinic": { + "en": "Select Clinic", + "ar": "اختر العيادة" + }, + "selectProject": { + "en": "Select Hospital", + "ar": "اختر المستشفى" + }, + "searchItemError": { + "en": "Item name should be more than 3 character", + "ar": "يجب أن يكون اسم العنصر أكثر من 3 أحرف" + }, + "youCanFind": { + "en": "You Can Find ", + "ar": "يمكنك العثور على " + }, + "itemInSearch": { + "en": " Item in Search", + "ar": " عنصر في البحث" + }, + "bloodDonation": { + "en": "Blood Donation", + "ar": "التبرع بالدم" + }, + "bloodDonationInfo": { + "en": "Through this service, you can register your name as a blood donor where the blood bank in the Habib Medical Group will communicate you in case of need for blood type.", + "ar": "من خلال هذه الخدمة، يمكنك تسجيل اسمك كمتبرع بالدم حيث سيتواصل معك بنك الدم في مجموعة الحبيب الطبية في حالة الحاجة إلى فصيلة الدم." + }, + "bloodInstruction": { + "en": "Enter the required information, in order to register for Blood Donation Service", + "ar": "أدخل المعلومات المطلوبة، من أجل التسجيل في خدمة التبرع بالدم" + }, + "viewTerms": { + "en": "To view the terms and conditions", + "ar": "لعرض الشروط والأحكام" + }, + "wantConnectHmgNetwork": { + "en": "Dear customer there is no internet access, do you want to connect with HMG network to use our app, make sure you are in range of HMG network", + "ar": "عزيزي العميل، لا يوجد وصول إلى الإنترنت، هل ترغب في الاتصال بشبكة مجموعة الحبيب الطبية لاستخدام تطبيقنا، تأكد من أنك في نطاق شبكة مجموعة الحبيب الطبية" + }, + "failedToAccessHmgServices": { + "en": "Connected with HMG Network,\n\nBut failed to access HMG services", + "ar": "متصل بشبكة مجموعة الحبيب الطبية،\n\nلكن فشل في الوصول إلى خدمات مجموعة الحبيب الطبية" + }, + "offerAndPackages": { + "en": "Offers and Packages", + "ar": "عروض وباقات" + }, + "offerAndPackagesDetails": { + "en": "This service allows you to view all HMG Offers:", + "ar": "تتيح لك هذه الخدمة عرض جميع عروض مجموعة الحبيب الطبية:" + }, + "invoiceNo": { + "en": "Invoice No", + "ar": "رقم الفاتورة" + }, + "invoiceDate": { + "en": "Invoice Date", + "ar": "تاريخ الفاتورة" + }, + "specialResult": { + "en": "Special Result", + "ar": "نتيجة خاصة" + }, + "generalResult": { + "en": "General Result", + "ar": "نتيجة عامة" + }, + "showMoreBtn": { + "en": "Flow Chart", + "ar": "مخطط التدفق" + }, + "value": { + "en": "Value", + "ar": "القيمة" + }, + "report": { + "en": "Radiology Report", + "ar": "تقرير الأشعة" + }, + "openRad": { + "en": "Open Image", + "ar": "فتح الصورة" + }, + "sendCopy": { + "en": "Email the Report", + "ar": "إرسال التقرير عبر البريد الإلكتروني" + }, + "appoSurvey": { + "en": "Survey", + "ar": "استطلاع" + }, + "appoSurveySubtitle": { + "en": "Survey", + "ar": "استطلاع" + }, + "labResults": { + "en": "Lab Results", + "ar": "نتائج المختبر" + }, + "doctorRating": { + "en": "Doctor Rating", + "ar": "تقييم الطبيب" + }, + "good": { + "en": "Good", + "ar": "جيد" + }, + "vGood": { + "en": "Very Good", + "ar": "جيد جدًا" + }, + "excellent": { + "en": "Excellent", + "ar": "ممتاز" + }, + "average": { + "en": "Average", + "ar": "متوسط" + }, + "infoSigns": { + "en": "This service allows you to view all vital signs were performed in the Habib Medical Group, e.x (height, weight, body mass index, heart rate, etc.) as well shows some statistics charts.", + "ar": "تتيح لك هذه الخدمة عرض جميع العلامات الحيوية التي تم قياسها في مجموعة الحبيب الطبية، مثل (الطول، الوزن، مؤشر كتلة الجسم، معدل ضربات القلب، إلخ.) بالإضافة إلى عرض بعض الرسوم البيانية الإحصائية." + }, + "infoAdvancePayment": { + "en": "This service designed so that you can deposit an amount in advance either in your account or in someone else's account with Al Habib Medical Group.", + "ar": "تم تصميم هذه الخدمة بحيث يمكنك إيداع مبلغ مقدم إما في حسابك أو في حساب شخص آخر، في مجموعة الحبيب الطبية." + }, + "infoMyBalance": { + "en": "This service allows you to check your balance in all branchs", + "ar": "تتيح لك هذه الخدمة التحقق من رصيدك في جميع الفروع" + }, + "erContant": { + "en": "This service displays nearest branch among all the branches of Al Habib Medical Group based on your current location.", + "ar": "تظهر هذه الخدمة أقرب فرع من بين جميع فروع مجموعة الحبيب الطبية بناءً على موقعك الحالي." + }, + "infoAmbulance": { + "en": "Through this service, you can request evacuation by ambulance, whether from home or to home, in addition to a set of other services", + "ar": "من خلال هذه الخدمة، يمكنك طلب الإخلاء بواسطة سيارة إسعاف، سواء من المنزل أو إلى المنزل، بالإضافة إلى مجموعة من الخدمات الأخرى" + }, + "infoMyAppointments": { + "en": "This service allows you to see all the appointment you have visited in Al Habib Medical Group, and through this service:", + "ar": "تتيح لك هذه الخدمة رؤية جميع المواعيد التي زرتها في مجموعة الحبيب الطبية، ومن خلال هذه الخدمة:" + }, + "infoTodo": { + "en": "This service is designed to enable you to have a quick link to the list of tasks that need to be done", + "ar": "تم تصميم هذه الخدمة لتمكينك من الحصول على رابط سريع لقائمة المهام التي تحتاج القيام بها" + }, + "familyInfo": { + "en": "Through this service, you will be able to link your family medical files to your medical file so that you can manage their records by login to your medical file.", + "ar": "من خلال هذه الخدمة، ستتمكن من ربط ملفات عائلتك الطبية بملفك الطبي حتى تتمكن من إدارة سجلاتهم عن طريق تسجيل الدخول إلى ملفك الطبي." + }, + "rrtdDetails": { + "en": "The Rapid response team provides a comprehensive medical service for all sorts of urgent and stable cases of all ages, including adult and paediatric patients, the service is covered by a fully equipped and highly trained medical team capable of providing the best medical care at the patient’s home.", + "ar": "تقدم فريق الاستجابة السريعة خدمة طبية شاملة لجميع أنواع الحالات العاجلة والمستقرة من جميع الأعمار، بما في ذلك البالغين والمرضى الأطفال، وتغطي الخدمة فريق طبي مدرب تدريبًا عاليًا ومجهز تجهيزًا كاملًا قادرًا على تقديم أفضل رعاية طبية في منزل المريض." + }, + "onlineCheckInAgreement": { + "en": "The online check-in is for non-life threatening situation. Call the red crescent (997) or go to the nearest emergency department if there are: \n\nsigns of stroke or heart attack \nhistory of seizure or syncope \nthere is limb or life threatening injury \npicture of severe injuries", + "ar": "تسجيل الوصول عبر الإنترنت مخصص للحالات التي لا تهدد الحياة. اتصل بالهلال الأحمر (997) أو اذهب إلى أقرب قسم طوارئ إذا كان هناك: \n\nعلامات السكتة الدماغية أو النوبة القلبية \nhالة من النوبات أو الإغماء \nهناك إصابة تهدد الطرف أو الحياة \nصورة لإصابات خطيرة" + }, + "infoEreferral": { + "en": "This service allows you to submit a Referral request from any health care providers either inside or outside the kingdom of Saudi Arabia to any of HMG Hospitals, by filling some of the patient's data and attaching the medical reports, moreover you can track the request status (Under process, Accepted or Rejected)", + "ar": "تتيح لك هذه الخدمة تقديم طلب إحالة من أي مقدم رعاية صحية سواء داخل أو خارج المملكة العربية السعودية إلى أي من مستشفيات HMG، عن طريق ملء بعض بيانات المريض وإرفاق التقارير الطبية، علاوة على ذلك يمكنك تتبع حالة الطلب (قيد المعالجة، مقبول أو مرفوض)" + }, + "erConsultation": { + "en": "This service allows you to make an online virtual consultation via video call directly with the doctor from anywhere at any time.", + "ar": "تتيح لك هذه الخدمة إجراء استشارة افتراضية عبر الإنترنت عبر مكالمة فيديو مباشرة مع الطبيب من أي مكان وفي أي وقت." + }, + "myInvoice": { + "en": "List", + "ar": "القائمة" + }, + "invoiceList": { + "en": "My Invoice", + "ar": "فواتيري" + }, + "thisItemIsNotAvailable": { + "en": "This item is not available", + "ar": "هذا العنصر غير متوفر" + }, + "beforeAfterImages": { + "en": "Before & After Images", + "ar": "صور قبل وبعد" + }, + "clinicAcceptLivecare": { + "en": "No need to wait or visit You can now get medical consultation via Video call (LiveCare service) in The name of the clinic clinic and the doctor will contact you immediately", + "ar": "لا حاجة للانتظار أو الزيارة يمكنك الآن الحصول على استشارة طبية عبر مكالمة فيديو (لايف كير) في اسم العيادة وسيتصل بك الطبيب على الفور" + }, + "livecareModalTop": { + "en": "This Clinic is Accepting LiveCare services", + "ar": "تقبل هذه العيادة خدمات ال لايف كير" + }, + "livecarePoint2": { + "en": "A Specialized doctor will contact you", + "ar": "سوف يتصل بك طبيب متخصص" + }, + "livecarePoint3": { + "en": "A Doctor will be able to see your full medical file history", + "ar": "سيكون لدى الطبيب القدرة على رؤية تاريخ ملفك الطبي الكامل" + }, + "livecarePoint4": { + "en": "Free Medicine Delivery Available", + "ar": "تتوفر خدمة توصيل الأدوية المجانية" + }, + "livecarePoint5": { + "en": "No need to visit the service is in your place", + "ar": "لا حاجة للزيارة، الخدمة في مكانك" + }, + "bookImmediateLivecare": { + "en": "I accept to get the service immediately", + "ar": "أوافق على الحصول على الخدمة على الفور" + }, + "bookVideoLivecare2": { + "en": "I don't need to visit the clinic", + "ar": "لا أحتاج لزيارة العيادة" + }, + "noThankyou": { + "en": "No Thanks", + "ar": "لا شكرًا" + }, + "visitClinic": { + "en": "Schedule appointment with the doctor", + "ar": "جدولة موعد مع الطبيب" + }, + "generateCovidCertificate": { + "en": "Generate Covid-19 Certificate", + "ar": "إصدار شهادة كوفيد-19" + }, + "isReportOutsideKsa": { + "en": "Is the certificate needed for outside KSA?", + "ar": "هل الشهادة مطلوبة خارج المملكة العربية السعودية؟" + }, + "passportNumber": { + "en": "Passport Number", + "ar": "رقم جواز السفر" + }, + "enterPassportNumber": { + "en": "Please confirm or update your passport number:", + "ar": "يرجى تأكيد أو تحديث رقم جواز السفر الخاص بك:" + }, + "validPassportNumber": { + "en": "Please enter valid passport number", + "ar": "يرجى إدخال رقم جواز سفر صالح" + }, + "continuePlan": { + "en": "Continue with the treatment plan?", + "ar": "متابعة خطة العلاج؟" + }, + "aboutApp": { + "en": "About the app", + "ar": "حول التطبيق" + }, + "dontHaveAccount": { + "en": "Don't have an account?", + "ar": "ليس لديك حساب؟" + }, + "loginOrRegister": { + "en": "Login or Register", + "ar": "تسجيل الدخول أو التسجيل" + }, + "myFiles": { + "en": "My Files", + "ar": "ملفاتي" + }, + "resultsPending": { + "en": "Results pending", + "ar": "النتائج معلقة" + }, + "resultsAvailable": { + "en": "Results available", + "ar": "النتائج متاحة" + }, + "viewReport": { + "en": "View Report", + "ar": "عرض التقرير" + }, + "checkAvailability": { + "en": "Check Availability", + "ar": "التحقق من التوفر" + }, + "readInstructions": { + "en": "Read Instructions", + "ar": "قراءة التعليمات" + }, + "searchLabReport": { + "en": "Search Lab Report", + "ar": "ابحث عن تقرير المختبر" + }, + "prescriptionDeliveryError": { + "en": "This Clinic Does Not Support Refill And Delivery.", + "ar": "هذه العيادة لا تدعم إعادة التعبئة والتسليم." + }, + "receiveOtpToast": { + "en": "Where would you like to receive OTP?", + "ar": "أين تود تلقي رمز التحقق OTP؟" + }, + "enterPhoneNumber": { + "en": "Enter Phone Number", + "ar": "أدخل رقم الهاتف" + }, + "enterEmailDesc": { + "en": "Enter your email to complete medical profile creation process", + "ar": "أدخل عنوان بريدك الإلكتروني لإكمال عملية إنشاء ملف طبي" + }, + "enterPhoneDesc": { + "en": "Enter your phone number to receive OTP ", + "ar": "أدخل رقم هاتفك لتلقي رمز التحقق " + }, + "pleaseChooseOption": { + "en": "Please select from the below options to receive OTP", + "ar": "الرجاء اختيار من الخيارات أدناه لتلقي رمز التحقق OTP" + }, + "prepareToElevate": { + "en": "Prepared to elevate your health and well-being?", + "ar": "هل أنت مستعد لتحسين صحتك ورفاهيتك؟" + }, + "iAcceptTermsConditions": { + "en": "I Accept the Terms and Conditions", + "ar": "أوافق على الشروط والأحكام" + }, + "alreadyHaveAccount": { + "en": "Already have an account?", + "ar": "هل لديك حساب بالفعل؟" + }, + "loginNow": { + "en": "Login Now", + "ar": "تسجيل الدخول الآن" + }, + "notice": { + "en": "Notice", + "ar": "إشعار" + }, + "oR": { + "en": "OR", + "ar": "أو" + }, + "sendOTPWHATSAPP": { + "en": "Send me OTP on Whatsapp", + "ar": "أرسل لي OTP عبر واتساب" + }, + "sendOTPSMS": { + "en": "Send me OTP on SMS", + "ar": "أرسل لي OTP عبر الرسائل القصيرة" + }, + "fullName": { + "en": "Full Name", + "ar": "الاسم الكامل" + }, + "married": { + "en": "Married", + "ar": "متزوج" + }, + "uae": { + "en": "United Arab Emirates", + "ar": "الإمارات العربية المتحدة" + }, + "malE": { + "en": "Male", + "ar": "ذكر" + }, + "loginBy": { + "en": "Login By", + "ar": "تسجيل الدخول بواسطة" + }, + "loginByOTP": { + "en": "Login By OTP", + "ar": "تسجيل الدخول بواسطة OTP" + }, + "guest": { + "en": "Guest", + "ar": "زائر" + }, + "switchAccount": { + "en": "Switch Account", + "ar": "تبديل الحساب" + }, + "lastLoginBy": { + "en": "Last login by", + "ar": "آخر تسجيل دخول بواسطة" + }, + "allSet": { + "en": "All Set! Now you can login with Face ID or Biometric", + "ar": "جاهز! الآن يمكنك تسجيل الدخول باستخدام Face ID أو البصمة" + }, + "enableQuickLogin": { + "en": "Enable Quick Login", + "ar": "تمكين تسجيل الدخول السريع" + }, + "enableMsg": { + "en": "Enabling the quick login will verify through your existing device Face ID / Biometric", + "ar": "تمكين تسجيل الدخول السريع سيسمح بالتحقق من خلال Face ID / Biometric الخاص بجهازك الحالي" + }, + "notNow": { + "en": "Not Now", + "ar": "ليس الآن" + }, + "pendingActivation": { + "en": "Pending Activation", + "ar": "في انتظار التنشيط" + }, + "awaitingApproval": { + "en": "Awaiting Approval", + "ar": "انتظر القبول" + }, + "news": { + "en": "News", + "ar": "أخبار" + }, + "ready": { + "en": "Ready", + "ar": "جاهز" + }, + "enterValidNationalId": { + "en": "Please enter a valid national ID or file number", + "ar": "الرجاء إدخال رقم الهوية الوطنية أو رقم الملف الصحيح" + }, + "enterValidPhoneNumber": { + "en": "Please enter a valid phone number", + "ar": "الرجاء إدخال رقم هاتف صالح" + }, + "cannotEnterSaudiOrUAENumber": { + "en": "You cannot enter Saudi Arabia (00966) or UAE (00971) phone numbers when 'Others' country is selected", + "ar": "لا يمكنك إدخال أرقام هواتف السعودية (00966) أو الإمارات (00971) عند اختيار دولة 'أخرى'" + }, + "medicalCentersWithCount": { + "en": "{count} Medical Centers", + "ar": "{count} مراكز طبية" + }, + "medicalCenters": { + "en": " Medical Centers", + "ar": "مراكز طبية" + }, + "hospitalsWithCount": { + "en": "{count} Hospitals", + "ar": "{count} مستشفيات" + }, + "selectRegion": { + "en": "Select Region", + "ar": "اختر المنطقة" + }, + "selectFacility": { + "en": "Select Facilities", + "ar": "اختر المرافق" + }, + "selectFacilitiesSubTitle": { + "en": "Please select the facility for the appointment", + "ar": "يرجى اختيار المرفق للموعد" + }, + "selectHospitalSubTitle": { + "en": "Please select the hospital for the appointment", + "ar": "يرجى اختيار المستشفى للموعد" + }, + "iAcceptThe": { + "en": "I Accept the", + "ar": "أوافق على" + }, + "personalDetailsVerification": { + "en": "Personal Details Verification", + "ar": "التحقق من التفاصيل الشخصية" + }, + "otpVerification": { + "en": "OTP Verification", + "ar": "التحقق من OTP" + }, + "weHaveSendOTP": { + "en": "We have sent you the OTP code on", + "ar": "لقد أرسلنا OTP إلى" + }, + "via": { + "en": "via", + "ar": "عبر" + }, + "forRegistrationVerification": { + "en": "for registration verification", + "ar": "للتحقق من التسجيل" + }, + "didntReceiveIt": { + "en": "Didn't receive it?", + "ar": "لم تستلمه؟" + }, + "resendOTP": { + "en": "Resend", + "ar": "إعادة إرسال" + }, + "resendIn": { + "en": "resend in", + "ar": "إعادة الإرسال في" + }, + "pleaseEnterAnationalID": { + "en": "Please enter a national ID", + "ar": "يرجى إدخال رقم الهوية الوطنية" + }, + "pleaseEnterAFileNumber": { + "en": "Please enter a file number", + "ar": "يرجى إدخال رقم الملف" + }, + "pleaseEnterAValidEmail": { + "en": "Please enter a valid email", + "ar": "يرجى إدخال بريد إلكتروني صالح" + }, + "pleaseEnterFullName": { + "en": "Please enter full name", + "ar": "يرجى إدخال الاسم الكامل" + }, + "pleaseAcceptTermsConditions": { + "en": "Please accept the terms and conditions", + "ar": "يرجى قبول الشروط والأحكام" + }, + "pleaseEnterAValidIqamaID": { + "en": "Please enter a valid Iqama ID", + "ar": "يرجى إدخال رقم إقامة صالح" + }, + "pleaseEnterAValidNationalID": { + "en": "Please enter a valid national ID", + "ar": "يرجى إدخال رقم هوية وطنية صالح" + }, + "pleaseEnterAValidDateOfBirth": { + "en": "Please enter a valid date of birth", + "ar": "يرجى إدخال تاريخ ميلاد صالح" + }, + "pleaseEnterAValidName": { + "en": "Please enter a valid name", + "ar": "يرجى إدخال اسم صالح" + }, + "pleaseSelectAGender": { + "en": "Please select a gender", + "ar": "يرجى اختيار الجنس" + }, + "pleaseSelectAMaritalStatus": { + "en": "Please select a marital status", + "ar": "يرجى اختيار الحالة الاجتماعية" + }, + "pleaseSelectACountry": { + "en": "Please select a country", + "ar": "يرجى اختيار الدولة" + }, + "pleaseEnterEmail": { + "en": "Please enter email", + "ar": "يرجى إدخال البريد الإلكتروني" + }, + "pleaseEnterAValidEmailFormat": { + "en": "Please enter a valid email format", + "ar": "يرجى إدخال تنسيق بريد إلكتروني صالح" + }, + "selectCountry": { + "en": "Select Country", + "ar": "اختر الدولة" + }, + "forLoginVerification": { + "en": "for login verification", + "ar": "للتحقق من تسجيل الدخول" + }, + "searchHospital": { + "en": "Search Hospital", + "ar": "بحث في المستشفى" + }, + "skip": { + "en": "Skip", + "ar": "تخطي" + }, + "getStarted": { + "en": "Get Started", + "ar": "ابدأ الآن" + }, + "onboardingHeading1": { + "en": "Booking appointment has never been easy", + "ar": "حجز المواعيد لم يكن أسهل من الآن." + }, + "onboardingBody1": { + "en": "In few clicks find yourself having consultation with the doctor of your choice.", + "ar": "ببضع نقرات فقط يمكنك استشارة الطبيب الذي تختاره." + }, + "onboardingHeading2": { + "en": "Access the medical history on finger tips", + "ar": "الوصول إلى السجل الطبي بين يديك" + }, + "onboardingBody2": { + "en": "Keep track on your medical history including labs, prescription, insurance, etc", + "ar": "تتبع تاريخك الطبي بما في ذلك الفحوصات المخبرية، الوصفات الطبية، التأمين، وغيرها." + }, + "hmgHospitals": { + "en": "HMG Hospitals", + "ar": "مستشفيات مجموعة الحبيب الطبية" + }, + "hmcMedicalClinic": { + "en": "HMC Medical Centers", + "ar": "مراكز مجموعة الحبيب الطبية" + }, + "applyFilter": { + "en": "Apply Filter", + "ar": "تطبيق الفلتر" + }, + "facilityAndLocation": { + "en": "Facility and Location", + "ar": "المرفق والموقع" + }, + "regionAndLocation": { + "en": "Region And Locations", + "ar": "المنطقة والمواقع" + }, + "clearAllFilters": { + "en": "Clear all filters", + "ar": "مسح جميع الفلاتر" + }, + "filters": { + "en": "Filters", + "ar": "فلاتر" + }, + "searchClinic": { + "en": "Search Clinic", + "ar": "بحث عن عيادة" + }, + "normal": { + "en": "Normal", + "ar": "عادي" + }, + "attention": { + "en": "Attention", + "ar": "انتباه" + }, + "monitor": { + "en": "Monitor", + "ar": "مراقبة" + }, + "noSpecialResult": { + "en": "No Special Results", + "ar": "لا توجد نتائج خاصة" + }, + "setTheDateRange": { + "en": "Set The Date Range", + "ar": "تعيين النطاق الزمني" + }, + "historyFlowchart": { + "en": "History FlowChart", + "ar": "مخطط تدفق التاريخ" + }, + "to": { + "en": "to", + "ar": "إلى" + }, + "startDate": { + "en": "Start Date", + "ar": "تاريخ البدء" + }, + "endDate": { + "en": "End Date", + "ar": "تاريخ الانتهاء" + }, + "walkin": { + "en": "Walk In", + "ar": "زيارة بدون موعد" + }, + "laserClinic": { + "en": "Laser Clinic", + "ar": "عيادة الليزر" + }, + "continueString": { + "en": "Continue", + "ar": "يكمل" + }, + "covid_info": { + "en": "Dr. Sulaiman Al Habib hospitals are conducting a test for the emerging corona virus and issuing travel certificates 24/7 in a short time and with high accuracy...", + "ar": "تجري مستشفيات د. سليمان الحبيب فحص فيروس كورونا المستجد وتصدر شهادات السفر على مدار الساعة..." + }, + "appointmentDetails": { + "en": "Appointment Details", + "ar": "تفاصيل الموعد" + }, + "checkingDoctorAvailability": { + "en": "Checking doctor availability...", + "ar": "جاري التحقق من توفر الطبيب..." + }, + "cancellingAppointmentPleaseWait": { + "en": "Cancelling Appointment, Please Wait...", + "ar": "جاري إلغاء الموعد، يرجى الانتظار..." + }, + "appointmentCancelledSuccessfully": { + "en": "Appointment Cancelled Successfully", + "ar": "تم إلغاء الموعد بنجاح" + }, + "notConfirmed": { + "en": "Not Confirmed", + "ar": "غير مؤكد" + }, + "appointmentStatus": { + "en": "Appointment Status", + "ar": "حالة الموعد" + }, + "doctorWillCallYou": { + "en": "The doctor will call you once the appointment time approaches.", + "ar": "سيتصل بك الطبيب عندما يقترب موعدك." + }, + "getDirections": { + "en": "Get Directions", + "ar": "الحصول على الاتجاهات" + }, + "notifyMeBeforeAppointment": { + "en": "Notify me before the appointment", + "ar": "أبلغني قبل الموعد" + }, + "fetchingLabResults": { + "en": "Fetching Lab Results...", + "ar": "جاري جلب نتائج المختبر..." + }, + "fetchingRadiologyResults": { + "en": "Fetching Radiology Results...", + "ar": "جاري جلب نتائج الأشعة..." + }, + "fetchingAppointmentPrescriptions": { + "en": "Fetching Appointment Prescriptions...", + "ar": "جاري جلب وصفات الموعد..." + }, + "noPrescriptionsForAppointment": { + "en": "You don't have any prescriptions for this appointment.", + "ar": "ليس لديك أي وصفات طبية لهذا الموعد." + }, + "amountBeforeTax": { + "en": "Amount before tax", + "ar": "المبلغ قبل الضريبة" + }, + "rebookAppointment": { + "en": "Re-book Appointment", + "ar": "إعادة حجز الموعد" + }, + "fetchingDoctorSchedulePleaseWait": { + "en": "Fetching Doctor Schedule, Please Wait...", + "ar": "جاري جلب جدول الطبيب، يرجى الانتظار..." + }, + "pickADate": { + "en": "Pick a Date", + "ar": "اختر تاريخاً" + }, + "confirmingAppointmentPleaseWait": { + "en": "Confirming Appointment, Please Wait...", + "ar": "جاري تأكيد الموعد، يرجى الانتظار..." + }, + "appointmentConfirmedSuccessfully": { + "en": "Appointment Confirmed Successfully", + "ar": "تم تأكيد الموعد بنجاح" + }, + "appointmentPayment": { + "en": "Appointment Payment", + "ar": "دفع الموعد" + }, + "checkingPaymentStatusPleaseWait": { + "en": "Checking payment status, Please wait...", + "ar": "جاري التحقق من حالة الدفع، يرجى الانتظار..." + }, + "paymentFailedPleaseTryAgain": { + "en": "Payment Failed! Please try again.", + "ar": "فشل الدفع! يرجى المحاولة مرة أخرى." + }, + "appointmentCheckIn": { + "en": "Appointment check in", + "ar": "تسجيل حضور الموعد" + }, + "insuranceExpiredOrInactive": { + "en": "Insurance expired or inactive", + "ar": "التأمين منتهي الصلاحية أو غير نشط" + }, + "totalAmountToPay": { + "en": "Total amount to pay", + "ar": "المبلغ الإجمالي المستحق" + }, + "vat15": { + "en": "VAT 15%", + "ar": "ضريبة القيمة المضافة 15%" + }, + "liveCare": { + "en": "LiveCare", + "ar": "لايف كير" + }, + "recentVisits": { + "en": "Recent Visits", + "ar": "الزيارات الأخيرة" + }, + "searchByClinic": { + "en": "Search By Clinic", + "ar": "البحث حسب العيادة" + }, + "tapToSelectClinic": { + "en": "Tap to select clinic", + "ar": "انقر لاختيار العيادة" + }, + "searchByDoctor": { + "en": "Search By Doctor", + "ar": "البحث حسب الطبيب" + }, + "tapToSelect": { + "en": "Tap to select", + "ar": "انقر للاختيار" + }, + "searchByRegion": { + "en": "Search By Region", + "ar": "البحث حسب المنطقة" + }, + "centralRegion": { + "en": "Central Region", + "ar": "المنطقة الوسطى" + }, + "immediateConsultation": { + "en": "Immediate Consultation", + "ar": "استشارة فورية" + }, + "scheduledConsultation": { + "en": "Scheduled Consultation", + "ar": "استشارة مجدولة" + }, + "pharmaLiveCare": { + "en": "Pharma LiveCare", + "ar": "لايف كير الصيدلية" + }, + "notSureHelpMeChooseClinic": { + "en": "Not sure? help me choose a clinic!", + "ar": "غير متأكد؟ ساعدني في اختيار عيادة!" + }, + "mentionYourSymptomsAndFindDoctors": { + "en": "Mention your symptoms and find the list of doctors accordingly", + "ar": "اذكر أعراضك واعثر على قائمة الأطباء وفقاً لذلك" + }, + "immediateService": { + "en": "Immediate service", + "ar": "خدمة فورية" + }, + "noNeedToWaitGetMedicalConsultation": { + "en": "No need to wait, you will get medical consultation immediately via video call", + "ar": "لا حاجة للانتظار، ستحصل على استشارة طبية فورية عبر مكالمة فيديو" + }, + "noVisitRequired": { + "en": "No visit required", + "ar": "لا حاجة للزيارة" + }, + "doctorWillContact": { + "en": "Doctor will contact", + "ar": "سيتصل بك الطبيب" + }, + "specialisedDoctorWillContactYou": { + "en": "A specialised doctor will contact you and will be able to view your medical history", + "ar": "سيتصل بك طبيب متخصص وسيكون قادراً على الاطلاع على تاريخك الطبي" + }, + "freeMedicineDelivery": { + "en": "Free medicine delivery", + "ar": "توصيل مجاني للأدوية" + }, + "offersFreeMedicineDelivery": { + "en": "Offers free medicine delivery for the LiveCare appointment", + "ar": "يوفر توصيل مجاني للأدوية لموعد لايف كير" + }, + "dentalChiefComplaints": { + "en": "Dental Chief Complaints", + "ar": "الشكاوى الرئيسة للأسنان" + }, + "viewAvailableAppointments": { + "en": "View available appointments", + "ar": "عرض المواعيد المتاحة" + }, + "doctorProfile": { + "en": "Doctor Profile", + "ar": " ملف الطبيب" + }, + "waitingAppointment": { + "en": "Waiting Appointment", + "ar": "موعد الانتظار" + }, + "hospitalInformation": { + "en": "Hospital Information", + "ar": "معلومات المستشفى" + }, + "fetchingAppointmentShare": { + "en": "Fetching Appointment Share...", + "ar": "جاري جلب تفاصيل الموعد..." + }, + "bookingYourAppointment": { + "en": "Booking your appointment...", + "ar": "جاري حجز موعدك..." + }, + "selectLiveCareClinic": { + "en": "Select LiveCare Clinic", + "ar": "اختر عيادة لايف كير" + }, + "checkingForExistingDentalPlan": { + "en": "Checking for an existing dental plan, Please wait...", + "ar": "جاري التحقق من وجود خطة أسنان حالية، يرجى الانتظار..." + }, + "dentalTreatmentPlan": { + "en": "Dental treatment plan", + "ar": "خطة علاج الأسنان" + }, + "youHaveExistingTreatmentPlan": { + "en": "You have an existing treatment plan: ", + "ar": "لديك خطة علاج حالية: " + }, + "mins": { + "en": "Mins", + "ar": "دقيقة" + }, + "totalTimeRequired": { + "en": "Total time required", + "ar": "إجمالي الوقت المطلوب" + }, + "wouldYouLikeToContinue": { + "en": "Would you like to continue it?", + "ar": "هل تريد متابعتها؟" + }, + "chooseDoctor": { + "en": "Choose Doctor", + "ar": "اختر الطبيب" + }, + "viewNearestAppos": { + "en": "View nearest available appointments", + "ar": "عرض أقرب المواعيد المتاحة" + }, + "noDoctorFound": { + "en": "No Doctor found for selected criteria...", + "ar": "لم يتم العثور على طبيب مطابق للمعايير المحددة..." + }, + "yesPleasImInAHurry": { + "en": "Yes please, I am in a hurry", + "ar": "نعم من فضلك، أنا في عجلة من أمري" + }, + "fetchingFeesPleaseWait": { + "en": "Fetching fees, Please wait...", + "ar": "جاري جلب الرسوم، يرجى الانتظار..." + }, + "noThanksPhysicalVisit": { + "en": "No, Thanks. I would like a physical visit", + "ar": "لا، شكراً. أفضل الزيارة الشخصية" + }, + "offline": { + "en": "Offline", + "ar": "غير متصل" + }, + "videoCall": { + "en": "Video Call", + "ar": "مكالمة فيديو" + }, + "liveVideoCallWithHMGDoctors": { + "en": "Live Video Call with HMG Doctors", + "ar": "مكالمة فيديو مباشرة مع أطباء مجموعة الحبيب الطبية" + }, + "liveAudioCallWithHMGDoctors": { + "en": "Live Audio Call with HMG Doctors", + "ar": "مكالمة صوتية مباشرة مع أطباء مجموعة الحبيب الطبية" + }, + "audioCall": { + "en": "Audio Call", + "ar": "مكالمة صوتية" + }, + "phoneCall": { + "en": "Phone Call", + "ar": "مكالمة هاتفية" + }, + "livePhoneCallWithHMGDoctors": { + "en": "Live Phone Call with HMG Doctors", + "ar": "مكالمة هاتفية مباشرة مع أطباء مجموعة الحبيب الطبية" + }, + "reviewLiveCareRequest": { + "en": "Review LiveCare Request", + "ar": "مراجعة طلب لايف كير" + }, + "selectedLiveCareType": { + "en": "Selected LiveCare Type", + "ar": "نوع لايف كير المحدد" + }, + "selectLiveCareCallType": { + "en": "Select LiveCare call type", + "ar": "اختر نوع مكالمة لايف كير" + }, + "confirmingLiveCareRequest": { + "en": "Confirming LiveCare request, Please wait...", + "ar": "جاري تأكيد طلب لايف كير، يرجى الانتظار..." + }, + "unknownErrorOccurred": { + "en": "Unknown error occurred...", + "ar": "حدث خطأ غير معروف..." + }, + "liveCarePermissionsMessage": { + "en": "LiveCare requires Camera, Microphone, Location & Notifications permissions to enable virtual consultation between patient & doctor...", + "ar": "يتطلب لايف كير أذونات الكاميرا والميكروفون والموقع والإشعارات لتمكين الاستشارة الافتراضية..." + }, + "liveCarePayment": { + "en": "LiveCare Payment", + "ar": "دفع لايف كير" + }, + "mada": { + "en": "Mada", + "ar": "مدى" + }, + "visaOrMastercard": { + "en": "Visa or Mastercard", + "ar": "فيزا أو ماستركارد" + }, + "tamara": { + "en": "Tamara", + "ar": "تمارا" + }, + "fetchingApplePayDetails": { + "en": "Fetching Apple Pay details, Please wait...", + "ar": "جاري جلب تفاصيل Apple Pay، يرجى الانتظار..." + }, + "liveCarePendingRequest": { + "en": "LiveCare Pending Request", + "ar": "طلب لايف كير قيد الانتظار" + }, + "callLiveCareSupport": { + "en": "Call LiveCare Support", + "ar": "اتصل بدعم لايف كير" + }, + "whatIsWaitingAppointment": { + "en": "What is Waiting Appointment?", + "ar": "ما هو موعد الانتظار؟" + }, + "waitingAppointmentsFeature": { + "en": "The waiting appointments feature allows you to book an appointment while you are inside the hospital building...", + "ar": "تتيح لك ميزة مواعيد الانتظار حجز موعد أثناء تواجدك داخل مبنى المستشفى..." + }, + "appointmentWithDoctorConfirmed": { + "en": "The appointment with the doctor is confirmed, but the time of entry is uncertain.", + "ar": "الموعد مع الطبيب مؤكد، ولكن وقت الدخول غير محدد." + }, + "paymentWithinTenMinutes": { + "en": "Note: You must have to pay within 10 minutes of booking, otherwise your appointment will be cancelled automatically", + "ar": "ملاحظة: يجب عليك الدفع خلال 10 دقائق من الحجز، وإلا سيتم إلغاء موعدك تلقائياً" + }, + "liveLocation": { + "en": "Live Location", + "ar": "الموقع المباشر" + }, + "verifyYourLocationAtHospital": { + "en": "Verify your location to be at hospital to check in", + "ar": "تحقق من موقعك في المستشفى لتسجيل الحضور" + }, + "error": { + "en": "Error", + "ar": "خطأ" + }, + "ensureWithinHospitalLocation": { + "en": "Please ensure you're within the hospital location to perform online check-in.", + "ar": "يرجى التأكد من أنك داخل موقع المستشفى لإجراء تسجيل الحضور عبر الإنترنت." + }, + "nfcNearFieldCommunication": { + "en": "NFC (Near Field Communication)", + "ar": "NFC (الاتصال قريب المدى)" + }, + "scanPhoneViaNFC": { + "en": "Scan your phone via NFC board to check in", + "ar": "امسح هاتفك عبر لوحة NFC لتسجيل الحضور" + }, + "qrCode": { + "en": "QR Code", + "ar": "رمز QR" + }, + "scanQRCodeToCheckIn": { + "en": "Scan QR code with your camera to check in", + "ar": "امسح رمز QR بالكاميرا لتسجيل الحضور" + }, + "processingCheckIn": { + "en": "Processing Check-In...", + "ar": "جاري معالجة تسجيل الحضور..." + }, + "bookingWaitingAppointment": { + "en": "Booking Waiting Appointment, Please wait...", + "ar": "جاري حجز موعد الانتظار، يرجى الانتظار..." + }, + "enterValidIDorIqama": { + "en": "Please enter a valid national ID or file number", + "ar": "يرجى إدخال رقم هوية وطنية أو رقم ملف صالح" + }, + "selectAppointment": { + "en": "Select Appointment", + "ar": "حدد الموعد" + }, + "rebookSameDoctor": { + "en": "Rebook with same doctor", + "ar": "أعد الحجز مع نفس الطبيب" + }, + "queueing": { + "en": "Queueing", + "ar": "قائمة الانتظار" + }, + "inQueue": { + "en": "In Queue", + "ar": "في قائمة الانتظار" + }, + "yourTurn": { + "en": "Your Turn", + "ar": "دورك" + }, + "halaFirstName": { + "en": "Hala {firstName}!!!", + "ar": "هلا {firstName}!!!" + }, + "thankYouForPatience": { + "en": "Thank you for your patience, here is your queue number.", + "ar": "شكراً لصبرك، هذا هو رقم قائمة الانتظار الخاص بك." + }, + "servingNow": { + "en": "Serving Now", + "ar": "يُخدم الآن" + }, + "callForVitalSigns": { + "en": "Call for vital signs", + "ar": "نداء للعلامات الحيوية" + }, + "callForDoctor": { + "en": "Call for Doctor", + "ar": "نداء للطبيب" + }, + "thingsToAskDoctor": { + "en": "Things to ask your doctor today", + "ar": "أشياء تسأل طبيبك عنها اليوم" + }, + "improveOverallHealth": { + "en": "What can I do to improve my overall health?", + "ar": "ماذا يمكنني أن أفعل لتحسين صحتي العامة؟" + }, + "routineScreenings": { + "en": "Are there any routine screenings I should get?", + "ar": "هل هناك أي فحوصات روتينية يجب أن أجريها؟" + }, + "whatIsThisMedicationFor": { + "en": "What is this medication for?", + "ar": "لماذا هذا الدواء؟" + }, + "sideEffectsToKnow": { + "en": "Are there any side effects I should know about?", + "ar": "هل هناك أي آثار جانبية يجب أن أعرفها؟" + }, + "whenFollowUp": { + "en": "When should I come back for a follow-up?", + "ar": "متى يجب أن أعود للمتابعة؟" + }, + "goToHomepage": { + "en": "Go to homepage", + "ar": "الذهاب إلى الصفحة الرئيسية" + }, + "appointmentsList": { + "en": "Appointments List", + "ar": "قائمة المواعيد" + }, + "allAppt": { + "en": "All Appt.", + "ar": "جميع المواعيد" + }, + "upcoming": { + "en": "Upcoming", + "ar": "القادمة" + }, + "completed": { + "en": "Completed", + "ar": "المكتملة" + }, + "noAppointmentsYet": { + "en": "You don't have any appointments yet.", + "ar": "ليس لديك أي مواعيد بعد." + }, + "viewProfile": { + "en": "View Profile", + "ar": "عرض الملف الشخصي" + }, + "choosePreferredHospitalForService": { + "en": "Choose your preferred hospital for the service", + "ar": "اختر المستشفى المفضل لديك للخدمة" + }, + "noHospitalsFound": { + "en": "No hospitals Found", + "ar": "لم يتم العثور على مستشفيات" + }, + "cancelOrderConfirmation": { + "en": "Are you sure you want to cancel this order?", + "ar": "هل أنت متأكد أنك تريد إلغاء هذا الطلب؟" + }, + "orderCancelledSuccessfully": { + "en": "Order has been cancelled successfully", + "ar": "تم إلغاء الطلب بنجاح" + }, + "requestID": { + "en": "Request ID:", + "ar": "معرف الطلب:" + }, + "noCMCOrdersYet": { + "en": "You don't have any CMC orders yet.", + "ar": "ليس لديك أي طلبات فحص شامل بعد." + }, + "cmcOrders": { + "en": "CMC Orders", + "ar": "طلبات الفحص الشامل" + }, + "summary": { + "en": "Summary", + "ar": "الملخص" + }, + "selectedService": { + "en": "Selected Service", + "ar": "الخدمة المحددة" + }, + "requestSubmittedSuccessfully": { + "en": "Your request has been successfully submitted.", + "ar": "تم إرسال طلبك بنجاح." + }, + "hereIsYourRequestNumber": { + "en": "Here is your request #: ", + "ar": "هذا هو رقم طلبك #: " + }, + "pleaseSelectHospitalToContinue": { + "en": "Please select a hospital to continue", + "ar": "يرجى اختيار مستشفى للمتابعة" + }, + "confirmSubmitRequest": { + "en": "Are you sure you want to submit this request?", + "ar": "هل أنت متأكد أنك تريد إرسال هذا الطلب؟" + }, + "pendingOrderWait": { + "en": "You have a pending order. Please wait for it to be processed.", + "ar": "لديك طلب معلق. يرجى الانتظار حتى تتم معالجته." + }, + "noServicesAvailable": { + "en": "No services available", + "ar": "لا توجد خدمات متاحة" + }, + "selectAService": { + "en": "Select a Service", + "ar": "اختر خدمة" + }, + "comprehensiveCheckup": { + "en": "Comprehensive Checkup", + "ar": "الفحص الشامل" + }, + "viewNearestHMGLocations": { + "en": "View your nearest HMG locations", + "ar": "عرض أقرب مواقع مجموعة الحبيب الطبية" + }, + "provideFeedbackOnServices": { + "en": "Provide your feedback on our services", + "ar": "قدم ملاحظاتك على خدماتنا" + }, + "liveChatWithHMG": { + "en": "Live chat option with HMG", + "ar": "خيار الدردشة المباشرة مع مجموعة الحبيب الطبية" + }, + "send": { + "en": "Send", + "ar": "إرسال" + }, + "status": { + "en": "Status", + "ar": "الحالة" + }, + "sendingFeedback": { + "en": "Sending Feedback...", + "ar": "جاري إرسال الملاحظات..." + }, + "selectFeedbackType": { + "en": "Select Feedback Type", + "ar": "اختر نوع الملاحظات" + }, + "loadingAppointmentsList": { + "en": "Loading appointments list...", + "ar": "جاري تحميل قائمة المواعيد..." + }, + "noAppointmentsForFeedback": { + "en": "You do not have any appointments to submit a feedback.", + "ar": "ليس لديك أي مواعيد لتقديم ملاحظات عنها." + }, + "selectedAppointment": { + "en": "Selected Appointment:", + "ar": "الموعد المحدد:" + }, + "subject": { + "en": "Subject", + "ar": "الموضوع" + }, + "enterSubjectHere": { + "en": "Enter subject here", + "ar": "أدخل الموضوع هنا" + }, + "message": { + "en": "Message", + "ar": "الرسالة" + }, + "enterMessageHere": { + "en": "Enter message here", + "ar": "أدخل الرسالة هنا" + }, + "filesSelected": { + "en": "{count} file(s) selected", + "ar": "تم تحديد {count} ملف(ات)" + }, + "otherDetails": { + "en": "Other Details", + "ar": "تفاصيل أخرى" + }, + "medicalReport": { + "en": "Medical Report", + "ar": "التقرير الطبي" + }, + "medicalReportNumber": { + "en": "Medical Report {number}", + "ar": "التقرير الطبي {number}" + }, + "patientIsInsured": { + "en": "Patient Is Insured", + "ar": "المريض مؤمن عليه" + }, + "insuranceDocument": { + "en": "Insurance Document", + "ar": "وثيقة التأمين" + }, + "selectBranch": { + "en": "Select Branch", + "ar": "اختر الفرع" + }, + "patientInformation": { + "en": "Patient Information", + "ar": "معلومات المريض" + }, + "patientLocation": { + "en": "Where the patient is located", + "ar": "أين يتواجد المريض" + }, + "identificationNumber": { + "en": "Identification Number", + "ar": "رقم الهوية" + }, + "enterIdentificationNumber": { + "en": "Enter Identification Number*", + "ar": "أدخل رقم الهوية*" + }, + "patientName": { + "en": "Patient Name*", + "ar": "اسم المريض*" + }, + "referralRequesterInformation": { + "en": "Referral Requester Information", + "ar": "معلومات مقدم طلب الإحالة" + }, + "enterReferralRequesterName": { + "en": "Enter Referral Requester Name*", + "ar": "أدخل اسم مقدم طلب الإحالة*" + }, + "requesterName": { + "en": "Requester Name", + "ar": "اسم مقدم الطلب" + }, + "relationship": { + "en": "Relationship", + "ar": "العلاقة" + }, + "selectRelation": { + "en": "Select Relation", + "ar": "اختر العلاقة" + }, + "otherName": { + "en": "Other Name", + "ar": "اسم آخر" + }, + "otherNameHint": { + "en": "Other Name*", + "ar": "اسم آخر*" + }, + "requesterNameRequired": { + "en": "Referral requester name is required", + "ar": "اسم مقدم طلب الإحالة مطلوب" + }, + "selectRelationshipRequired": { + "en": "Please select a relationship", + "ar": "يرجى اختيار العلاقة" + }, + "otherRelationshipNameRequired": { + "en": "Other relationship name is required", + "ar": "اسم العلاقة الأخرى مطلوب" + }, + "identificationNumberRequired": { + "en": "Identification number is required", + "ar": "رقم الهوية مطلوب" + }, + "patientNameRequired": { + "en": "Patient name is required", + "ar": "اسم المريض مطلوب" + }, + "enterPatientPhoneRequired": { + "en": "Please Enter patient phone number", + "ar": "يرجى إدخال رقم هاتف المريض" + }, + "selectPatientCityRequired": { + "en": "Please select patient city", + "ar": "يرجى اختيار مدينة المريض" + }, + "medicalReportRequired": { + "en": "At least one medical report is required", + "ar": "مطلوب تقرير طبي واحد على الأقل" + }, + "selectBranchRequired": { + "en": "Please select a branch", + "ar": "يرجى اختيار الفرع" + }, + "insuranceDocumentRequired": { + "en": "Insurance document is required for insured patients", + "ar": "وثيقة التأمين مطلوبة للمرضى المؤمن عليهم" + }, + "searchResult": { + "en": "Search Result", + "ar": "نتيجة البحث" + }, + "referralNo": { + "en": "Referral No {number}", + "ar": "رقم الإحالة {number}" + }, + "eReferral": { + "en": "E Referral", + "ar": "الإحالة الإلكترونية" + }, + "referralCreatedSuccessfully": { + "en": "Your Referral has been created Successfully.", + "ar": "تم إنشاء إحالتك بنجاح." + }, + "hereIsYourReferralNumber": { + "en": "Here is your Referral #: ", + "ar": "هذا هو رقم الإحالة الخاص بك #: " + }, + "searchEReferral": { + "en": "Search E-Referral", + "ar": "البحث عن إحالة إلكترونية" + }, + "enterRequiredInfoToSearch": { + "en": "Please enter the required information to search for an e-referral", + "ar": "يرجى إدخال المعلومات المطلوبة للبحث عن إحالة إلكترونية" + }, + "selectPickupDirection": { + "en": "Select Pickup Direction", + "ar": "اختر اتجاه الاستلام" + }, + "selectDirection": { + "en": "Select Direction", + "ar": "اختر الاتجاه" + }, + "toHospital": { + "en": "To Hospital", + "ar": "إلى المستشفى" + }, + "fromHospital": { + "en": "From Hospital", + "ar": "من المستشفى" + }, + "selectWay": { + "en": "Select Way", + "ar": "اختر الطريقة" + }, + "oneWay": { + "en": "One Way", + "ar": "اتجاه واحد" + }, + "twoWay": { + "en": "Two Way", + "ar": "اتجاهين" + }, + "selectPickupDetails": { + "en": "Select Pickup Details", + "ar": "اختر تفاصيل الاستلام" + }, + "pleaseSelectDetailsOfPickup": { + "en": " Please select the details of pickup", + "ar": " يرجى تحديد تفاصيل الاستلام" + }, + "selectDetails": { + "en": "Select Details", + "ar": "اختر التفاصيل" + }, + "work": { + "en": "Work", + "ar": "العمل" + }, + "pick": { + "en": "Pick", + "ar": "استلام" + }, + "insideTheHome": { + "en": "Inside the home", + "ar": "داخل المنزل" + }, + "haveAnyAppointment": { + "en": "Have any appointment", + "ar": "هل لديك أي موعد" + }, + "amountPaidAtHospital": { + "en": "Amount will be paid at the hospital", + "ar": "سيتم دفع المبلغ في المستشفى" + }, + "submitRequest": { + "en": "Submit Request", + "ar": "إرسال الطلب" + }, + "enterPickupLocationManually": { + "en": "Enter Pickup Location Manually", + "ar": "أدخل موقع الاستلام يدوياً" + }, + "enterPickupLocation": { + "en": "Enter Pickup Location", + "ar": "أدخل موقع الاستلام" + }, + "trackingDetails": { + "en": "Tracking Details", + "ar": "تفاصيل التتبع" + }, + "cancelRequest": { + "en": "Cancel Request", + "ar": "إلغاء الطلب" + }, + "shareLocationWhatsapp": { + "en": "Share Your Live Location on Whatsapp", + "ar": "مشاركة موقعك المباشر على واتساب" + }, + "pleaseWaitForCall": { + "en": "Please wait for the call", + "ar": "يرجى انتظار المكالمة" + }, + "toHospitalLower": { + "en": "to hospital", + "ar": "إلى المستشفى" + }, + "contact": { + "en": "Contact", + "ar": "اتصال" + }, + "failed": { + "en": "Failed", + "ar": "فشل" + }, + "confirmationCall": { + "en": "Confirmation Call", + "ar": "مكالمة التأكيد" + }, + "pickupFromHome": { + "en": "Pickup Up from Home", + "ar": "الاستلام من المنزل" + }, + "onTheWayToHospital": { + "en": " On The Way To Hospital", + "ar": " في الطريق إلى المستشفى" + }, + "arrivedAtHospital": { + "en": "Arrived at Hospital", + "ar": "وصل إلى المستشفى" + }, + "orderCancel": { + "en": "Order Cancel", + "ar": "إلغاء الطلب" + }, + "emergencyCheckIn": { + "en": "Emergency Check-In", + "ar": "تسجيل الطوارئ الإلكتروني" + }, + "erOnlineCheckInDescription": { + "en": "This service lets patients register their ER appointment prior to arrival.", + "ar": "تتيح هذه الخدمة للمرضى تسجيل موعد الطوارئ قبل الوصول." + }, + "erOnlineCheckInSuccess": { + "en": "Your ER Online Check-In has been successfully done. Please proceed to the waiting area.", + "ar": "تم تسجيل وصول الطوارئ بنجاح. الرجاء التوجه إلى منطقة الانتظار." + }, + "erOnlineCheckInError": { + "en": "Unexpected error occurred during check-in. Please contact support.", + "ar": "حدث خطأ غير متوقع أثناء عملية التسجيل. يرجى التواصل مع الدعم." + }, + "fetchingHospitalsList": { + "en": "Fetching hospitals list...", + "ar": "جاري جلب قائمة المستشفيات..." + }, + "fetchingPaymentInformation": { + "en": "Fetching payment information...", + "ar": "جاري جلب معلومات الدفع..." + }, + "erVisitDetails": { + "en": "ER Visit Details", + "ar": "تفاصيل زيارة الطوارئ" + }, + "erClinic": { + "en": "ER Clinic", + "ar": "عيادة الطوارئ" + }, + "vatWithAmount": { + "en": "VAT 15% ({amount})", + "ar": "الضريبة 15% ({amount})" + }, + "erAppointmentBookedSuccess": { + "en": "Your appointment has been booked successfully. Please perform Check-In once you arrive at the hospital.", + "ar": "تم حجز موعدك بنجاح. يرجى إتمام إجراءات تسجيل الوصول عند وصولك إلى المستشفى." + }, + "underProcessing": { + "en": "Under processing", + "ar": "قيد المعالجة" + }, + "canceledByPatient": { + "en": "Cancelled by patient", + "ar": "ملغى بواسطة المريض" + }, + "rapidResponseTeam": { + "en": "Rapid Response Team", + "ar": "فريق الاستجابة السريع" + }, + "allFacilities": { + "en": "All Facilities", + "ar": "جميع المرافق" + }, + "selectLocation": { + "en": "Select Location", + "ar": "اختر الموقع" + }, + "pleaseSelectTheLocation": { + "en": "Please select the location", + "ar": "يرجى اختيار الموقع" + }, + "viewLocationGoogleMaps": { + "en": "View Location on Google Maps", + "ar": "عرض الموقع على خرائط جوجل" + }, + "callAmbulance": { + "en": "Call Ambulance", + "ar": "استدعاء سيارة إسعاف" + }, + "requestAmbulanceInEmergency": { + "en": "Request an ambulance in emergency from home or hospital", + "ar": "طلب سيارة إسعاف في حالة الطوارئ من المنزل أو المستشفى" + }, + "confirmation": { + "en": "Confirmation", + "ar": "تأكيد" + }, + "areYouSureYouWantToCallAmbulance": { + "en": "Are you sure you want to call an ambulance?", + "ar": "هل أنت متأكد أنك تريد استدعاء سيارة إسعاف؟" + }, + "getDetailsOfNearestBranch": { + "en": "Get the details of nearest branch including directions", + "ar": "احصل على تفاصيل أقرب فرع بما في ذلك الاتجاهات" + }, + "areYouSureYouWantToCallRRT": { + "en": "Are you sure you want to call Rapid Response Team (RRT)?", + "ar": "هل أنت متأكد أنك تريد استدعاء فريق الاستجابة السريعة (RRT)؟" + }, + "priorERCheckInToSkipLine": { + "en": "Prior ER Check-In to skip the line & payment at the reception.", + "ar": "تسجيل الوصول المسبق في الطوارئ لتجاوز الطابور والدفع في الاستقبال." + }, + "areYouSureYouWantToMakeERCheckIn": { + "en": "Are you sure you want to make ER Check-In?", + "ar": "هل أنت متأكد أنك تريد إجراء تسجيل وصول الطوارئ؟" + }, + "checkingYourERAppointmentStatus": { + "en": "Checking your ER Appointment status...", + "ar": "جاري التحقق من حالة موعد الطوارئ الخاص بك..." + }, + "transportOptions": { + "en": "Transport Options", + "ar": "خيارات النقل" + }, + "selectHospitalForAdvancePayment": { + "en": "Please select the hospital you want to make an advance payment for.", + "ar": "يرجى اختيار المستشفى الذي ترغب في دفع مبلغ مقدم له." + }, + "recharge": { + "en": "Recharge", + "ar": "إعادة الشحن" + }, + "activityLevel": { + "en": "Activity Level", + "ar": "مستوى النشاط" + }, + "selectActivityLevel": { + "en": "Select Activity Level", + "ar": "حدد مستوى النشاط" + }, + "caloriesPerDay": { + "en": "Calories Per Day", + "ar": "السعرات الحرارية في اليوم الواحد" + }, + "dietType": { + "en": "Diet Type", + "ar": "نوع النظام الغذائي" + }, + "selectDietType": { + "en": "Select Diet Type", + "ar": "حدد نوع النظام الغذائي" + }, + "bodyFrameSize": { + "en": "Body Frame Size", + "ar": "حجم إطار الجسم" + }, + "selectBodyFrameSize": { + "en": "Select Body Frame Size", + "ar": "حدد حجم إطار الجسم" + }, + "averageCycleLength": { + "en": "Average Cycle Length (Usually 28 days)", + "ar": "متوسط طول الدورة الشهرية (عادةً 28 يومًا)" + }, + "averageLutealPhase": { + "en": "Average Luteal Phase Length(Usually 14 days)", + "ar": "متوسط طول المرحلة الأصفرية (عادةً 14 يومًا)" + }, + "convert": { + "en": "Convert", + "ar": "يتحول" + }, + "calculate": { + "en": "Calculate", + "ar": "احسب" + }, + "healthCalculators": { + "en": "Health Calculators", + "ar": "حاسبات الصحة" + }, + "healthConverters": { + "en": "Health Converters", + "ar": "محولات الصحة" + }, + "generalHealth": { + "en": "General Health", + "ar": "الصحة العامة" + }, + "relatedToBMICalories": { + "en": "Related To BMI, calories, body fat, etc to stay updated with your health.", + "ar": "متعلق بمؤشر كتلة الجسم والسعرات الحرارية ودهون الجسم وما إلى ذلك للبقاء على اطلاع دائم بصحتك." + }, + "selectCalculator": { + "en": "Select Calculator", + "ar": "اختر الآلة الحاسبة" + }, + "womensHealth": { + "en": "Women's Health", + "ar": "صحة المرأة" + }, + "relatedToPeriodsOvulation": { + "en": "Related To periods, ovulation, pregnancy, and other topics.", + "ar": "متعلق بالدورة الشهرية والإباضة والحمل ومواضيع أخرى." + }, + "bloodSugar": { + "en": "Blood Sugar", + "ar": "سكر الدم" + }, + "trackYourGlucoseLevels": { + "en": "Track your glucose levels, understand trends, and get personalized insights for better health.", + "ar": "تتبع مستويات الجلوكوز لديك، وفهم الاتجاهات، واحصل على رؤى مخصصة لصحة أفضل." + }, + "bloodCholesterol": { + "en": "Blood Cholesterol", + "ar": "كوليسترول الدم" + }, + "monitorCholesterolLevels": { + "en": "Monitor cholesterol levels, assess heart health risks, and take proactive steps for well-being.", + "ar": "راقب مستويات الكوليسترول، وقيّم مخاطر صحة القلب، واتخذ خطوات استباقية للرفاهية." + }, + "triglyceridesFatBlood": { + "en": "Triglycerides Fat Blood", + "ar": "الدهون الثلاثية في الدم" + }, + "understandTriglyceridesImpact": { + "en": "Understand triglycerides' impact on heart health with personalized insights and expert recommendations.", + "ar": "افهم تأثير الدهون الثلاثية على صحة القلب مع رؤى مخصصة وتوصيات الخبراء." + }, + "bmiCalculator": { + "en": "BMI\nCalculator", + "ar": "حاسبة\nمؤشر كتلة الجسم" + }, + "caloriesCalculator": { + "en": "Calories\nCalculator", + "ar": "حاسبة\nالسعرات الحرارية" + }, + "bmrCalculator": { + "en": "BMR\nCalculator", + "ar": "حاسبة\nمعدل الأيض الأساسي" + }, + "idealBodyWeight": { + "en": "Ideal Body\nWeight", + "ar": "الوزن المثالي\nللجسم" + }, + "bodyFatCalculator": { + "en": "Body Fat\nCalculator", + "ar": "حاسبة\nدهون الجسم" + }, + "carbsProteinFat": { + "en": "Carbs\nProtein & Fat", + "ar": "الكربوهيدرات\nالبروتين والدهون" + }, + "ovulationPeriod": { + "en": "Ovulation\nPeriod", + "ar": "فترة\nالإباضة" + }, + "deliveryDueDate": { + "en": "Delivery\nDue Date", + "ar": "تاريخ الولادة\nالمتوقع" + }, + "low": { + "en": "Low", + "ar": "منخفض" + }, + "preDiabetic": { + "en": "Pre-diabetic", + "ar": "ما قبل السكري" + }, + "high": { + "en": "High", + "ar": "مرتفع" + }, + "elevated": { + "en": "Elevated", + "ar": "مرتفع قليلاً" + }, + "recorded": { + "en": "Recorded", + "ar": "مسجل" + }, + "noRecordsYet": { + "en": "No records yet", + "ar": "لا توجد سجلات بعد" + }, + "lastRecord": { + "en": "Last Record", + "ar": "آخر سجل" + }, + "addBloodSugar": { + "en": "Add Blood Sugar", + "ar": "إضافة سكر الدم" + }, + "addBloodPressure": { + "en": "Add Blood Pressure", + "ar": "إضافة ضغط الدم" + }, + "addWeight": { + "en": "Add Weight", + "ar": "إضافة الوزن" + }, + "bloodSugarDataSavedSuccessfully": { + "en": "Blood Sugar Data saved successfully", + "ar": "تم حفظ بيانات سكر الدم بنجاح" + }, + "bloodPressureDataSavedSuccessfully": { + "en": "Blood Pressure Data saved successfully", + "ar": "تم حفظ بيانات ضغط الدم بنجاح" + }, + "weightDataSavedSuccessfully": { + "en": "Weight Data saved successfully", + "ar": "تم حفظ بيانات الوزن بنجاح" + }, + "pleaseWait": { + "en": "Please wait", + "ar": "يرجى الانتظار" + }, + "selectUnit": { + "en": "Select Unit", + "ar": "اختر الوحدة" + }, + "selectMeasureTime": { + "en": "Select Measure Time", + "ar": "اختر وقت القياس" + }, + "selectArm": { + "en": "Select Arm", + "ar": "اختر الذراع" + }, + "enterBloodSugar": { + "en": "Enter Blood Sugar", + "ar": "أدخل سكر الدم" + }, + "enterSystolicValue": { + "en": "Enter Systolic Value", + "ar": "أدخل القيمة الانقباضية" + }, + "enterDiastolicValue": { + "en": "Enter Diastolic Value", + "ar": "أدخل القيمة الانبساطية" + }, + "enterWeight": { + "en": "Enter Weight", + "ar": "أدخل الوزن" + }, + "selectDuration": { + "en": "Select Duration", + "ar": "اختر المدة" + }, + "systolic": { + "en": "Systolic", + "ar": "الانقباضي" + }, + "diastolic": { + "en": "Diastolic", + "ar": "الانبساطي" + }, + "sendReportByEmail": { + "en": "Send Report by Email", + "ar": "إرسال التقرير عبر البريد الإلكتروني" + }, + "enterYourEmailToReceiveReport": { + "en": "Enter your email address to receive the report", + "ar": "أدخل عنوان بريدك الإلكتروني لاستلام التقرير" + }, + "addNewRecord": { + "en": "Add new Record", + "ar": "إضافة سجل جديد" + }, + "healthTrackers": { + "en": "Health Trackers", + "ar": "متتبعات الصحة" + }, + "monitorBloodPressureLevels": { + "en": "Monitor your blood pressure levels, track systolic and diastolic readings, and maintain a healthy heart.", + "ar": "راقب مستويات ضغط الدم لديك، وتتبع القراءات الانقباضية والانبساطية، وحافظ على صحة قلبك." + }, + "trackWeightProgress": { + "en": "Track your weight progress, set goals, and maintain a healthy body mass for overall wellness.", + "ar": "تتبع تقدم وزنك، وضع الأهداف، وحافظ على كتلة جسم صحية من أجل العافية الشاملة." + }, + "bookAppointment": { + "en": "Book Appointment", + "ar": "احجز موعد" + }, + "completeCheckup": { + "en": "Complete Checkup", + "ar": "الفحص الشامل" + }, + "indoorNavigation": { + "en": "Indoor Navigation", + "ar": "الملاحة الداخلية" + }, + "eReferralServices": { + "en": "E-Referral Services", + "ar": "خدمات الإحالة الإلكترونية" + }, + "dailyWaterMonitor": { + "en": "Daily Water Monitor", + "ar": "مراقب الماء اليومي" + }, + "fetchingYourWaterIntakeDetails": { + "en": "Fetching your water intake details.", + "ar": "جاري جلب تفاصيل استهلاك الماء الخاص بك." + }, + "healthCalculatorsServices": { + "en": "Health\nCalculators", + "ar": "حاسبات\nالصحة" + }, + "healthConvertersServices": { + "en": "Health\nConverters", + "ar": "محولات\nالصحة" + }, + "smartWatchesServices": { + "en": "Smart\nWatches", + "ar": "الساعات\nالذكية" + }, + "exploreServices": { + "en": "Explore Services", + "ar": "استكشف الخدمات" + }, + "medicalAndCareServices": { + "en": "Medical & Care Services", + "ar": "الخدمات الطبية والرعاية" + }, + "hmgServices": { + "en": "HMG Services", + "ar": "خدمات مجموعة الحبيب الطبية" + }, + "personalServices": { + "en": "Personal Services", + "ar": "الخدمات الشخصية" + }, + "habibWallet": { + "en": "Habib Wallet", + "ar": "محفظة الحبيب" + }, + "loginToViewWalletBalance": { + "en": "Login to view your wallet balance", + "ar": "سجل الدخول لعرض رصيد محفظتك" + }, + "loginToViewMedicalFile": { + "en": "Login to view your medical file", + "ar": "سجل الدخول لعرض ملفك الطبي" + }, + "addMember": { + "en": "Add Member", + "ar": "إضافة عضو" + }, + "addFamilyMember": { + "en": "Add Family Member", + "ar": "إضافة فرد من العائلة" + }, + "pleaseFillBelowFieldToAddNewFamilyMember": { + "en": "Please fill the below field to add a new family member to your profile", + "ar": "يرجى ملء الحقل أدناه لإضافة فرد جديد من العائلة إلى ملفك الشخصي" + }, + "healthTools": { + "en": "Health Tools", + "ar": "أدوات الصحة" + }, + "supportServices": { + "en": "Support Services", + "ar": "خدمات الدعم" + }, + "virtualTour": { + "en": "Virtual Tour", + "ar": "جولة افتراضية" + }, + "carParking": { + "en": "Car Parking", + "ar": "موقف السيارات" + }, + "latestNews": { + "en": "Latest News", + "ar": "آخر الأخبار" + }, + "hmgContact": { + "en": "HMG Contact", + "ar": "اتصل بمجموعة الحبيب الطبية" + }, + "durationCannotExceed90": { + "en": "Duration can not exceed 90 mins", + "ar": "لا يجوز أن تتجاوز المدة 90 دقيقة" + }, + "unexpectedError": { + "en": "Unexpected Error Occurred", + "ar": "حدث خطأ غير متوقع" + }, + "gettingAmbulanceTransportOption": { + "en": "Getting Ambulance Transport Option", + "ar": "جاري الحصول على خيارات نقل الإسعاف" + }, + "fetchingAppointment": { + "en": "Fetching Appointment", + "ar": "جاري جلب الموعد" + }, + "doYouWantToCancelTheRequest": { + "en": "Do you want to cancel the request", + "ar": "هل تريد إلغاء الطلب" + }, + "cancellingRequest": { + "en": "Cancelling request", + "ar": "جاري إلغاء الطلب" + }, + "fetchingTermsAndConditions": { + "en": "Fetching Terms And Conditions", + "ar": "جاري جلب الشروط والأحكام" + }, + "selectLocationPrescriptionDelivery": { + "en": "Please select the location for prescription delivery", + "ar": "يرجى تحديد موقع توصيل الوصفة الطبية" + }, + "noRadiologyOrders": { + "en": "No Radiology Orders Found", + "ar": "لم يتم العثور على أي طلبات تصوير شعاعي" + }, + "ageIsRequired": { + "en": "Age is required", + "ar": "العمر مطلوب" + }, + "invalidAge": { + "en": "Invalid age", + "ar": "العمر غير صالح" + }, + "ageMustBeBetween11And120": { + "en": "Age must be between 11 and 120", + "ar": "يجب أن يكون العمر بين 11 و 120" + }, + "heightIsRequired": { + "en": "Height is required", + "ar": "الطول مطلوب" + }, + "invalidHeight": { + "en": "Invalid height", + "ar": "الطول غير صالح" + }, + "weightIsRequired": { + "en": "Weight is required", + "ar": "الوزن مطلوب" + }, + "invalidWeight": { + "en": "Invalid weight", + "ar": "الوزن غير صالح" + }, + "timeToDrinkWater": { + "en": "Time to Drink Water! 💧", + "ar": "حان وقت شرب الماء! 💧" + }, + "stayHydratedDrinkWater": { + "en": "Stay hydrated! Drink {amount}ml of water.", + "ar": "ابق رطبًا! اشرب {amount} مل من الماء." + }, + "visitPharmacyOnline": { + "en": "Visit Pharmacy Online", + "ar": "زيارة الصيدلية على الانترنت" + }, + "howAreYouFeelingToday": { + "en": "How are you feeling today?", + "ar": "كيف حالك اليوم؟" + }, + "checkYourSymptomsWithScale": { + "en": "Check your symptoms with this scale", + "ar": "تحقق من أعراضك باستخدام ذا المقياس" + }, + "checkYourSymptoms": { + "en": "Check your symptoms", + "ar": "تحقق من أعراضك" + }, + "noUpcomingAppointmentPleaseBook": { + "en": "You do not have any upcoming appointment. Please book an appointment", + "ar": "ليس لديك أي مواعيد قادمة. يرجى حجز موعد" + }, + "youHaveEROnlineCheckInRequest": { + "en": "You have ER Online Check-In Request", + "ar": "لديك طلب تسجيل وصول عبر الإنترنت للطوارئ" + }, + "quickLinks": { + "en": "Quick Links", + "ar": "روابط سريعة" + }, + "viewMedicalFileLandingPage": { + "en": "View medical file", + "ar": "عرض الملف الطبي" + }, + "immediateLiveCareRequest": { + "en": "Immediate LiveCare Request", + "ar": "طلب لايف كير فوري" + }, + "yourTurnIsAfterPatients": { + "en": "Your turn is after {count} patients.", + "ar": "دورك بعد {count} مريض." + }, + "dontHaveHHCOrders": { + "en": "You don't have any Home Health Care orders yet.", + "ar": "ليس لديك أي أوامر رعاية صحية منزلية حتى الآن." + }, + "hhcOrders": { + "en": "HHC Orders", + "ar": "أوامر الرعاية الصحية المنزلية" + }, + "requestedServices": { + "en": "Requested Services", + "ar": "الخدمات المطلوبة" + }, + "selectServices": { + "en": "Select Services", + "ar": "اختر الخدمات" + }, + "selectedServices": { + "en": "Selected Services", + "ar": "الخدمات المختارة" + }, + "createNewRequest": { + "en": "Create new request", + "ar": "إنشاء طلب جديد" + }, + "youHaveNoPendingRequests": { + "en": "You have no pending requests.", + "ar": "ليس لديك أي طلبات معلقة." + }, + "noInsuranceDataFound": { + "en": "No insurance data found...", + "ar": "لم يتم العثور على بيانات التأمين..." + }, + "noInsuranceUpdateRequest": { + "en": "No insurance update requests found.", + "ar": "لم يتم العثور على أي طلبات لتحديث بيانات التأمين." + }, + "policyNumberInsurancePage": { + "en": "Policy: {number}", + "ar": "الوثيقة: {number}" + }, + "insuranceExpired": { + "en": "Insurance Expired", + "ar": "التأمين منتهي الصلاحية" + }, + "insuranceActive": { + "en": "Insurance Active", + "ar": "التأمين نشط" + }, + "patientCardID": { + "en": "Patient Card ID: {id}", + "ar": "رقم بطاقة المريض: {id}" + }, + "noInsuranceApprovals": { + "en": "You don't have any insurance approvals yet.", + "ar": "لم تحصل على أي موافقات تأمينية حتى الآن." + }, + "noInsuranceWithHMG": { + "en": "You don't have an insurance registered with HMG.", + "ar": "ليس لديك تأمين مسجل لدى مجموعة الحبيب الطبية." + }, + "referenceRange": { + "en": "Reference Range", + "ar": "النطاق المرجعي" + }, + "downloadReport": { + "en": "Download Report", + "ar": "تنزيل التقرير" + }, + "generatingReport": { + "en": "Generating Report, Please wait...", + "ar": "جارٍ إنشاء التقرير، يرجى الانتظار..." + }, + "noLabResults": { + "en": "You don't have any lab results yet.", + "ar": "ليس لديك أي نتائج مختبرية حتى الآن." + }, + "labResultDetails": { + "en": "Lab Result Details", + "ar": "تفاصيل نتائج المختبر" + }, + "resultOf": { + "en": "Result of {date}", + "ar": "نتيجة {date}" + }, + "whatIsThisResult": { + "en": "What is this result?", + "ar": "ما هي هذه النتيجة؟" + }, + "lastTested": { + "en": "Last Tested", + "ar": "آخر اختبار" + }, + "byVisit": { + "en": "By Visit", + "ar": "حسب الزيارة" + }, + "byTest": { + "en": "By Test", + "ar": "حسب التحليل" + }, + "results": { + "en": "results", + "ar": "نتائج" + }, + "viewResults": { + "en": "View Results", + "ar": "عرض النتائج" + }, + "rebook": { + "en": "Rebook", + "ar": "إعادة الحجز" + }, + "noOphthalmologyAppointments": { + "en": "No Ophthalmology appointments found...", + "ar": "لم يتم العثور على أي مواعيد في قسم طب العيون..." + }, + "noVitalSignsRecordedYet": { + "en": "No vital signs recorded yet", + "ar": "لا توجد علامات حيوية مسجلة بعد" + }, + "appointmentsAndVisits": { + "en": "Appointments & visits", + "ar": "المواعيد والزيارات" + }, + "labAndRadiology": { + "en": "Lab & Radiology", + "ar": "المختبر والأشعة" + }, + "activeMedicationsAndPrescriptions": { + "en": "Active Medications & Prescriptions", + "ar": "الأدوية النشطة والوصفات الطبية" + }, + "allPrescriptions": { + "en": "All Prescriptions", + "ar": "جميع الوصفات" + }, + "allMedications": { + "en": "All Medications", + "ar": "جميع الأدوية" + }, + "youDontHaveAnyPrescriptionsYet": { + "en": "You don't have any prescriptions yet.", + "ar": "ليس لديك أي وصفات طبية بعد." + }, + "youDontHaveAnyCompletedVisitsYet": { + "en": "You don't have any completed visits yet", + "ar": "ليس لديك أي زيارات مكتملة بعد" + }, + "others": { + "en": "Others", + "ar": "أخرى" + }, + "allergyInfo": { + "en": "Allergy Info", + "ar": "معلومات الحساسية" + }, + "vaccineInfo": { + "en": "Vaccine Info", + "ar": "معلومات اللقاحات" + }, + "updateInsuranceInfo": { + "en": "Update Insurance", + "ar": "تحديث التأمين" + }, + "myInvoicesList": { + "en": "My Invoices List", + "ar": "قائمة فواتيري" + }, + "ancillaryOrdersList": { + "en": "Ancillary Orders List", + "ar": "قائمة الطلبات المساعدة" + }, + "youDontHaveAnySickLeavesYet": { + "en": "You don't have any sick leaves yet.", + "ar": "ليس لديك أي إجازات مرضية بعد." + }, + "medicalReports": { + "en": "Medical Reports", + "ar": "التقارير الطبية" + }, + "sickLeaveReport": { + "en": "Sick Leave Report", + "ar": "تقرير الإجازة المرضية" + }, + "weightTracker": { + "en": "Weight Tracker", + "ar": "متتبع الوزن" + }, + "askYourDoctor": { + "en": "Ask Your Doctor", + "ar": "اسأل طبيبك" + }, + "internetPairing": { + "en": "Internet Pairing", + "ar": "الاقتران بالإنترنت" + }, + "requested": { + "en": "Requested", + "ar": "مطلوب" + }, + "youDontHaveAnyMedicalReportsYet": { + "en": "You don't have any medical reports yet.", + "ar": "ليس لديك أي تقارير طبية بعد." + }, + "requestMedicalReport": { + "en": "Request medical report", + "ar": "طلب تقرير طبي" + }, + "youDoNotHaveAnyAppointmentsToRequestMedicalReport": { + "en": "You do not have any appointments to request a medical report.", + "ar": "ليس لديك أي مواعيد لطلب تقرير طبي." + }, + "areYouSureYouWantToRequestMedicalReport": { + "en": "Are you sure you want to request a medical report for this appointment?", + "ar": "هل أنت متأكد أنك تريد طلب تقرير طبي لهذا الموعد؟" + }, + "yourMedicalReportRequestSubmittedSuccessfully": { + "en": "Your medical report request has been successfully submitted.", + "ar": "تم إرسال طلب التقرير الطبي بنجاح." + }, + "monthlyHealthSummaryReportDisclaimer": { + "en": "This monthly health summary report reflects the health indicators and analysis results of the latest visits. Please note that this will be sent automatically from the system and it's not considered as a official report so no medical decision should be taken based on it", + "ar": "يعكس تقرير الملخص الصحي الشهري هذا المؤشرات الصحية ونتائج التحليل لأحدث الزيارات. يرجى ملاحظة أن هذا سيتم إرساله تلقائيًا من النظام ولا يعتبر تقريرًا رسميًا لذا لا ينبغي اتخاذ أي قرار طبي بناءً عليه" + }, + "updatingMonthlyReportStatus": { + "en": "Updating Monthly Report Status...", + "ar": "جاري تحديث حالة التقرير الشهري..." + }, + "monthlyReportStatusUpdatedSuccessfully": { + "en": "Monthly Report Status Updated Successfully", + "ar": "تم تحديث حالة التقرير الشهري بنجاح" + }, + "whoCanViewMyMedicalFile": { + "en": "Who can view my medical file?", + "ar": "من يمكنه عرض ملفي الطبي؟" + }, + "acceptedYourRequestToBeYourFamilyMember": { + "en": "{status} your request to be your family member", + "ar": "{status} طلب الانضمام الى أفراد عائلتك" + }, + "canViewYourFile": { + "en": "can view your file", + "ar": "يمكنه عرض ملفك" + }, + "hasARequestPendingToBeYourFamilyMember": { + "en": "has a request {status} to be your family member", + "ar": "لديه طلب {status} ليكون فردًا من عائلتك" + }, + "wantsToAddYouAsTheirFamilyMember": { + "en": "wants to add you as their family member", + "ar": "يرغب في إضافتك كفرد من أفراد العائلة" + }, + "rejectedYourRequestToBeYourFamilyMember": { + "en": "{status} your request to be your family member", + "ar": "{status} طلب الانضمام إلى عائلتك" + }, + "rejectedYourFamilyMemberRequest": { + "en": "{status} your family member request", + "ar": "{status} طلب أحد أفراد عائلتك" + }, + "notAvailable": { + "en": "N/A", + "ar": "غير متاح" + }, + "selectAProfile": { + "en": "Please select a profile", + "ar": "الرجاء تحديد ملف تعريف" + }, + "switchFamilyFile": { + "en": "Switch from the below list of medical file", + "ar": "قم بالتبديل من قائمة الملفات الطبية أدناه" + }, + "medicalFiles": { + "en": "Medical Files", + "ar": "الملفات الطبية" + }, + "addANewFamilyMember": { + "en": "Add a new family member", + "ar": "إضافة فرد جديد من العائلة" + }, + "viewInvoiceDetails": { + "en": "View invoice details", + "ar": "عرض تفاصيل الفاتورة" + }, + "outPatient": { + "en": "OutPatient", + "ar": "مريض خارجي" + }, + "invoiceDetails": { + "en": "Invoice Details", + "ar": "تفاصيل الفاتورة" + }, + "sendingEmailPleaseWait": { + "en": "Sending email, Please wait...", + "ar": "جاري إرسال البريد الإلكتروني، يرجى الانتظار..." + }, + "emailSentSuccessfullyMessage": { + "en": "Email sent successfully.", + "ar": "تم إرسال البريد الإلكتروني بنجاح." + }, + "discount": { + "en": "Discount", + "ar": "خصم" + }, + "paid": { + "en": "Paid", + "ar": "مدفوع" + }, + "fetchingInvoiceDetails": { + "en": "Fetching invoice details, Please wait...", + "ar": "جارٍ جلب تفاصيل الفاتورة، يرجى الانتظار..." + }, + "scanQRCode": { + "en": "Scan QR code", + "ar": "مسح رمز الاستجابة السريعة" + }, + "parkingSlotDetails": { + "en": "Parking Slot Details", + "ar": "تفاصيل موقف السيارة" + }, + "slotNumber": { + "en": "Slot: {code}", + "ar": "رقم الموقف: {code}" + }, + "basement": { + "en": "Basement: {description}", + "ar": "الطابق: {description}" + }, + "parkingDate": { + "en": "Date: {date}", + "ar": "التاريخ: {date}" + }, + "parkedSince": { + "en": "Parked Since: {time}", + "ar": "متوقف منذ: {time}" + }, + "resetDirection": { + "en": "Reset Direction", + "ar": "إعادة تعيين الاتجاه" + }, + "noPrescriptionOrdersYet": { + "en": "You don't have any prescription orders yet.", + "ar": "ليس لديك أي طلبات وصفات طبية حتى الآن." + }, + "fetchingPrescriptionPDFPleaseWait": { + "en": "Fetching prescription PDF, Please wait...", + "ar": "جاري جلب ملف الوصفة الطبية، يرجى الانتظار..." + }, + "ratingValue": { + "en": "Rating: {rating}", + "ar": "التقييم: {rating}" + }, + "downloadPrescription": { + "en": "Download Prescription", + "ar": "تحميل الوصفة الطبية" + }, + "fetchingPrescriptionDetails": { + "en": "Fetching prescription details...", + "ar": "جاري جلب تفاصيل الوصفة الطبية..." + }, + "switchBackFamilyFile": { + "en": "Switch Back To Family File", + "ar": "العودة إلى ملف العائلة" + }, + "profileAndSettings": { + "en": "Profile & Settings", + "ar": "الملف الشخصي والإعدادات" + }, + "quickActions": { + "en": "Quick Actions", + "ar": "إجراءات سريعة" + }, + "notificationsSettings": { + "en": "Notifications Settings", + "ar": "إعدادات الإشعارات" + }, + "touchIDFaceIDServices": { + "en": "Touch ID / Face ID Services", + "ar": "خدمات Touch ID / Face ID" + }, + "personalInformation": { + "en": "Personal Information", + "ar": "المعلومات الشخصية" + }, + "updateEmailAddress": { + "en": "Update Email Address", + "ar": "تحديث عنوان البريد الإلكتروني" + }, + "helpAndSupport": { + "en": "Help & Support", + "ar": "المساعدة والدعم" + }, + "permissionsProfile": { + "en": "Permissions", + "ar": "الأذونات" + }, + "privacyPolicy": { + "en": "Privacy Policy", + "ar": "سياسة الخصوصية" + }, + "deactivateAccount": { + "en": "Deactivate account", + "ar": "إلغاء تنشيط الحساب" + }, + "ageYearsOld": { + "en": "{age} {yearsOld}", + "ar": "{age} {yearsOld}" + }, + "youDontHaveRadiologyOrders": { + "en": "You don't have any radiology results yet.", + "ar": "ليس لديك أي نتائج للأشعة حتى الآن." + }, + "radiologyResult": { + "en": "Radiology Result", + "ar": "نتيجة الأشعة" + }, + "viewRadiologyImage": { + "en": "View Radiology Image", + "ar": "عرض صورة الأشعة" + }, + "rateClinic": { + "en": "Rate Clinic", + "ar": "تقييم العيادة" + }, + "back": { + "en": "Back", + "ar": "رجوع" + }, + "rateDoctor": { + "en": "Rate Doctor", + "ar": "تقييم الطبيب" + }, + "howWasYourLastVisitWithDoctor": { + "en": "How was your last visit with doctor?", + "ar": "كيف كانت زيارتك الأخيرة مع الطبيب؟" + }, + "dateOfBirthSymptoms": { + "en": "What is your Date of Birth?", + "ar": "ما هو تاريخ ميلادك؟" + }, + "genderSymptoms": { + "en": "What is your gender?", + "ar": "ما هو جنسك؟" + }, + "heightSymptoms": { + "en": "How tall are you?", + "ar": "كم طولك؟" + }, + "weightSymptoms": { + "en": "What is your weight?", + "ar": "ما هو وزنك؟" + }, + "femaleGender": { + "en": "Female", + "ar": "أنثى" + }, + "previous": { + "en": "Previous", + "ar": "سابق" + }, + "selectedOrgans": { + "en": "Selected Organs", + "ar": "الهيئات المختارة" + }, + "noOrgansSelected": { + "en": "No organs selected yet", + "ar": "لم يتم تحديد أي أعضاء بعد" + }, + "organSelector": { + "en": "Organ Selector", + "ar": "محدد الأعضاء" + }, + "noPredictionsAvailable": { + "en": "No Predictions available", + "ar": "لا توجد تنبؤات متاحة" + }, + "areYouSureYouWantToRestartOrganSelection": { + "en": "Are you sure you want to restart the organ selection?", + "ar": "هل أنت متأكد أنك تريد إعادة تشغيل اختيار الأعضاء؟" + }, + "possibleConditions": { + "en": "Possible Conditions", + "ar": "الحالات المحتملة" + }, + "pleaseSelectAtLeastOneRiskBeforeProceeding": { + "en": "Please select at least one risk before proceeding", + "ar": "يرجى اختيار عامل خطر واحد على الأقل قبل المتابعة" + }, + "aboveYouSeeCommonRiskFactors": { + "en": "Above you see the most common risk factors. Although /diagnosis may return questions about risk factors, ", + "ar": "أعلاه ترى عوامل الخطر الأكثر شيوعًا. على الرغم من أن /diagnosis قد تعيد أسئلة حول عوامل الخطر، " + }, + "readMore": { + "en": "Read more", + "ar": "اقرأ المزيد" + }, + "riskFactors": { + "en": "Risk Factors", + "ar": "عوامل الخطر" + }, + "noRiskFactorsFound": { + "en": "No risk factors found", + "ar": "لم يتم العثور على عوامل خطر" + }, + "basedOnYourSelectedSymptomsNoRiskFactors": { + "en": "Based on your selected symptoms, no additional risk factors were identified.", + "ar": "بناءً على الأعراض المحددة، لم يتم تحديد عوامل خطر إضافية." + }, + "messageNotification": { + "en": "Message", + "ar": "الرسالة" + }, + "attachedImage": { + "en": "Attached Image", + "ar": "الصورة المرفقة" + }, + "failedToLoadImage": { + "en": "Failed to load image", + "ar": "فشل تحميل الصورة" + }, + "typeNotification": { + "en": "Type", + "ar": "النوع" + }, + "pleaseSelectAtLeastOneOptionBeforeProceeding": { + "en": "Please select at least one option before proceeding", + "ar": "يرجى اختيار خيار واحد على الأقل قبل المتابعة" + }, + "suggestions": { + "en": "Suggestions", + "ar": "الاقتراحات" + }, + "pleaseGoBackAndSelectOrgansFirst": { + "en": "Please go back and select organs first", + "ar": "يرجى العودة واختيار الأعضاء أولاً" + }, + "symptomsSelector": { + "en": "Symptoms Selector", + "ar": "محدد الأعراض" + }, + "possibleSymptomsRelatedTo": { + "en": "Possible symptoms related to", + "ar": "الأعراض المحتملة المتعلقة بـ" + }, + "suggestionAIListDescription": { + "en": "This is a list of symptoms suggested by our AI, based on the information gathered so far during the interview", + "ar": "هذه قائمة بالأعراض المقترحة من قبل الذكاء الاصطناعي، بناءً على المعلومات التي تم جمعها حتى الآن خلال المقابلة" + }, + "analyzing": { + "en": "Analyzing...", + "ar": "جاري التحليل..." + }, + "seekMedicalAdvice": { + "en": "Seek Medical Advice", + "ar": "اطلب المشورة الطبية" + }, + "monitorDescription": { + "en": "No need to seek medical advice. Just keep healthy routine.", + "ar": "لا حاجة لطلب المشورة الطبية. فقط حافظ على روتين صحي." + }, + "seekMedicalAdviceDescription": { + "en": "Not emergency but better to monitor the symptoms.", + "ar": "ليست حالة طوارئ ولكن من الأفضل مراقبة الأعراض." + }, + "emergencyDescription": { + "en": "Need to consult doctor as soon as possible before getting too late.", + "ar": "تحتاج إلى استشارة الطبيب في أقرب وقت ممكن قبل فوات الأوان." + }, + "colorScience": { + "en": "Color Science", + "ar": "دلالات الألوان" + }, + "noNeedToVisitDoctor": { + "en": "No need to visit doctor", + "ar": "لا حاجة لزيارة الطبيب" + }, + "commonSymptom": { + "en": "Common Symptom", + "ar": "الأعراض الشائعة" + }, + "notApplicable": { + "en": "Not Applicable", + "ar": "لا ينطبق" + }, + "emergencyTriage": { + "en": "Emergency", + "ar": "طوارئ" + }, + "emergencyEvidenceDetected": { + "en": "Emergency evidence detected. Please seek medical attention.", + "ar": "تم اكتشاف دليل طوارئ. يرجى طلب العناية الطبية." + }, + "noQuestionItemsAvailable": { + "en": "No question items available", + "ar": "لا توجد عناصر أسئلة متاحة" + }, + "pleaseAnswerAllQuestionsBeforeProceeding": { + "en": "Please answer all questions before proceeding", + "ar": "يرجى الإجابة على جميع الأسئلة قبل المتابعة" + }, + "triage": { + "en": "Triage", + "ar": "الفرز" + }, + "areYouSureYouWantToExitProgress": { + "en": "Are you sure you want to exit? Your progress will be lost.", + "ar": "هل أنت متأكد أنك تريد الخروج؟ سيتم فقدان تقدمك." + }, + "noQuestionAvailable": { + "en": "No question available", + "ar": "لا يوجد سؤال متاح" + }, + "possibleSymptom": { + "en": "Possible symptom: ", + "ar": "عرض محتمل: " + }, + "symptomsCheckerFindingScore": { + "en": "- Symptoms checker finding score", + "ar": "- درجة نتائج فاحص الأعراض" + }, + "notSet": { + "en": "Not set", + "ar": "غير محدد" + }, + "years": { + "en": "Years", + "ar": "سنوات" + }, + "symptomsChecker": { + "en": "Symptoms Checker", + "ar": "فاحص الأعراض" + }, + "helloIsYourInformationUpToDate": { + "en": "Hello {name}, Is your information up to date?", + "ar": "مرحباً {name}، هل معلوماتك محدثة؟" + }, + "noEditAll": { + "en": "No, Edit all", + "ar": "لا، تعديل الكل" + }, + "yesItIs": { + "en": "Yes, It is", + "ar": "نعم، إنها كذلك" + }, + "age": { + "en": "Age", + "ar": "العمر" + }, + "youDontHaveAnyAncillaryOrdersYet": { + "en": "You don't have any ancillary orders yet.", + "ar": "ليس لديك أي طلبات مساعدة بعد." + }, + "invoiceWithNumber": { + "en": "Invoice: {invoiceNo}", + "ar": "الفاتورة: {invoiceNo}" + }, + "queued": { + "en": "Queued", + "ar": "في قائمة الانتظار" + }, + "checkInReady": { + "en": "Check-in Ready", + "ar": "جاهز للتسجيل" + }, + "checkIn": { + "en": "Check In", + "ar": "تسجيل الوصول" + }, + "viewDetails": { + "en": "View Details", + "ar": "عرض التفاصيل" + }, + "selectPaymentMethod": { + "en": "Select Payment Method", + "ar": "اختر طريقة الدفع" + }, + "processingPaymentPleaseWait": { + "en": "Processing payment, Please wait...", + "ar": "جاري معالجة الدفع، يرجى الانتظار..." + }, + "finalizingPaymentPleaseWait": { + "en": "Finalizing payment, Please wait...", + "ar": "جاري إتمام الدفع، يرجى الانتظار..." + }, + "generatingInvoicePleaseWait": { + "en": "Generating invoice, Please wait...", + "ar": "جاري إنشاء الفاتورة، يرجى الانتظار..." + }, + "hereIsYourInvoiceNumber": { + "en": "Here is your invoice #: ", + "ar": "هذا هو رقم فاتورتك #: " + }, + "paymentCompletedSuccessfully": { + "en": "Payment Completed Successfully", + "ar": "تم الدفع بنجاح" + }, + "failedToInitializeApplePay": { + "en": "Failed to initialize Apple Pay. Please try again.", + "ar": "فشل في تهيئة Apple Pay. يرجى المحاولة مرة أخرى." + }, + "cash": { + "en": "Cash", + "ar": "نقدي" + }, + "approved": { + "en": "Approved", + "ar": "موافق عليه" + }, + "approvalRejectedPleaseVisitReceptionist": { + "en": "Approval Rejected - Please visit receptionist", + "ar": "تم رفض الموافقة - يرجى زيارة موظف الاستقبال" + }, + "sentForApproval": { + "en": "Sent For Approval", + "ar": "تم إرساله للموافقة" + }, + "ancillaryOrderDetails": { + "en": "Ancillary Order Details", + "ar": "تفاصيل الطلبات المساندة" + }, + "noProceduresAvailableForSelectedOrder": { + "en": "No Procedures available for the selected order.", + "ar": "لا توجد إجراءات متاحة للطلب المحدد." + }, + "procedures": { + "en": "Procedures", + "ar": "الإجراءات" + }, + "totalAmount": { + "en": "Total Amount", + "ar": "المبلغ الإجمالي" + }, + "covered": { + "en": "Covered", + "ar": "مغطى" + }, + "vatPercent": { + "en": "VAT (15%)", + "ar": "ضريبة القيمة المضافة (15%)" + }, + "proceedToPayment": { + "en": "Proceed to Payment", + "ar": "المتابعة للدفع" + }, + "supportedSmartWatches": { + "en": "Supported Smart Watches", + "ar": "الساعات الذكية المدعومة" + }, + "pleaseMakeSureSamsungWatchConnected": { + "en": "Please make sure that your Samsung Watch is connected to your Phone, is actively synced & updated.", + "ar": "يرجى التأكد من أن ساعة Samsung الخاصة بك متصلة بهاتفك، ومتزامنة ومحدثة بشكل نشط." + }, + "beforeSyncingDataFollowInstructions": { + "en": "Before syncing data, please make sure that you have followed the instructions properly.", + "ar": "قبل مزامنة البيانات، يرجى التأكد من اتباع التعليمات بشكل صحيح." + }, + "viewWatchInstructions": { + "en": "View watch instructions", + "ar": "عرض تعليمات الساعة" + }, + "healthConnectAppNotInstalled": { + "en": "Seems like you do not have Health Connect App installed. Please install it from the Play Store to sync your health data.", + "ar": "يبدو أنه ليس لديك تطبيق Health Connect مثبتًا. يرجى تثبيته من متجر Play لمزامنة بيانات صحتك." + }, + "setTimerOfReminder": { + "en": "Set the timer of reminder", + "ar": "ضبط مؤقت التذكير" + }, + "youHaveAppointmentWithDr": { + "en": "You have appointment with Dr. ", + "ar": "لديك موعد مع د. " + }, + "hours": { + "en": "Hours", + "ar": "ساعات" + }, + "secs": { + "en": "Secs", + "ar": "ثواني" + }, + "noAllergiesDataFound": { + "en": "No allergies data found...", + "ar": "لم يتم العثور على بيانات الحساسية..." + }, + "heartRateDescription": { + "en": "Your heart rate indicates how many times your heart beats per minute", + "ar": "معدل ضربات قلبك يشير إلى عدد المرات التي ينبض فيها قلبك في الدقيقة" + }, + "bloodOxygenDescription": { + "en": "Blood oxygen level indicates how much oxygen your red blood cells are carrying", + "ar": "مستوى الأكسجين في الدم يشير إلى كمية الأكسجين التي تحملها خلايا الدم الحمراء" + }, + "stepsDescription": { + "en": "Number of steps taken throughout the day", + "ar": "عدد الخطوات المتخذة على مدار اليوم" + }, + "caloriesDescription": { + "en": "Calories burned during physical activity", + "ar": "السعرات الحرارية المحروقة أثناء النشاط البدني" + }, + "distanceDescription": { + "en": "Distance covered throughout the day", + "ar": "المسافة المقطوعة على مدار اليوم" + }, + "overview": { + "en": "Overview", + "ar": "نظرة عامة" + }, + "details": { + "en": "Details", + "ar": "التفاصيل" + }, + "healthy": { + "en": "Healthy", + "ar": "صحي" + }, + "warning": { + "en": "Warning", + "ar": "تحذير" + }, + "vitalSignDetails": { + "en": "Vital Sign Details", + "ar": "تفاصيل العلامات الحيوية" + }, + "resultOfNoDate": { + "en": "Result of --", + "ar": "نتيجة --" + }, + "referenceRangeBetween": { + "en": "Reference range: {low} – {high} {unit}", + "ar": "النطاق المرجعي: {low} – {high} {unit}" + }, + "referenceRangeMin": { + "en": "Reference range: ≥ {low} {unit}", + "ar": "النطاق المرجعي: ≥ {low} {unit}" + }, + "referenceRangeMax": { + "en": "Reference range: ≤ {high} {unit}", + "ar": "النطاق المرجعي: ≤ {high} {unit}" + }, + "noHistoryAvailable": { + "en": "No history available", + "ar": "لا يوجد تاريخ متاح" + }, + "bmiDescription": { + "en": "BMI is a measurement based on height and weight that estimates body fat.", + "ar": "مؤشر كتلة الجسم هو قياس يعتمد على الطول والوزن لتقدير دهون الجسم." + }, + "heightDescription": { + "en": "Height is measured in centimeters and is used to calculate BMI and dosage recommendations.", + "ar": "يقاس الطول بالسنتيمتر ويستخدم لحساب مؤشر كتلة الجسم وتوصيات الجرعات." + }, + "weightDescription": { + "en": "Weight helps track overall health, nutrition, and changes over time.", + "ar": "الوزن يساعد في تتبع الصحة العامة والتغذية والتغيرات مع مرور الوقت." + }, + "bloodPressureDescription": { + "en": "Blood pressure reflects the force of blood against artery walls. It is shown as systolic/diastolic.", + "ar": "ضغط الدم يعكس قوة الدم على جدران الشرايين. يظهر كانقباضي/انبساطي." + }, + "temperatureDescription": { + "en": "Body temperature reflects how hot your body is and may change with infection or inflammation.", + "ar": "درجة حرارة الجسم تعكس مدى سخونة جسمك وقد تتغير مع العدوى أو الالتهاب." + }, + "heartRateDescriptionVital": { + "en": "Heart rate refers to the number of heart beats per minute.", + "ar": "معدل ضربات القلب يشير إلى عدد نبضات القلب في الدقيقة." + }, + "respiratoryRateDescription": { + "en": "Respiratory rate is the number of breaths taken per minute.", + "ar": "معدل التنفس هو عدد الأنفاس المأخوذة في الدقيقة." + }, + "bmiAdvice": { + "en": "Maintain a balanced diet and regular activity. If your BMI is high or low, consider consulting your doctor.", + "ar": "حافظ على نظام غذائي متوازن ونشاط منتظم. إذا كان مؤشر كتلة جسمك مرتفعًا أو منخفضًا، فكر في استشارة طبيبك." + }, + "heightAdvice": { + "en": "No action is needed unless your measurement looks incorrect. Update it during your next visit.", + "ar": "لا حاجة لاتخاذ أي إجراء إلا إذا بدا قياسك غير صحيح. قم بتحديثه في زيارتك القادمة." + }, + "weightAdvice": { + "en": "Monitor weight changes. Sudden gain or loss may require medical advice.", + "ar": "راقب تغيرات الوزن. الزيادة أو الخسارة المفاجئة قد تتطلب استشارة طبية." + }, + "bloodPressureAdvice": { + "en": "Keep tracking your blood pressure. High or low readings should be discussed with your doctor.", + "ar": "استمر في تتبع ضغط دمك. يجب مناقشة القراءات المرتفعة أو المنخفضة مع طبيبك." + }, + "temperatureAdvice": { + "en": "If you have a persistent fever or symptoms, contact your healthcare provider.", + "ar": "إذا كان لديك حمى مستمرة أو أعراض، اتصل بمقدم الرعاية الصحية." + }, + "heartRateAdvice": { + "en": "Track your heart rate trends. If you feel dizziness or chest pain, seek medical care.", + "ar": "تتبع اتجاهات معدل ضربات قلبك. إذا شعرت بدوار أو ألم في الصدر، اطلب الرعاية الطبية." + }, + "respiratoryRateAdvice": { + "en": "If you notice shortness of breath or abnormal breathing, seek medical advice.", + "ar": "إذا لاحظت ضيقًا في التنفس أو تنفسًا غير طبيعي، اطلب المشورة الطبية." + }, + "whatShouldIDoNext": { + "en": "What should I do next?", + "ar": "ماذا يجب أن أفعل بعد ذلك؟" + }, + "customizeDrinkCup": { + "en": "Customize your drink cup", + "ar": "قم بتخصيص كوب مشروبك" + }, + "tipsToStayHydrated": { + "en": "Tips to stay hydrated", + "ar": "نصائح للبقاء رطبًا" + }, + "drinkBeforeYouFeelThirsty": { + "en": "Drink before you feel thirsty", + "ar": "اشرب قبل أن تشعر بالعطش" + }, + "keepRefillableBottleNextToYou": { + "en": "Keep a refillable bottle next to you", + "ar": "احتفظ بزجاجة قابلة لإعادة التعبئة بجانبك" + }, + "trackYourDailyIntakeToStayMotivated": { + "en": "Track your daily intake to stay motivated", + "ar": "تتبع كمية الماء اليومية للحفاظ على الحافز" + }, + "chooseSparklingWaterInsteadOfSoda": { + "en": "Choose sparkling water instead of soda", + "ar": "اختر الماء الفوار بدلاً من الصودا" + }, + "switchCup": { + "en": "Switch Cup", + "ar": "تبديل الكوب" + }, + "plainWater": { + "en": "Plain Water", + "ar": "ماء عادي" + }, + "yourGoal": { + "en": "Your Goal", + "ar": "هدفك" + }, + "remaining": { + "en": "Remaining", + "ar": "المتبقي" + }, + "hydrationStatus": { + "en": "Hydration Status", + "ar": "حالة الترطيب" + }, + "areYouSureYouWantToCancelAllWaterReminders": { + "en": "Are you sure you want to cancel all water reminders?", + "ar": "هل أنت متأكد أنك تريد إلغاء جميع تذكيرات الماء؟" + }, + "remindersSet": { + "en": "Reminders Set!", + "ar": "تم ضبط التذكيرات!" + }, + "dailyWaterRemindersScheduledAt": { + "en": "Daily water reminders scheduled at:", + "ar": "تم جدولة تذكيرات الماء اليومية في:" + }, + "waterConsumption": { + "en": "Water Consumption", + "ar": "استهلاك المياه" + }, + "selectNumberOfReminders": { + "en": "Select Number of Reminders", + "ar": "حدد عدد التذكيرات" + }, + "h2oSettings": { + "en": "H20 Settings", + "ar": "إعدادات H20" + }, + "settingsSavedSuccessfully": { + "en": "Settings saved successfully", + "ar": "تم حفظ الإعدادات بنجاح" + }, + "yourName": { + "en": "Your Name", + "ar": "اسمك" + }, + "ageYears": { + "en": "Age (11-120) yrs", + "ar": "العمر (11-120) سنة" + }, + "numberOfRemindersInADay": { + "en": "Number of reminders in a day", + "ar": "عدد التذكيرات في اليوم" + }, + "medications": { + "en": "Medications", + "ar": "الأدوية" + }, + "someRemarksAboutPrescription": { + "en": "some remarks about the prescription will be here", + "ar": "ستجدون هنا بعض الملاحظات حول الوصفة الطبية" + }, + "notifyMeBeforeConsumptionTime": { + "en": "Notify me before the consumption time", + "ar": "أبلغني قبل وقت الاستهلاك" + }, + "noMedicationsToday": { + "en": "No medications today", + "ar": "لا أدوية اليوم" + }, + "reminders": { + "en": "Reminders", + "ar": "تذكيرات" + }, + "reminderAddedToCalendar": { + "en": "Reminder added to calendar ✅", + "ar": "تمت إضافة تذكير إلى التقويم ✅" + }, + "errorWhileSettingCalendar": { + "en": "Error while setting calendar: {error}", + "ar": "حدث خطأ أثناء ضبط التقويم:{error}" + }, + "instructions": { + "en": "Instructions", + "ar": "التعليمات" + }, + "requests": { + "en": "Requests", + "ar": "الطلبات" + }, + "thisWeek": { + "en": "This Week", + "ar": "هذا الأسبوع" + }, + "lastMonth": { + "en": "Last Month", + "ar": "الشهر الماضي" + }, + "lastSixMonths": { + "en": "Last 6 Months", + "ar": "آخر 6 أشهر" + }, + "selectTime": { + "en": "Select Time", + "ar": "حدد الوقت" + }, + "pleaseWaitYouWillBeCalledForVitalSigns": { + "en": "Please wait! you will be called for vital signs", + "ar": "يرجى الانتظار! سيتم استدعاؤك لقياس العلامات الحيوية" + }, + "pleaseVisitRoomForVitalSigns": { + "en": "Please visit Room {roomNumber} for vital signs", + "ar": "يرجى زيارة الغرفة {roomNumber} لقياس العلامات الحيوية" + }, + "pleaseVisitRoomToTheDoctor": { + "en": "Please visit Room {roomNumber} to the Doctor", + "ar": "يرجى زيارة الغرفة {roomNumber} لمقابلة الطبيب" + }, + "erOnlineCheckInRequest": { + "en": "ER Online Check-In Request", + "ar": "طلب تسجيل الوصول عبر الإنترنت لقسم الطوارئ" + }, + "indoor": { + "en": "Indoor", + "ar": "داخلي" + }, + "navigation": { + "en": "Navigation", + "ar": "الملاحة" + }, + "health": { + "en": "Health", + "ar": "الصحة" + }, + "calculators": { + "en": "Calculators", + "ar": "الحاسبات" + }, + "converters": { + "en": "Converters", + "ar": "المحولات" + }, + "guide": { + "en": "Guide", + "ar": "الدليل" + }, + "liveCareServiceDesc": { + "en": "Get medical advice with a specialist doctor Via a video call", + "ar": "احصل على استشارة طبية من طبيب متخصص عبر مكالمة فيديو" + }, + "bloodGroup": { + "en": "Blood: {bloodType}", + "ar": "فصيلة الدم: {bloodType}" + }, + "medicalServices": { + "en": "Medical Services", + "ar": "الخدمات الطبية" + }, + "insuranceAndPayments": { + "en": "Insurance & Payments", + "ar": "التأمين والمدفوعات" + }, + "trackerAndOthers": { + "en": "Tracker & Others", + "ar": "المتتبع وأخرى" + }, + "bmi": { + "en": "BMI", + "ar": "مؤشر كتلة الجسم" + }, + "yesPleaseINeedHelp": { + "en": "Yes, Please I need help", + "ar": "نعم، من فضلك أريد المساعدة" + }, + "aiOverView": { + "en": "AI Overview", + "ar": "AI ملخص" + }, + "generateAiAnalysis": { + "en": "Generate AI analysis for this order", + "ar": "قم بإجراء تحليل لهذا الطلب AI" + }, + "aiAnalysis": { + "en": "AI Analysis", + "ar": "AI تحليل" + }, + "prediction": { + "en": "Prediction", + "ar": "تنبؤ" + }, + "prevention": { + "en": "Prevention", + "ar": "وقاية" + }, + "disclaimer": { + "en": "Disclaimer", + "ar": "تنصل" + }, + "thisAboveInfo": { + "en": "The above information is generated by AI based on your lab results and is intended for informational purposes only. It should not be considered a medical diagnosis or treatment plan. Always consult with your healthcare provider for personalized medical advice and before making any health-related decisions.", + "ar": "المعلومات المذكورة أعلاه مُولّدة بواسطة AI بناءً على نتائج تحاليلك المخبرية، وهي لأغراض إعلامية فقط. لا ينبغي اعتبارها تشخيصًا طبيًا أو خطة علاجية. استشر طبيبك دائمًا للحصول على نصيحة طبية مُخصصة قبل اتخاذ أي قرارات تتعلق بصحتك." + }, + "aiDisclaimer": { + "en": "Your lab result data will be securely shared with our AI Analyzer for analysis. This helps provide personalized health insights. Do you want to proceed?", + "ar": "سيتم مشاركة بيانات نتائج تحاليلك المخبرية بشكل آمن مع خدمة الذكاء الاصطناعي لدينا لتحليلها. يساعد هذا في تقديم رؤى صحية مُخصصة. هل ترغب في المتابعة؟" + }, + "consent": { + "en": "Consent", + "ar": "موافقة" + }, + "bmiNormalDescription": { + "en": "Your BMI is within the healthy range. Continue a balanced diet, regular physical activity, and routine checkups to maintain good health. Monitor any significant changes over time.", + "ar": "مؤشر كتلة جسمك ضمن المعدل الصحي. استمر في اتباع نظام غذائي متوازن، وممارسة النشاط البدني بانتظام، وإجراء الفحوصات الدورية للحفاظ على صحة جيدة. راقب أي تغييرات ملحوظة مع مرور الوقت." + }, + "bmiUnderweightDescription": { + "en": "BMI suggests you are underweight. Consider increasing calorie intake with nutrient-dense foods, include resistance training to build muscle, and consult a healthcare professional to check for underlying causes.", + "ar": "يشير مؤشر كتلة الجسم إلى أنك تعاني من نقص الوزن. لذا، يُنصح بزيادة السعرات الحرارية المتناولة من خلال تناول الأطعمة الغنية بالعناصر الغذائية، وممارسة تمارين المقاومة لبناء العضلات، واستشارة أخصائي رعاية صحية للتحقق من وجود أسباب كامنة." + }, + "bmiOverweightDescription": { + "en": "BMI suggests overweight. It is advised to aim for gradual, sustainable weight loss through moderate calorie reduction, regular physical activity, and healthy food choices. Consult your doctor before making any major lifestyle changes.", + "ar": "يشير مؤشر كتلة الجسم إلى زيادة الوزن. لذا، يُنصح بالسعي إلى إنقاص الوزن تدريجياً وبشكل مستدام من خلال تقليل السعرات الحرارية بشكل معتدل، وممارسة النشاط البدني بانتظام، واختيار الأطعمة الصحية. استشر طبيبك قبل إجراء أي تغييرات جذرية في نمط حياتك." + }, + "caloriesMaintenanceDescription": { + "en": "Estimated daily calories to maintain your current weight based on your activity level and metabolic rate. Use this as a baseline: slightly increase for muscle gain or slightly decrease for gradual weight loss. Monitor progress and adjust every 2–4 weeks.", + "ar": "السعرات الحرارية اليومية المُقدَّرة للحفاظ على وزنك الحالي بناءً على مستوى نشاطك ومعدل الأيض لديك. استخدم هذه الكمية كخط أساس: زدها قليلاً لزيادة الكتلة العضلية، أو قللها قليلاً لإنقاص الوزن تدريجياً. تابع تقدمك وعدّل الخطة كل أسبوعين إلى أربعة أسابيع." + }, + "caloriesModerateDeficitDescription": { + "en": "A moderate calorie reduction plan designed for steady, sustainable weight loss (typically 0.25 to 0.5 kg per week). Combine with resistance training and adequate protein to preserve muscle mass. Avoid sharp calorie drops and consult a professional if you have medical conditions.", + "ar": "نظام غذائي معتدل لتقليل السعرات الحرارية مصمم لإنقاص الوزن بشكل ثابت ومستدام (عادةً من 0.25 إلى 0.5 كيلوغرام أسبوعيًا). يُنصح بدمجه مع تمارين المقاومة وتناول كمية كافية من البروتين للحفاظ على الكتلة العضلية. تجنب التخفيضات الحادة في السعرات الحرارية واستشر طبيبًا مختصًا إذا كنت تعاني من أي حالة صحية." + }, + "caloriesAggressiveDeficitDescription": { + "en": "A large calorie reduction that may produce faster weight loss but can be hard to sustain and increase risk of nutrient deficiencies, fatigue, or muscle loss. Not recommended long-term; seek guidance from a healthcare or nutrition professional before continuing.", + "ar": "يؤدي خفض السعرات الحرارية بشكل كبير إلى فقدان الوزن بشكل أسرع، ولكنه قد يصعب الاستمرار عليه ويزيد من خطر نقص العناصر الغذائية والإرهاق وفقدان الكتلة العضلية. لا يُنصح باتباعه على المدى الطويل؛ استشر طبيبًا أو أخصائي تغذية قبل الاستمرار." + }, + "bodyFatEssentialDescription": { + "en": "Your body fat percentage is in the essential/athletic range. This level is typical for athletes and indicates very low body fat. While this may be optimal for performance, ensure you maintain adequate nutrition and hormone function. Consult a healthcare professional if you experience fatigue, hormonal issues, or other health concerns.", + "ar": "نسبة الدهون في جسمك ضمن النطاق الأساسي/الرياضي. هذا المستوى شائع لدى الرياضيين ويشير إلى انخفاض نسبة الدهون في الجسم. مع أن هذا قد يكون مثاليًا للأداء، تأكد من الحفاظ على تغذية سليمة ووظائف هرمونية متوازنة. استشر طبيبًا إذا شعرت بالتعب، أو واجهت مشاكل هرمونية، أو أي مخاوف صحية أخرى." + }, + "bodyFatFitnessDescription": { + "en": "Your body fat percentage is in the fitness range. This indicates a healthy level of body fat associated with good physical conditioning. Maintain your current lifestyle habits including regular exercise and balanced nutrition to sustain this healthy range.", + "ar": "نسبة الدهون في جسمك ضمن النطاق الصحي. وهذا يدل على مستوى صحي من الدهون في الجسم يرتبط بلياقة بدنية جيدة. حافظ على نمط حياتك الحالي، بما في ذلك ممارسة الرياضة بانتظام واتباع نظام غذائي متوازن، للحفاظ على هذا المستوى الصحي." + }, + "bodyFatAverageDescription": { + "en": "Your body fat percentage is in the average/acceptable range. This is considered a healthy range for general population. To improve body composition, consider incorporating strength training, cardiovascular exercise, and a balanced diet. Focus on gradual, sustainable changes for long-term health.", + "ar": "نسبة الدهون في جسمك ضمن المعدل الطبيعي/المقبول، وهي نسبة تُعتبر صحية لعموم الناس. لتحسين تكوين جسمك، يُنصح بممارسة تمارين القوة، وتمارين القلب والأوعية الدموية، واتباع نظام غذائي متوازن. ركّز على التغييرات التدريجية والمستدامة للحفاظ على صحتك على المدى الطويل." + }, + "bodyFatObeseDescription": { + "en": "Your body fat percentage is above the recommended healthy range. This may increase health risks including cardiovascular disease, diabetes, and joint problems. Consider consulting a healthcare provider or registered dietitian to develop a personalized plan that includes balanced nutrition, regular physical activity, and lifestyle modifications for sustainable weight management.", + "ar": "نسبة الدهون في جسمك أعلى من المعدل الصحي الموصى به. قد يزيد هذا من المخاطر الصحية، بما في ذلك أمراض القلب والأوعية الدموية، والسكري، ومشاكل المفاصل. يُنصح باستشارة طبيب أو أخصائي تغذية معتمد لوضع خطة علاجية شخصية تشمل التغذية المتوازنة، والنشاط البدني المنتظم، وتعديلات نمط الحياة لتحقيق إدارة مستدامة للوزن." + }, + "bmrNormalDescription": { + "en": "Your Basal Metabolic Rate (BMR) is within the expected range for your profile. BMR is the energy your body needs at rest to maintain vital functions (breathing, circulation, temperature). Use this value as the baseline for estimating total daily energy needs by applying an activity multiplier. Maintain a balanced diet and regular physical activity to support metabolic health.", + "ar": "معدل الأيض الأساسي لديك ضمن النطاق المتوقع لحالتك. معدل الأيض الأساسي هو الطاقة التي يحتاجها جسمك في حالة الراحة للحفاظ على وظائفه الحيوية (التنفس، الدورة الدموية، درجة الحرارة). استخدم هذه القيمة كأساس لتقدير إجمالي احتياجاتك اليومية من الطاقة من خلال تطبيق مُعامل النشاط. حافظ على نظام غذائي متوازن وممارسة النشاط البدني بانتظام لدعم صحة التمثيل الغذائي." + }, + "bmrLowDescription": { + "en": "Your BMR is lower than typical for your profile. Possible causes include lower lean muscle mass, age-related metabolic decline, or metabolic adaptation from prolonged calorie restriction. Consider focusing on resistance training to build/maintain muscle, ensure adequate protein and micronutrient intake, and consult a healthcare professional if this is unexpected.", + "ar": "معدل الأيض الأساسي لديك أقل من المعدل الطبيعي لحالتك. تشمل الأسباب المحتملة انخفاض كتلة العضلات، أو تراجع التمثيل الغذائي المرتبط بالتقدم في السن، أو التكيف الأيضي الناتج عن تقييد السعرات الحرارية لفترة طويلة. يُنصح بالتركيز على تمارين المقاومة لبناء العضلات والحفاظ عليها، والتأكد من تناول كميات كافية من البروتين والمغذيات الدقيقة، واستشارة أخصائي رعاية صحية إذا كان هذا الأمر غير متوقع." + }, + "bmrHighDescription": { + "en": "Your BMR is higher than average for your profile. This can reflect greater lean mass, younger age, or a naturally higher metabolic rate, meaning you burn more energy at rest. Use this information to tailor calorie targets: higher needs for maintenance or muscle gain, moderate deficit for weight loss. Seek medical advice if you notice rapid unexplained changes.", + "ar": "معدل الأيض الأساسي لديك أعلى من المتوسط ​​بالنسبة لحالتك. قد يعكس هذا زيادة في كتلة العضلات، أو صغر السن، أو ارتفاع معدل الأيض لديك بشكل طبيعي، مما يعني أنك تحرق طاقة أكبر أثناء الراحة. استخدم هذه المعلومات لتحديد احتياجاتك من السعرات الحرارية: احتياجات أعلى للحفاظ على الوزن أو بناء العضلات، ونقص معتدل في السعرات الحرارية لإنقاص الوزن. استشر طبيبك إذا لاحظت أي تغيرات سريعة غير مبررة." + }, + "ibwAtTargetDescription": { + "en": "Your weight is at the ideal target. Maintain your current habits — balanced diet and regular activity — to keep this.", + "ar": "وزنك في النطاق المثالي. حافظ على عاداتك الحالية — نظام غذائي متوازن ونشاط بدني منتظم — للاستمرار على هذا المستوى." + }, + "ibwBelowTargetDescription": { + "en": "You are below the ideal weight by {kg} kg. Aim to gradually increase weight with a modest calorie surplus, nutrient-dense foods, and resistance training.", + "ar": "أنتِ أقل من الوزن المثالي بمقدار {kg} كجم. يُنصح بزيادة الوزن تدريجيًا من خلال فائضٍ بسيط في السعرات الحرارية، وتناول أطعمة غنية بالعناصر الغذائية، مع ممارسة تمارين المقاومة." + }, + "ibwAboveTargetDescription": { + "en": "You are above the ideal weight by {kg} kg. Aim for a gradual, sustainable weight reduction through a moderate calorie deficit, increased activity, and balanced nutrition.", + "ar": "أنتِ أعلى من الوزن المثالي بمقدار {kg} كجم. يُنصح باتباع خفضٍ تدريجي ومستدام للوزن من خلال عجزٍ معتدل في السعرات الحرارية، وزيادة مستوى النشاط البدني، واتباع تغذية متوازنة." + }, + "ibwCloseToRangeDescription": { + "en": "Your weight is close to the ideal range. Maintain a balanced diet and regular activity; follow personalized advice from a healthcare professional if needed.", + "ar": "وزنك قريب من النطاق المثالي. حافظ على نظام غذائي متوازن ونشاط بدني منتظم، مع اتباع إرشادات شخصية من مختص صحي عند الحاجة." + }, + "ibwUnderweightDescription": { + "en": "You are below the ideal weight by {kg} kg. Focus on increasing calorie intake with nutrient-dense foods, prioritize protein and resistance training to build healthy mass, and consider consulting a healthcare professional.", + "ar": "أنت أقل من الوزن المثالي بمقدار {kg} كجم. ركّز على زيادة السعرات الحرارية من خلال أطعمة غنية بالعناصر الغذائية، وأعط الأولوية للبروتين وتمارين المقاومة لبناء كتلة صحية، مع اتباع إرشادات شخصية من مختص صحي." + }, + "ibwUnderweightGenericDescription": { + "en": "You appear underweight compared to the ideal. Consider increasing calorie intake with nutrient-dense foods and resistance training; seek professional guidance if needed.", + "ar": "يبدو أنكِ أقل من الوزن المثالي. يُنصح بزيادة السعرات الحرارية من خلال أطعمة غنية بالعناصر الغذائية وممارسة تمارين المقاومة؛ مع الحصول على استشارة مختص صحي عند الحاجة." + }, + "ibwOverweightDescription": { + "en": "You are above the ideal weight by {kg} kg. Aim for a gradual, sustainable weight loss strategy — moderate calorie deficit, regular physical activity, and balanced nutrition. Consult a professional before major changes.", + "ar": "أنت أعلى من الوزن المثالي بمقدار {kg} كجم. يُنصح باتباع استراتيجية تدريجية ومستدامة لفقدان الوزن — من خلال عجزٍ معتدل في السعرات الحرارية، وممارسة نشاط بدني منتظم، وتغذية متوازنة. يُفضّل استشارة مختص صحي قبل إجراء تغييرات كبيرة." + }, + "ibwOverweightGenericDescription": { + "en": "You appear above the ideal weight. Consider a gradual, sustainable calorie deficit combined with activity and balanced nutrition; consult a professional if needed.", + "ar": "يبدو أنك أعلى من الوزن المثالي. يُنصح باتباع عجزٍ تدريجي ومستدام في السعرات الحرارية مع ممارسة النشاط البدني واتباع تغذية متوازنة؛ مع الحصول على استشارة مختص صحي عند الحاجة." + }, + "dietVeryLowCarbsDescription": { + "en": "Very low‑carb (ketogenic) approach: minimal carbohydrates, higher fat and moderate protein. May support rapid weight loss and improved blood sugar control for some, but can be hard to sustain and may cause nutrient gaps. Monitor hydration/electrolytes and consult a professional for long‑term use.", + "ar": "نهج منخفض الكربوهيدرات جدًا (الكيتوني): تقليل الكربوهيدرات إلى الحد الأدنى مع زيادة الدهون وبروتين معتدل. قد يساعد على فقدان الوزن بسرعة وتحسين التحكم في سكر الدم لدى بعض الأشخاص، لكنه قد يكون صعب الاستمرار عليه وقد يسبب نقصًا في بعض العناصر الغذائية. يجب مراقبة الترطيب ، والحصول على استشارة مختص صحي عند استخدامه لفترة طويلة." + }, + "dietLowCarbsDescription": { + "en": "Low‑carb, higher‑protein plan: reduced carbohydrates with increased protein to support satiety and muscle maintenance. Helpful for weight management and glycemic control when balanced with vegetables and healthy fats. Ensure adequate fiber and micronutrients.", + "ar": "خطة منخفضة الكربوهيدرات وعالية البروتين: تقليل الكربوهيدرات مع زيادة البروتين لدعم الشعور بالشبع والحفاظ على الكتلة العضلية. مفيدة لإدارة الوزن وضبط سكر الدم عند موازنتها مع الخضروات والدهون الصحية. احرص على الحصول على كمية كافية من الألياف والعناصر الدقيقة (الفيتامينات والمعادن)." + }, + "dietModerateCarbsDescription": { + "en": "Moderate carbohydrate intake with balanced protein and fats: provides steady energy for daily activity and exercise while allowing flexibility. Suitable for many people aiming for sustainable weight management and performance.", + "ar": "تناول معتدل للكربوهيدرات مع توازن في البروتين والدهون: يوفر طاقة مستقرة للأنشطة اليومية والتمارين مع قدر من المرونة. مناسب لكثير من الأشخاص الذين يسعون لإدارة وزن مستدامة وتحسين الأداء." + }, + "dietUSDAGuidelinesDescription": { + "en": "USDA‑based balanced pattern: emphasizes fruits, vegetables, whole grains, lean proteins, and limited added sugars and saturated fats. Evidence‑based framework for general health, nutrient adequacy, and chronic disease prevention.", + "ar": "نمط متوازن مستند إلى (USDA): يركز على الفواكه والخضروات والحبوب الكاملة والبروتينات قليلة الدهن، مع الحد من السكريات المضافة والدهون المشبعة. يُعد إطارًا قائمًا على الأدلة لدعم الصحة العامة، وكفاية العناصر الغذائية، والوقاية من الأمراض المزمنة." + }, + "dietZoneDietDescription": { + "en": "Zone Diet (~40% carbs / 30% protein / 30% fat): emphasizes hormonal balance and portion control. May improve body composition and energy for some, but requires planning; personalize with a nutrition professional.", + "ar": "حمية الزون (~40٪ كربوهيدرات / 30٪ بروتين / 30٪ دهون): تركز على التوازن الهرموني وضبط الحصص الغذائية. قد تُحسّن تركيب الجسم ومستوى الطاقة لدى بعض الأشخاص، لكنها تتطلب تخطيطًا جيدًا؛ ويُفضّل تخصيصها بالتعاون مع مختص تغذية." + }, + "contextDependent": { + "en": "Context Dependent", + "ar": "يعتمد السياق" + }, + "calculatedValue": { + "en": "Calculated Value", + "ar": "القيمة المحسوبة" + }, + "calculationFormula": { + "en": "Calculation Formula", + "ar": "صيغة الحساب" + }, + "confirmYourLocation": { + "en": "Confirm your location", + "ar": "قم بتأكيد موقعك" + }, + "confirmYourLocationDesc": { + "en": "Please confirm your current location to show appropriate directions.", + "ar": "يرجى تأكيد موقعك الحالي لعرض الاتجاهات المناسبة." + }, + "insideHospital": { + "en": "I am inside the hospital", + "ar": "أنا داخل المستشفى" + }, + "outsideHospital": { + "en": "I am outside the hospital", + "ar": "أنا خارج المستشفى" + }, + "servicePriceList": { + "en": "Service Price List", + "ar": "قائمة أسعار الخدمات" + }, + "servicePriceListDesc": { + "en": "The service price list below shows the fees for health services provided to patients on a cash payment basis. Regarding services covered by insurance, insurance coverage will be applied, eligibility verified, and co-payment percentages calculated according to the terms of the insurance policy and the approved benefit schedule for each insurance company.", + "ar": "توضح قائمة أسعار الخدمات أدناه رسوم الخدمات الصحية المقدمة للمرضى بنظام الدفع النقدي. أما فيما يتعلق بالخدمات المشمولة بالتأمين، فسيتم تطبيق التغطية التأمينية والتحقق من الأهلية واحتساب نسب التحمل وفقًا لشروط وثيقة التأمين وجدول المنافع المعتمد لكل شركة تأمين." + }, + "servicePriceListRights": { + "en": "The patient is entitled to a free follow-up within 14 days of the first visit", + "ar": "يحق للمريض الحصول على متابعة مجانية في غضون 14 يومًا من الزيارة الأولى" + }, + "serviceName": { + "en": "Service Name", + "ar": "اسم الخدمة" + }, + "noFreeSlot": { + "en": "There are no appointments available on the selected date. Please choose another date or try again later.", + "ar": "لا توجد مواعيد متاحة في التاريخ المحدد. يرجى اختيار تاريخ آخر أو إعادة المحاولة لاحقاً." + }, + "noThanksIKnowTheClinic": { + "en": "No, thanks. I know the clinic.", + "ar": "لا، شكراً. أنا أعرف العيادة." + }, + "unableToSendOTP": { + "en": "Unable to send One-Time Password", + "ar": "تعذر إرسال رمز التحقق لمرة واحدة" + }, + "loadingAIAnalysis": { + "en": "Analysing your lab results, Please be patient and let the AI do the magic, This might take some time.", + "ar": "جارٍ تحليل نتائج المختبر، يرجى التحلي بالصبر والسماح للذكاء الاصطناعي بالقيام بالمهمة، قد يستغرق هذا بعض الوقت." + }, + "symptoms": { + "en": "Symptoms", + "ar": "أعراض" + }, + "insuranceInActive": { + "en": "Insurance Inactive", + "ar": "التأمين غير نشط" + }, + "insuranceInActiveContactSupport": { + "en": "You have a valid insurance but it is currently inactive in HMG. Please contact HMG customer support to activate it.", + "ar": "لديك تأمين ساري المفعول، ولكنه غير مُفعّل حاليًا في مجموعة حبيب الطبية. يُرجى التواصل مع خدمة عملاء مجموعة حبيب الطبية." + }, + "updateAppNow": { + "en": "Update App Now", + "ar": "تحديث التطبيق الآن" + }, + "Dr": { + "en": "Dr.", + "ar": "الدكتور." + }, + "reschedulingAppo": { + "en": "Rescheduling Appointment, Please wait...", + "ar": "إعادة جدولة الموعد، يرجى الانتظار..." + }, + "invalidEligibility": { + "en": "You cannot make online payment because you are not eligible to use the provided service.", + "ar": "لا يمكنك إجراء الدفع عبر الإنترنت لأنك غير مؤهل لاستخدام الخدمة المقدمة." + }, + "invalidInsurance": { + "en": "You cannot make online payment because you do not have a valid insurance.", + "ar": "لا يمكنك إجراء الدفع عبر الإنترنت لأنه ليس لديك تأمين صالح." + }, + "continueCash": { + "en": "Continue as cash", + "ar": "متابعة الدفع نقدًا" + }, + "timeFor": { + "en": "Time For", + "ar": "الوقت" + }, + "hmgPolicies": { + "en": "HMG Policies", + "ar": "سياسات مجموعة الحبيب الطبية" + }, + "darkMode": { + "en": "Dark Mode", + "ar": "المظهر الداكن" + }, + "generateAiAnalysisResult": { + "en": "Generate AI analysis for this result", + "ar": "قم بإجراء تحليل لهذا المختبر AI" + } +} \ No newline at end of file diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 71d30372..f415d8ac 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -184,15 +184,15 @@ class ApiClientImp implements ApiClient { body[_appState.isAuthenticated ? 'TokenID' : 'LogInTokenID'] = _appState.appAuthToken; } - if (url.contains("HMGAI_Lab_Analyze_Orders_API")) { - url = "https://uat.hmgwebservices.com/Services/Patients.svc/REST/HMGAI_Lab_Analyze_Orders_API"; - body['TokenID'] = "@dm!n"; - } - - if (url.contains("HMGAI_Lab_Analyzer_API")) { - url = "https://uat.hmgwebservices.com/Services/Patients.svc/REST/HMGAI_Lab_Analyzer_API"; - body['TokenID'] = "@dm!n"; - } + // if (url.contains("HMGAI_Lab_Analyze_Orders_API")) { + // url = "https://uat.hmgwebservices.com/Services/Patients.svc/REST/HMGAI_Lab_Analyze_Orders_API"; + // body['TokenID'] = "@dm!n"; + // } + // + // if (url.contains("HMGAI_Lab_Analyzer_API")) { + // url = "https://uat.hmgwebservices.com/Services/Patients.svc/REST/HMGAI_Lab_Analyzer_API"; + // body['TokenID'] = "@dm!n"; + // } if (url == 'https://uat.hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo') { url = "https://hmgwebservices.com/Services/NHIC.svc/REST/GetPatientInfo"; diff --git a/lib/features/habib_wallet/habib_wallet_view_model.dart b/lib/features/habib_wallet/habib_wallet_view_model.dart index 65e8e276..3d72f651 100644 --- a/lib/features/habib_wallet/habib_wallet_view_model.dart +++ b/lib/features/habib_wallet/habib_wallet_view_model.dart @@ -112,6 +112,8 @@ class HabibWalletViewModel extends ChangeNotifier { habibWalletBalanceList.sort((a, b) => b.patientAdvanceBalanceAmount!.compareTo(a.patientAdvanceBalanceAmount!)); + habibWalletBalanceList.removeWhere((element) => element.patientAdvanceBalanceAmount == 0); + isWalletAmountLoading = false; notifyListeners(); if (onSuccess != null) { diff --git a/lib/presentation/habib_wallet/habib_wallet_page.dart b/lib/presentation/habib_wallet/habib_wallet_page.dart index 780c3d64..2a3da660 100644 --- a/lib/presentation/habib_wallet/habib_wallet_page.dart +++ b/lib/presentation/habib_wallet/habib_wallet_page.dart @@ -56,8 +56,10 @@ class _HabibWalletState extends State { width: double.infinity, height: 180.h, decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24, + // color: AppColors.blackBgColor, + color: Color(0xFF2E3039), + borderRadius: 24.r, + hasShadow: true ), child: Padding( padding: EdgeInsets.all(16.h), @@ -71,7 +73,7 @@ class _HabibWalletState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "${_appState.getAuthenticatedUser()!.firstName!} ${_appState.getAuthenticatedUser()!.lastName!}".toText19(isBold: true, color: AppColors.textColor), + "${_appState.getAuthenticatedUser()!.firstName!} ${_appState.getAuthenticatedUser()!.lastName!}".toText19(isBold: true, color: Colors.white), "MRN: ${_appState.getAuthenticatedUser()!.patientId!}".toText14(weight: FontWeight.w500, color: AppColors.greyTextColor), ], ).expanded, @@ -79,10 +81,10 @@ class _HabibWalletState extends State { ], ), Spacer(), - LocaleKeys.balanceAmount.tr(context: context).toText14(weight: FontWeight.w500, color: AppColors.textColor), + LocaleKeys.balanceAmount.tr(context: context).toText14(weight: FontWeight.w500, color: Colors.white), SizedBox(height: 4.h), Consumer(builder: (context, habibWalletVM, child) { - return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, textColor: AppColors.textColor, iconColor: AppColors.textColor, iconSize: 16, isExpanded: false) + return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, textColor: Colors.white, iconColor: Colors.white, iconSize: 16, isExpanded: false) .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.h, width: 80.h, height: 24.h); }), ], diff --git a/lib/presentation/lab/lab_result_via_clinic/ai_analysis_widget.dart b/lib/presentation/lab/lab_result_via_clinic/ai_analysis_widget.dart index 2c552bc7..ebf802df 100644 --- a/lib/presentation/lab/lab_result_via_clinic/ai_analysis_widget.dart +++ b/lib/presentation/lab/lab_result_via_clinic/ai_analysis_widget.dart @@ -78,6 +78,8 @@ class AiAnalysisWidget extends StatelessWidget { CustomButton( height: 50.h, text: LocaleKeys.close.tr(context: context), + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, onPressed: () { getIt.get().closeAILabResultAnalysis(); }, From 55b8bc162c87b55b935f9e2ce98b1d1dff60fd06 Mon Sep 17 00:00:00 2001 From: Haroon Amjad <> Date: Sat, 21 Mar 2026 21:00:03 -0600 Subject: [PATCH 07/17] Updates --- assets/langs/ar-SA.json | 5 +- assets/langs/en-US.json | 3 +- assets/langs/translations.json | 6290 ----------------- lib/core/api_consts.dart | 4 +- lib/extensions/string_extensions.dart | 4 +- .../book_appointments_view_model.dart | 1 + lib/generated/locale_keys.g.dart | 1 + .../widgets/appointment_card.dart | 10 +- .../widgets/appointment_doctor_card.dart | 50 +- .../book_appointment/doctor_profile_page.dart | 4 +- .../book_appointment/select_doctor_page.dart | 2 +- .../widgets/appointment_calendar.dart | 155 +- .../book_appointment/widgets/doctor_card.dart | 2 +- .../home/widgets/welcome_widget.dart | 2 +- .../widgets/patient_insurance_card.dart | 2 +- lib/presentation/lab/lab_orders_page.dart | 2 +- .../medical_file/medical_file_page.dart | 16 +- .../medical_file_appointment_card.dart | 2 +- .../prescription_detail_page.dart | 26 +- .../prescriptions/prescription_item_view.dart | 8 +- .../prescriptions_list_page.dart | 9 +- .../profile_settings/profile_settings.dart | 2 +- .../radiology/radiology_orders_page.dart | 13 +- .../radiology/radiology_result_page.dart | 83 +- lib/widgets/appbar/collapsing_list_view.dart | 6 + lib/widgets/chip/app_custom_chip_widget.dart | 6 +- pubspec.yaml | 4 +- 27 files changed, 233 insertions(+), 6479 deletions(-) delete mode 100644 assets/langs/translations.json diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 76736da7..04684df5 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -448,7 +448,7 @@ "lakumPoint": "نقطة", "wishlist": "قائمة الرغبات", "products": "المنتجات", - "reviews": "التقييمات", + "reviews": "التعليقات", "brands": "العلامات التجارية", "productDetails": "تفاصيل المنتج", "medicationRefill": "إعادة تعبئة الدواء", @@ -1584,5 +1584,6 @@ "timeFor": "الوقت", "hmgPolicies": "سياسات مجموعة الحبيب الطبية", "darkMode": "المظهر الداكن", - "generateAiAnalysisResult": "قم بإجراء تحليل لهذا المختبر AI" + "generateAiAnalysisResult": "قم بإجراء تحليل لهذا المختبر AI", + "ratings": "التقييمات" } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index b7c8def0..c43d730e 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1577,5 +1577,6 @@ "timeFor": "Time For", "hmgPolicies": "HMG Policies", "darkMode": "Dark Mode", - "generateAiAnalysisResult": "Generate AI analysis for this result" + "generateAiAnalysisResult": "Generate AI analysis for this result", + "ratings": "Ratings" } diff --git a/assets/langs/translations.json b/assets/langs/translations.json deleted file mode 100644 index 9750d779..00000000 --- a/assets/langs/translations.json +++ /dev/null @@ -1,6290 +0,0 @@ -{ - "english": { - "en": "English", - "ar": "الإنجليزية" - }, - "arabic": { - "en": "Arabic", - "ar": "العربية" - }, - "login": { - "en": "Login", - "ar": "تسجيل الدخول" - }, - "noDataAvailable": { - "en": "No Data Available", - "ar": "لا توجد بيانات متاحة" - }, - "confirm": { - "en": "Confirm", - "ar": "تأكيد" - }, - "loadingText": { - "en": "Loading, please wait...", - "ar": "جاري التحميل، يرجى الانتظار..." - }, - "kilometerUnit": { - "en": "KM", - "ar": "كم" - }, - "dashboardScreenToolbarTitle": { - "en": "Home", - "ar": "الرئيسية" - }, - "settings": { - "en": "Settings", - "ar": "الإعدادات" - }, - "language": { - "en": "App Language", - "ar": "لغة التطبيق" - }, - "lanEnglish": { - "en": "English", - "ar": "الإنجليزية" - }, - "lanArabic": { - "en": "العربية", - "ar": "العربية" - }, - "cancel": { - "en": "Cancel", - "ar": "إلغاء" - }, - "done": { - "en": "Done", - "ar": "تم" - }, - "replay2": { - "en": "Replay", - "ar": "إعادة التشغيل" - }, - "home": { - "en": "Home", - "ar": "الرئيسية" - }, - "services": { - "en": "SERVICES", - "ar": "الخدمات" - }, - "mySchedule": { - "en": "My Schedule", - "ar": "جدولي" - }, - "logout": { - "en": "Logout", - "ar": "تسجيل الخروج" - }, - "respirationRate": { - "en": "Respiration Rate", - "ar": "معدل التنفس" - }, - "bookAppo": { - "en": "Book Appointment", - "ar": "حجز موعد" - }, - "searchBy": { - "en": "Search By:", - "ar": "البحث بواسطة:" - }, - "clinic": { - "en": "Clinic", - "ar": "عيادة" - }, - "byClinic": { - "en": "By Clinic", - "ar": "حسب العيادة" - }, - "hospital": { - "en": "Hospital", - "ar": "مستشفى" - }, - "byHospital": { - "en": "By Hospital", - "ar": "حسب المستشفى" - }, - "name": { - "en": "Name", - "ar": "الاسم" - }, - "doctor": { - "en": "Doctor", - "ar": "طبيب" - }, - "clinicName": { - "en": "Clinic Name", - "ar": "اسم العيادة" - }, - "hospitalName": { - "en": "Hospital Name", - "ar": "اسم المستشفى" - }, - "noClinicFound": { - "en": "No Clinic Found", - "ar": "لم يتم العثور على عيادة" - }, - "doctorName": { - "en": "Doctor Name", - "ar": "اسم الطبيب" - }, - "nearestAppo": { - "en": "Nearest Appointment", - "ar": "أقرب موعد" - }, - "searchByDocText": { - "en": "Type the name of the doctor to help you find him", - "ar": "اكتب اسم الطبيب لمساعدتك في العثور عليه" - }, - "enterDocName": { - "en": "Enter Doctor name", - "ar": "أدخل اسم الطبيب" - }, - "search": { - "en": "Search", - "ar": "بحث" - }, - "noResultFound": { - "en": "No Result Found", - "ar": "لم يتم العثور على نتائج" - }, - "noSearchResultFound": { - "en": "No Result Found", - "ar": "لم يتم العثور على نتائج" - }, - "pleaseEnterProductName": { - "en": "Please Enter Product Name", - "ar": "يرجى إدخال اسم المنتج" - }, - "bookNow": { - "en": "Book Now", - "ar": "احجز الآن" - }, - "docInfo": { - "en": "Doctor Information", - "ar": "معلومات الطبيب" - }, - "appoInfo": { - "en": "Appointment Information", - "ar": "معلومات الموعد" - }, - "availableAppo": { - "en": "Available Appointments", - "ar": "المواعيد المتاحة" - }, - "gender": { - "en": "Gender", - "ar": "الجنس" - }, - "nationality": { - "en": "Nationality", - "ar": "الجنسية" - }, - "neverWait": { - "en": "Never wait in queue", - "ar": "لا تنتظر في الطابور أبدًا" - }, - "reminderTitle": { - "en": "You have appointment with Dr. ", - "ar": "لديك موعد مع الدكتور." - }, - "appointmentCalendar": { - "en": "Would you like to set a reminder for this appointment in your calendar?", - "ar": "هل ترغب في تعيين تذكير لهذا الموعد في التقويم الخاص بك؟" - }, - "appointmentSuccess": { - "en": "Appointment is successfully booked", - "ar": "تم حجز الموعد بنجاح" - }, - "docQualifications": { - "en": "Doctor Qualifications", - "ar": "مؤهلات الطبيب" - }, - "pressAgain": { - "en": "Press again to exit the app", - "ar": "اضغط مرة أخرى للخروج من التطبيق" - }, - "laserMaxLimitReach": { - "en": "Maximum limit is 90 minutes", - "ar": "الحد الأقصى هو 90 دقيقة" - }, - "confirmAppoHeading": { - "en": "Kindly review your Appointment", - "ar": "يرجى مراجعة موعدك" - }, - "patientInfo": { - "en": "Patient Information", - "ar": "معلومات المريض" - }, - "doctorFilter": { - "en": "Doctors will be filtered based on your gender and age", - "ar": "سيتم تصفية الأطباء بناءً على جنسك وعمرك" - }, - "bookSuccess": { - "en": "Book Success", - "ar": "تم الحجز بنجاح" - }, - "patientShare": { - "en": "Patient Share", - "ar": "نسبة المريض" - }, - "patientShareWithTax": { - "en": "Patient Share with Tax", - "ar": "نسبة المريض مع الضريبة" - }, - "confirmAppo": { - "en": "Confirm Appointment", - "ar": "تأكيد الموعد" - }, - "confirmLiveCare": { - "en": "Confirm LiveCare", - "ar": "تأكيد ال لايف كير" - }, - "waitingForDoctor": { - "en": "Waiting for doctor", - "ar": "في انتظار الطبيب" - }, - "appointment": { - "en": "Appointment", - "ar": "موعد" - }, - "confirmLater": { - "en": "Confirm Later", - "ar": "تأكيد لاحقًا" - }, - "todoList": { - "en": "Todo List", - "ar": "قائمة المهام" - }, - "appoActions": { - "en": "Appointment Actions", - "ar": "إجراءات الموعد" - }, - "date": { - "en": "Date", - "ar": "التاريخ" - }, - "time": { - "en": "Time", - "ar": "الوقت" - }, - "pendingPayment": { - "en": "Pending for payment", - "ar": "معلق للدفع" - }, - "payNow": { - "en": "Pay Now", - "ar": "ادفع الآن" - }, - "viewQR": { - "en": "View QR Code", - "ar": "عرض رمز الاستجابة السريعة" - }, - "instruction": { - "en": "Instructions", - "ar": "تعليمات" - }, - "livecare": { - "en": "LiveCare", - "ar": "لايف كير" - }, - "livecareAppo": { - "en": "LiveCare Appointment", - "ar": "موعد لايف كير" - }, - "agreeTo": { - "en": "I agree to the", - "ar": "أوافق على" - }, - "termsConditoins": { - "en": "Terms and Conditions", - "ar": "الشروط والأحكام" - }, - "cancelAppoMsg": { - "en": "Are you sure you want to cancel this appointment?", - "ar": "هل أنت متأكد أنك تريد إلغاء هذا الموعد؟" - }, - "changePayment": { - "en": "Change Payment Method", - "ar": "تغيير طريقة الدفع" - }, - "upcomingNoAction": { - "en": "No Action Required", - "ar": "لا يتطلب أي إجراء" - }, - "upcomingConfirm": { - "en": "Please confirm the appointment to avoid cancellation", - "ar": "يرجى تأكيد الموعد لتجنب الإلغاء" - }, - "bookSuccessConfirmMore2412": { - "en": "The online payment process will be available 24 hours before the appointment.", - "ar": "ستكون عملية الدفع عبر الإنترنت متاحة قبل 24 ساعة من الموعد." - }, - "upcomingPaymentPending": { - "en": "Online Payment will be Activated before 24 Hours of Appointment Time", - "ar": "سيتم تفعيل الدفع عبر الإنترنت قبل 24 ساعة من موعد الموعد" - }, - "upcomingPaymentNow": { - "en": "Pay Online now to avoid long waiting queue", - "ar": "ادفع عبر الإنترنت الآن لتجنب الانتظار الطويل" - }, - "upcomingQR": { - "en": "Use the QR Code to Check-In in hospital", - "ar": "استخدم رمز الاستجابة السريعة لتسجيل الوصول في المستشفى" - }, - "upcomingVirtual": { - "en": "This is a virtual appointment, Please adhere to the instructions for a seamless experience.", - "ar": "هذا موعد افتراضي، يرجى الالتزام بالتعليمات لتجربة سلسة." - }, - "upcomingLivecare": { - "en": "This is a LiveCare appointment", - "ar": "هذا موعد لايف كير" - }, - "upcomingDetails": { - "en": "More Details", - "ar": "المزيد من التفاصيل" - }, - "reschedule": { - "en": "Reschedule", - "ar": "إعادة جدولة" - }, - "raise": { - "en": "Raise", - "ar": "رفع" - }, - "complaint": { - "en": "Complaint", - "ar": "شكوى" - }, - "add": { - "en": "Add", - "ar": "إضافة" - }, - "reminder": { - "en": "Reminder", - "ar": "تذكير" - }, - "location": { - "en": "Locations", - "ar": "المواقع" - }, - "online": { - "en": "Online", - "ar": "عبر الإنترنت" - }, - "payment": { - "en": "Payment", - "ar": "الدفع" - }, - "onlinePayment": { - "en": "Online", - "ar": "عبر الإنترنت" - }, - "onlinePaymentSubtitle": { - "en": "Payment", - "ar": "الدفع" - }, - "cancelNocaps": { - "en": "Cancel", - "ar": "إلغاء" - }, - "setReminder": { - "en": "Set Reminder", - "ar": "ضبط تذكير" - }, - "nationalIdNumber": { - "en": "National ID Number", - "ar": "رقم الهوية الوطنية" - }, - "medicalFileNumber": { - "en": "Medical File Number", - "ar": "رقم الملف الطبي" - }, - "loginregister": { - "en": "Login / Register", - "ar": "تسجيل الدخول / التسجيل" - }, - "poweredBy": { - "en": "Powered by", - "ar": "مدعوم من" - }, - "welcome": { - "en": "Welcome", - "ar": "مرحبًا" - }, - "welcomeToDrSulaiman": { - "en": "Welcome to Dr. Sulaiman Al Habib Medical Group", - "ar": "مرحباً بكم في مجموعة الدكتور سليمان الحبيب الطبية" - }, - "patientApp": { - "en": "Patient App", - "ar": "تطبيق المريض" - }, - "welcomeText": { - "en": "Dr. Sulaiman Al Habib Mobile Application", - "ar": "تطبيق الدكتور سليمان الحبيب للهاتف المحمول" - }, - "drSulaimanText": { - "en": "Dr. Sulaiman Al Habib", - "ar": "الدكتور سليمان الحبيب" - }, - "welcomeText2": { - "en": "Have you previously visited the hospitals or medical centers of Dr. Sulaiman Al Habib?", - "ar": "هل زرت مستشفيات أو مراكز الدكتور سليمان الحبيب من قبل؟" - }, - "yes": { - "en": "Yes", - "ar": "نعم" - }, - "no": { - "en": "No", - "ar": "لا" - }, - "logintyperadio": { - "en": " Choose from the below options to login to your medical file.", - "ar": "اختر من الخيارات أدناه لتسجيل الدخول إلى ملفك الطبي." - }, - "registernow": { - "en": "Register Now", - "ar": "سجل الآن" - }, - "nationalID": { - "en": "Enter the Identification Number", - "ar": "أدخل رقم الهوية" - }, - "nationalId": { - "en": "National ID", - "ar": "الهوية الوطنية" - }, - "fileNo": { - "en": "File Number", - "ar": "رقم الملف" - }, - "fileno": { - "en": "File No", - "ar": "رقم الملف" - }, - "forgotFileNo": { - "en": "Forgot file Number?", - "ar": "نسيت رقم الملف؟" - }, - "forgotFileNoTitle": { - "en": "Forgot medical file", - "ar": "نسيت الملف الطبي" - }, - "enterNationalId": { - "en": "Please enter mobile number and identification number", - "ar": "يرجى إدخال رقم الهاتف المحمول ورقم الهوية" - }, - "profileInfo": { - "en": "Please enter profile information", - "ar": "يرجى إدخال معلومات الملف الشخصي" - }, - "submit": { - "en": "Submit", - "ar": "إرسال" - }, - "forgotDesc": { - "en": "Enter the mobile number to receive the Medical File Number via SMS", - "ar": "أدخل رقم الهاتف المحمول لاستلام رقم الملف الطبي عبر الرسائل القصيرة" - }, - "dob": { - "en": "Birth Date:", - "ar": "تاريخ الميلاد:" - }, - "hijriDate": { - "en": "Hijri Date", - "ar": "التاريخ الهجري" - }, - "gregorianDate": { - "en": "Gregorian Date", - "ar": "التاريخ الميلادي" - }, - "verifyLoginWith": { - "en": "Please choose one of the following options to verify", - "ar": "يرجى اختيار واحدة من الخيارات التالية للتحقق" - }, - "registerUser": { - "en": "Register", - "ar": "تسجيل" - }, - "verifyWithFingerprint": { - "en": "Biometric", - "ar": "البيومترية" - }, - "verifyWithFaceid": { - "en": "Face ID", - "ar": "معرف الوجه" - }, - "verifyWithSms": { - "en": "SMS", - "ar": "رسالة قصيرة" - }, - "verifyWithWhatsapp": { - "en": "Whatsapp", - "ar": "واتساب" - }, - "verifyThrough": { - "en": "Verify Through", - "ar": "التحقق من خلال" - }, - "lastLogin": { - "en": "LAST LOGIN AT:", - "ar": "آخر تسجيل دخول في:" - }, - "lastLoginWith": { - "en": "VERIFICATION TYPE:", - "ar": "نوع التحقق:" - }, - "verifyFingerprint": { - "en": "To activate the fingerprint login service, please verify data by using one of the following options.", - "ar": "لتفعيل خدمة تسجيل الدخول ببصمة الإصبع، يرجى التحقق من البيانات باستخدام واحدة من الخيارات التالية." - }, - "searchMedicine": { - "en": "Search Medicine", - "ar": "ابحث عن دواء" - }, - "pharmaciesList": { - "en": "Pharmacies List", - "ar": "قائمة الصيدليات" - }, - "searchMedicineHere": { - "en": "Search Medicine Here", - "ar": "ابحث عن دواء هنا" - }, - "description": { - "en": "Description", - "ar": "الوصف" - }, - "howToUse": { - "en": "How to Use", - "ar": "كيفية الاستخدام" - }, - "price": { - "en": "Price", - "ar": "السعر" - }, - "youCanFindItIn": { - "en": "You can find it in", - "ar": "يمكنك العثور عليه في" - }, - "pleaseEnterMedicineName": { - "en": "Please Enter Medicine Name", - "ar": "يرجى إدخال اسم الدواء" - }, - "verificationMessage": { - "en": "Please enter the Verification Code sent to", - "ar": "يرجى إدخال رمز التحقق المرسل إلى" - }, - "validationMessage": { - "en": "The verification code expires in", - "ar": "ينتهي رمز التحقق في" - }, - "notification": { - "en": "Notifications", - "ar": "الإشعارات" - }, - "appSettings": { - "en": "App Settings", - "ar": "إعدادات التطبيق" - }, - "rateApp": { - "en": "Rate Our App", - "ar": "قيم تطبيقنا" - }, - "before": { - "en": "Before", - "ar": "قبل" - }, - "minute": { - "en": "Minutes", - "ar": "دقائق" - }, - "hour": { - "en": "Hour", - "ar": "ساعة" - }, - "reminderSuccess": { - "en": "The reminder has been added successfully", - "ar": "تمت إضافة التذكير بنجاح" - }, - "reminderCancelSuccess": { - "en": "The reminder has been cancelled successfully", - "ar": "تم إلغاء التذكير بنجاح" - }, - "patientShareToDo": { - "en": "Amount before tax: ", - "ar": "المبلغ قبل الضريبة: " - }, - "patientTaxToDo": { - "en": "Tax amount: ", - "ar": "قيمة الضريبة: " - }, - "patientShareTotalToDo": { - "en": "Total amount due: ", - "ar": "إجمالي المبلغ المستحق: " - }, - "paymentMethod": { - "en": "Payment Method", - "ar": "طريقة الدفع" - }, - "noNeedToWaitInLine": { - "en": "No need to stand in line.", - "ar": "لا حاجة للانتظار في الطابور." - }, - "useQRAppoAttend": { - "en": "Use the QR code to register the appointment attendance.", - "ar": "استخدم رمز الاستجابة السريعة لتسجيل حضور الموعد." - }, - "passQRAppoAttend": { - "en": "Pass the QR code through the attendance devices available in the Hospital.", - "ar": "مرر رمز الاستجابة السريعة عبر أجهزة الحضور المتاحة في المستشفى." - }, - "sitWaitingQR": { - "en": "Sit in the waiting rooms until called by the nurse.", - "ar": "اجلس في غرف الانتظار حتى يتم استدعاؤك من قبل الممرضة." - }, - "attendRegisterCode": { - "en": "Attendance registration code", - "ar": "رمز تسجيل الحضور" - }, - "scanQRHospital": { - "en": "Approach the Online Check-In board in the hospital & scan via NFC or QR Code to Check-In", - "ar": "توجّه إلى لوحة تسجيل الوصول الإلكتروني في المستشفى، وقم بالمسح عبر تقنية NFC أو رمز الاستجابة السريعة (QR) لإتمام تسجيل الوصول." - }, - "scanNFC": { - "en": "Scan NFC to Check-In", - "ar": "امسح NFC لتسجيل الوصول" - }, - "sendEmail": { - "en": "Send Email", - "ar": "إرسال بريد إلكتروني" - }, - "success": { - "en": "Done successfully", - "ar": "تم بنجاح" - }, - "emailSentSuccessfully": { - "en": "Email Sent Successfully", - "ar": "تم إرسال البريد الإلكتروني بنجاح" - }, - "emailSentError": { - "en": "Error Sending Email", - "ar": "خطأ في إرسال البريد الإلكتروني" - }, - "close": { - "en": "Close", - "ar": "إغلاق" - }, - "closeIt": { - "en": "Close", - "ar": "أغلق" - }, - "booked": { - "en": "Booked", - "ar": "محجوز" - }, - "confirmed": { - "en": "Confirmed", - "ar": "مؤكد" - }, - "arrived": { - "en": "Arrived", - "ar": "وصل" - }, - "payNowBookSuccess": { - "en": "Pay now via Al Habib App", - "ar": "ادفع الآن عبر تطبيق الحبيب" - }, - "payNowBookSuccesstext1": { - "en": "Pay Now using online payment service from secure payment gateways", - "ar": "ادفع الآن باستخدام خدمة الدفع عبر الإنترنت من بوابات الدفع الآمنة" - }, - "payNowBookSuccesstext2": { - "en": "You can also Pay Later via online payment or in Hospital", - "ar": "يمكنك أيضًا الدفع لاحقًا عبر الدفع الإلكتروني أو في المستشفى." - }, - "payLater": { - "en": "Pay Later", - "ar": "ادفع لاحقًا" - }, - "askDocNotAllowed": { - "en": "This service will be available for last 15 days’ doctor Visit only", - "ar": "هذه الخدمة ستكون متاحة فقط لزيارة الطبيب قبل 15 يومًا" - }, - "moreVerify": { - "en": "More Verification Options", - "ar": "خيارات تحقق إضافية" - }, - "welcomeBack": { - "en": "Welcome back!", - "ar": "مرحبًا بعودتك!" - }, - "accountInfo": { - "en": "Would you like to login with current username?", - "ar": "هل ترغب في تسجيل الدخول باستخدام اسم المستخدم الحالي؟" - }, - "anotherAcc": { - "en": "Use Another Account", - "ar": "استخدم حسابًا آخر" - }, - "next": { - "en": "Next", - "ar": "التالي" - }, - "firstName": { - "en": "First Name", - "ar": "الاسم الأول" - }, - "middleName": { - "en": "Middle Name", - "ar": "اسم الأب" - }, - "lastName": { - "en": "Last Name", - "ar": "اسم العائلة" - }, - "female": { - "en": "Female", - "ar": "أنثى" - }, - "male": { - "en": "Male", - "ar": "ذكر" - }, - "preferredLanguage": { - "en": "Preferred Language *", - "ar": "اللغة المفضلة *" - }, - "locationsRegister": { - "en": "Where do you want to create this file?", - "ar": "أين ترغب في إنشاء هذا الملف؟" - }, - "ksa": { - "en": "KSA", - "ar": "السعودية" - }, - "dubai": { - "en": "Dubai", - "ar": "دبي" - }, - "enterEmail": { - "en": "Please Enter Email", - "ar": "يرجى إدخال البريد الإلكتروني" - }, - "family": { - "en": "My Family", - "ar": "عائلتي" - }, - "familyTitle": { - "en": "My Family Files", - "ar": "ملفات عائلتي" - }, - "myFamily": { - "en": "MY FAMILY", - "ar": "عائلتي" - }, - "addNewMember": { - "en": "Add Family Member", - "ar": "إضافة فرد جديد للعائلة" - }, - "sentRequests": { - "en": "Sent Requests", - "ar": "الطلبات المرسلة" - }, - "recievedRequests": { - "en": "Recieved Requests", - "ar": "الطلبات المستلمة" - }, - "manageFiles": { - "en": "Manage Family Files", - "ar": "إدارة ملفات العائلة" - }, - "oxygenation": { - "en": "Oxygenation", - "ar": "تشبع الأكسجين" - }, - "bodyMeasurements": { - "en": "body Mass Index", - "ar": "مؤشر كتلة الجسم" - }, - "temperature": { - "en": "Temperature", - "ar": "درجة الحرارة" - }, - "pulse": { - "en": "Pulse", - "ar": "النبض" - }, - "respiration": { - "en": "Respiration", - "ar": "التنفس" - }, - "bloodPressure": { - "en": "Blood Pressure", - "ar": "ضغط الدم" - }, - "painScale": { - "en": "Pain Scale", - "ar": "مقياس الألم" - }, - "weight": { - "en": "Weight", - "ar": "الوزن" - }, - "height": { - "en": "Height", - "ar": "الطول" - }, - "heart": { - "en": "Heart Rate", - "ar": "معدل ضربات القلب" - }, - "heightUnit": { - "en": "height unit", - "ar": "وحدة الطول" - }, - "weightUnit": { - "en": "Weight Unit", - "ar": "وحدة الوزن" - }, - "unit": { - "en": "Unit", - "ar": "الوحدة" - }, - "request": { - "en": "Request", - "ar": "طلب" - }, - "memberName": { - "en": "Member Name", - "ar": "اسم العضو" - }, - "switchLogin": { - "en": "Switch", - "ar": "تبديل" - }, - "removeMember": { - "en": "Remove", - "ar": "إزالة" - }, - "allowView": { - "en": "Allow", - "ar": "السماح" - }, - "rejectView": { - "en": "Reject", - "ar": "رفض" - }, - "deleteView": { - "en": "Delete", - "ar": "حذف" - }, - "approvals": { - "en": "Approvals", - "ar": "الموافقات" - }, - "approvalNo": { - "en": "Approval No:", - "ar": "رقم الموافقة:" - }, - "companyName": { - "en": "Company Name:", - "ar": "اسم الشركة:" - }, - "receiptOn": { - "en": "Receipt on:", - "ar": "الإيصال على:" - }, - "expiryDate": { - "en": "Expiry Date:", - "ar": "تاريخ الانتهاء:" - }, - "expiryPoints": { - "en": "Expired", - "ar": "منتهي الصلاحية" - }, - "expiryOn": { - "en": "Expiry on:", - "ar": "ينتهي في:" - }, - "procedureName": { - "en": "Procedure Name:", - "ar": "اسم الإجراء:" - }, - "procedure": { - "en": "Procedure", - "ar": "الإجراء" - }, - "procedureStatus": { - "en": "Procedure Status: ", - "ar": "حالة الإجراء: " - }, - "usageStatus": { - "en": "Usage Status", - "ar": "حالة الاستخدام" - }, - "unusedCount": { - "en": "Unused Count:", - "ar": "عدد غير المستخدم:" - }, - "totalApproval": { - "en": "Total approval unused", - "ar": "إجمالي الموافقة غير المستخدمة" - }, - "category": { - "en": "Category: ", - "ar": "الفئة: " - }, - "expirationDate": { - "en": "Expiration Date: ", - "ar": "تاريخ انتهاء الصلاحية: " - }, - "patientCard": { - "en": "Patient Card ID: ", - "ar": "رقم بطاقة المريض: " - }, - "policyNumber": { - "en": "Policy Number: ", - "ar": "رقم الوثيقة: " - }, - "seeDetails": { - "en": "SEE DETAILS", - "ar": "عرض التفاصيل" - }, - "insuranceCards": { - "en": "Insurance Cards", - "ar": "بطاقات التأمين" - }, - "requestType": { - "en": "Request Type", - "ar": "نوع الطلب" - }, - "registerInfoFamily": { - "en": "How would like to add the new member?", - "ar": "كيف تود إضافة عضو جديد؟" - }, - "removeFamilyMember": { - "en": "Remove this member?", - "ar": "هل تريد إزالة هذا العضو؟" - }, - "myMedicalFile": { - "en": "My Medical File", - "ar": "ملفي الطبي" - }, - "myMedicalFileSubTitle": { - "en": "All your medical records", - "ar": "جميع سجلاتك الطبية" - }, - "viewMore": { - "en": "View More", - "ar": "عرض المزيد" - }, - "homeHealthCareService": { - "en": "Home Health Care Service", - "ar": "خدمة الرعاية الصحية المنزلية" - }, - "onlinePharmacy": { - "en": "Online Pharmacy", - "ar": "الصيدلية الإلكترونية" - }, - "emergencyService": { - "en": "Emergency Service", - "ar": "خدمة الطوارئ" - }, - "onlinePaymentService": { - "en": "Online Payment Service", - "ar": "خدمة الدفع عبر الإنترنت" - }, - "offersAndPackages": { - "en": "Online transfer request", - "ar": "طلب تحويل عبر الإنترنت" - }, - "comprehensiveMedicalCheckup": { - "en": "Comprehensive Medical Check-up", - "ar": "فحص طبي شامل" - }, - "hmgService": { - "en": "HMG Service", - "ar": "خدمة HMG" - }, - "viewAllHabibMedicalService": { - "en": "View All Habib Medical Service", - "ar": "عرض جميع خدمات الحبيب الطبية" - }, - "viewAll": { - "en": "View All", - "ar": "عرض الكل" - }, - "view": { - "en": "View", - "ar": "عرض" - }, - "contactUs": { - "en": "Contact Us", - "ar": "اتصل بنا" - }, - "contactUsLocation": { - "en": "P.O.Box: 91877 - Riyadh 11643, King Fahad Road - Olaya - Kingdom of Saudi Arabia", - "ar": "ص.ب: 91877 - الرياض 11643، طريق الملك فهد - العليا - المملكة العربية السعودية" - }, - "contactUsTime": { - "en": "Saturday - Wednesday 8:00 AM - 10 PM, Thursday 8:00 AM- 8:00 PM, Friday 2:00 PM - 8:00 PM", - "ar": "السبت - الأربعاء 8:00 صباحًا - 10 مساءً، الخميس 8:00 صباحًا- 8:00 مساءً، الجمعة 2:00 مساءً - 8:00 مساءً" - }, - "viewAllWaysReachUs": { - "en": "View All Ways Reach Us", - "ar": "عرض جميع طرق التواصل معنا" - }, - "medicalProfile": { - "en": "Medical Profile", - "ar": "الملف الطبي" - }, - "consultation": { - "en": "Consultation", - "ar": "استشارة" - }, - "logs": { - "en": "Logs", - "ar": "السجلات" - }, - "textToSpeech": { - "en": "How May I Help You?", - "ar": "كيف يمكنني مساعدتك؟" - }, - "locationDialogMessage": { - "en": "Allow the HMG app to access your location will assist you in showing the hospitals according to the nearest to you.", - "ar": "السماح لتطبيق HMG بالوصول إلى موقعك سيساعدك في عرض المستشفيات الأقرب إليك." - }, - "userViewRequester": { - "en": "User Wants to View Your Medical File", - "ar": "يريد المستخدم عرض ملفك الطبي" - }, - "userView": { - "en": "User Can View Your Medical File", - "ar": "يمكن للمستخدم عرض ملفك الطبي" - }, - "parking": { - "en": "Parking", - "ar": "موقف السيارات" - }, - "alhabiServices": { - "en": "HMG Service", - "ar": "خدمة HMG" - }, - "parkingTitle": { - "en": "Car service, car service, service to save parking information, return to it later, 1- By clicking on (Read the code), save the parking data. 2- By clicking on the button (view my car park), it shows you the car’s location in Google Maps. 3- Read another position by pressing the Clear Position Data button.", - "ar": "خدمة السيارة، خدمة السيارة، خدمة لحفظ معلومات الموقف، العودة إليها لاحقًا، 1- من خلال النقر على (قراءة الرمز)، حفظ بيانات الموقف. 2- من خلال النقر على زر (عرض موقف سيارتي)، يظهر لك موقع السيارة في خرائط Google. 3- قراءة موضع آخر بالضغط على زر مسح بيانات الموضع." - }, - "parkingDescription": { - "en": "Parking service is for you to scan the car location so you can find it easy on you way out. click on (scan parking) button to save the parking location, then (show my park) button will appear to show you the way for the parking. if you want to rescan parking QR just click on (Clear My Data).", - "ar": "خدمة المواقف هي لك لمسح موقع السيارة حتى تتمكن من العثور عليها بسهولة عند مغادرتك. انقر على زر (مسح الموقف) لحفظ موقع الموقف، ثم سيظهر زر (عرض موقفي) لإظهار الطريق إلى الموقف. إذا كنت ترغب في إعادة مسح موقف السيارة QR فقط انقر على (مسح بياناتي)." - }, - "appointments": { - "en": "Appointments", - "ar": "المواعيد" - }, - "all2": { - "en": "All", - "ar": "الكل" - }, - "checkinOption": { - "en": "Check-In", - "ar": "تسجيل الوصول" - }, - "readBarcode": { - "en": "Read Barcode", - "ar": "قراءة الكود" - }, - "showMyPark": { - "en": "Show My Park", - "ar": "عرض الموقف" - }, - "clearMyData": { - "en": "Clear My Data", - "ar": "امسح البيانات" - }, - "floor": { - "en": "Floor:", - "ar": "الطابق:" - }, - "gate": { - "en": "Gate:", - "ar": "البوابة:" - }, - "building": { - "en": "Building:", - "ar": "المبنى:" - }, - "branch": { - "en": "Branch:", - "ar": "الفرع:" - }, - "emergencyServices": { - "en": "Emergency Services", - "ar": "خدمات الطوارئ" - }, - "nearester": { - "en": "Nearest ER", - "ar": "أقرب طوارئ" - }, - "locationa": { - "en": "Location", - "ar": "الموقع" - }, - "callNow": { - "en": "Call now", - "ar": "اتصل الآن" - }, - "ambulancerequest": { - "en": "Ambulance", - "ar": "طلب إسعاف" - }, - "requestA": { - "en": "Request", - "ar": "طلب" - }, - "noBookedAppointments": { - "en": "No Booked Appointments", - "ar": "لا توجد مواعيد محجوزة" - }, - "noConfirmedAppointments": { - "en": "No Confirmed Appointments", - "ar": "لا توجد مواعيد مؤكدة" - }, - "noArrivedAppointments": { - "en": "No Arrived Appointments", - "ar": "لا توجد مواعيد تم تسجيل الوصول إليها" - }, - "myAppointmentsList": { - "en": "Appointments", - "ar": "المواعيد" - }, - "myAppointments": { - "en": "My", - "ar": "مواعيدي" - }, - "radiology": { - "en": "Radiology", - "ar": "الأشعة" - }, - "radiologySubtitle": { - "en": "Result", - "ar": "النتيجة" - }, - "lab": { - "en": "Lab", - "ar": "المختبر" - }, - "labSubtitle": { - "en": "Results", - "ar": "النتائج" - }, - "medicines": { - "en": "Medicines", - "ar": "الأدوية" - }, - "medicinesSubtitle": { - "en": "Prescriptions", - "ar": "الوصفات" - }, - "vitalSigns": { - "en": "Vital Signs", - "ar": "علامات حيوية" - }, - "vitalSignsSubTitle": { - "en": "Reports", - "ar": "التقارير" - }, - "myMedical": { - "en": "Active", - "ar": "نشط" - }, - "myMedicalSubtitle": { - "en": "Medications", - "ar": "الأدوية" - }, - "myDoctor": { - "en": "My Doctor", - "ar": "طبيبي" - }, - "myDoctorSubtitle": { - "en": "List", - "ar": "القائمة" - }, - "eye": { - "en": "Eye", - "ar": "العين" - }, - "eyeSubtitle": { - "en": "Measurement", - "ar": "القياس" - }, - "insurance": { - "en": "Insurance", - "ar": "التأمين" - }, - "insuranceSubtitle": { - "en": "Card", - "ar": "البطاقة" - }, - "updateInsurance": { - "en": "Update", - "ar": "تحديث" - }, - "updateInsuranceSubtitle": { - "en": "Insurance", - "ar": "التأمين" - }, - "insuranceApproval": { - "en": "Insurance", - "ar": "التأمين" - }, - "insuranceApprovalSubtitle": { - "en": "Approvals", - "ar": "الموافقات" - }, - "allergies": { - "en": "Allergies", - "ar": "الحساسية" - }, - "allergiesSubtitle": { - "en": "List", - "ar": "القائمة" - }, - "myVaccines": { - "en": "My Vaccines", - "ar": "لقاحاتي" - }, - "myVaccinesSubtitle": { - "en": "List", - "ar": "القائمة" - }, - "medical": { - "en": "Medical", - "ar": "طبي" - }, - "medicalSubtitle": { - "en": "Report", - "ar": "التقرير" - }, - "monthly": { - "en": "Monthly", - "ar": "شهري" - }, - "monthlySubtitle": { - "en": "Report", - "ar": "التقرير" - }, - "sick": { - "en": "Sick", - "ar": "مريض" - }, - "sickSubtitle": { - "en": "Leaves", - "ar": "الإجازات" - }, - "myBalance": { - "en": "My Balance", - "ar": "رصيدي" - }, - "myBalanceSubtitle": { - "en": "Credit", - "ar": "الرصيد" - }, - "patientCall": { - "en": "Patient Call", - "ar": "مكالمة المريض" - }, - "patientCallSubtitle": { - "en": "Service", - "ar": "الخدمة" - }, - "smartWatches": { - "en": "Smart Watches", - "ar": "الساعات الذكية" - }, - "smartWatchesSubtitle": { - "en": "Pairing", - "ar": "الاقتران" - }, - "myTrackers": { - "en": "My Trackers", - "ar": "متعقباتي" - }, - "myTrackersSubtitle": { - "en": "Service", - "ar": "الخدمة" - }, - "askYour": { - "en": "Ask Your", - "ar": "اسأل" - }, - "askYourSubtitle": { - "en": "Doctor", - "ar": "طبيبك" - }, - "internet": { - "en": "Internet", - "ar": "الإنترنت" - }, - "internetSubtitle": { - "en": "Pairing", - "ar": "الاقتران" - }, - "chatbot": { - "en": "Chatbot", - "ar": "الدردشة الآلية" - }, - "chatbotSubtitle": { - "en": "", - "ar": "" - }, - "timeLine": { - "en": "Timeline", - "ar": "الخط الزمني" - }, - "labOrders": { - "en": "Lab Orders", - "ar": "طلبات المختبر" - }, - "billNo": { - "en": "Bill No:", - "ar": "رقم الفاتورة:" - }, - "prescriptions": { - "en": "Prescriptions", - "ar": "الوصفات" - }, - "history": { - "en": "History", - "ar": "التاريخ" - }, - "orderNo": { - "en": "Order No", - "ar": "رقم الطلب" - }, - "orderDetails": { - "en": "Order Details", - "ar": "تفاصيل الطلب" - }, - "deliveryDriverTrack": { - "en": "Driver Tracking", - "ar": "تتبع السائق" - }, - "deliveryLocation": { - "en": "Delivery Location", - "ar": "موقع التسليم" - }, - "driver": { - "en": "Driver", - "ar": "السائق" - }, - "vitalSign": { - "en": "Vital Sign", - "ar": "علامة حيوية" - }, - "monthlyReports": { - "en": "Monthly Reports", - "ar": "تقارير شهرية" - }, - "km": { - "en": "KMs:", - "ar": "كم:" - }, - "km_": { - "en": "KM", - "ar": "كم" - }, - "patientHealthSummaryReport": { - "en": "Patient Health Summary Report", - "ar": "تقرير ملخص صحة المريض" - }, - "toViewTheTermsAndConditions": { - "en": "To View the Terms and Conditions Report", - "ar": "لعرض الشروط والأحكام" - }, - "clickHere": { - "en": "Click here", - "ar": "انقر هنا" - }, - "iAgreeToTheTermsAndConditions": { - "en": "I agree to the terms and conditions ", - "ar": "أوافق على الشروط والأحكام " - }, - "iAgreeToTheTermsAndConditionsSubtitle": { - "en": "I agree to the terms and conditions ", - "ar": "أوافق على الشروط والأحكام " - }, - "save": { - "en": "Save", - "ar": "حفظ" - }, - "userAgreement": { - "en": "User Agreement", - "ar": "اتفاقية المستخدم" - }, - "updateSuccessfully": { - "en": "Update Successfully", - "ar": "تم التحديث بنجاح" - }, - "checkVaccineAvailability": { - "en": "CHECK VACCINE AVAILABILITY", - "ar": "تحقق من توفر اللقاح" - }, - "myVaccinesAvailability": { - "en": "My Vaccines Availability", - "ar": "توفر اللقاحات الخاصة بي" - }, - "paymentService": { - "en": "Payment Service", - "ar": "خدمة الدفع" - }, - "paymentOnline": { - "en": "Service", - "ar": "الخدمة" - }, - "onlineCheckIn": { - "en": "Online Check-In", - "ar": "تسجيل الوصول عبر الإنترنت" - }, - "myBalances": { - "en": "My Balances", - "ar": "رصيدي" - }, - "myWallet": { - "en": "My Wallet", - "ar": "محفظتي" - }, - "balanceAmount": { - "en": "Wallet Amount", - "ar": "مبلغ المحفظة" - }, - "totalBalance": { - "en": "Total Balance", - "ar": "إجمالي الرصيد" - }, - "createAdvancedPayment": { - "en": "Recharge Wallet", - "ar": "إعادة شحن المحفظة" - }, - "advancePayment": { - "en": "Advance Payment", - "ar": "دفع مسبق" - }, - "advancePaymentLabel": { - "en": "You can create and add an Advanced Payment for your account or other accounts.", - "ar": "يمكنك إنشاء وإضافة دفعة مقدمة لحسابك أو حسابات أخرى." - }, - "fileNumber": { - "en": "File Number", - "ar": "رقم الملف" - }, - "amount": { - "en": "Amount *", - "ar": "المبلغ *" - }, - "depositorEmail": { - "en": "Depositor Email *", - "ar": "البريد الإلكتروني للودائع *" - }, - "notes": { - "en": "Notes", - "ar": "ملاحظات" - }, - "selectPatientName": { - "en": "Select Patient Name", - "ar": "اختر اسم المريض" - }, - "selectFamilyPatientName": { - "en": "Family Members", - "ar": "أفراد العائلة" - }, - "selectHospital": { - "en": "Select Hospital", - "ar": "اختر المستشفى" - }, - "selectCity": { - "en": "Select City", - "ar": "اختر المدينة" - }, - "city": { - "en": "City", - "ar": "المدينة" - }, - "distance": { - "en": "Distance", - "ar": "المسافة" - }, - "myAccount": { - "en": "My Account", - "ar": "حسابي" - }, - "otherAccount": { - "en": "Other Account", - "ar": "حساب آخر" - }, - "selectBeneficiary": { - "en": "Select Beneficiary", - "ar": "اختر المستفيد" - }, - "confirmThePayment": { - "en": "Confirm The Payment", - "ar": "تأكيد الدفع" - }, - "depositorName": { - "en": "Depositor Name", - "ar": "اسم مُقدِّم الإيداع" - }, - "mobileNumber": { - "en": "Mobile Number", - "ar": "رقم الجوال" - }, - "phoneNumber": { - "en": "Phone Number", - "ar": "رقم الهاتف" - }, - "country": { - "en": "Country", - "ar": "البلد" - }, - "ok": { - "en": "Ok", - "ar": "حسنا" - }, - "averageWaitingTime": { - "en": "Average Waiting Time:", - "ar": "متوسط وقت الانتظار:" - }, - "waitingTime": { - "en": "Expected waiting time:", - "ar": "وقت الانتظار المتوقع:" - }, - "waterConsumedInWeek": { - "en": "Water consumed in a week", - "ar": "الماء المستهلك في أسبوع" - }, - "waterConsumedInMonth": { - "en": "Water consumed in a month", - "ar": "الماء المستهلك في شهر" - }, - "theVerificationCodeExpiresIn": { - "en": "The Verification Code Expires in", - "ar": "ينتهي رمز التحقق في" - }, - "pleaseEnterTheVerificationCode": { - "en": "Please enter the verification code send to", - "ar": "يرجى إدخال رمز التحقق المرسل إلى" - }, - "eyeMeasurements": { - "en": "Eye Measurements", - "ar": "قياسات العين" - }, - "measurements": { - "en": "Measurements", - "ar": "قياسات" - }, - "classes": { - "en": "Glasses", - "ar": "نظارات" - }, - "contactLens": { - "en": "Contact Lens", - "ar": "عدسات لاصقة" - }, - "rightEye": { - "en": "Right Eye", - "ar": "العين اليمنى" - }, - "sphere": { - "en": "Sphere", - "ar": "الكرة" - }, - "cylinder": { - "en": "Cylinder", - "ar": "الأسطوانة" - }, - "axis": { - "en": "Axis", - "ar": "المحور" - }, - "prism": { - "en": "Prism", - "ar": "الهرم" - }, - "va": { - "en": "VA", - "ar": "VA" - }, - "leftEye": { - "en": "Left Eye", - "ar": "العين اليسرى" - }, - "brand": { - "en": "Brand", - "ar": "العلامة التجارية" - }, - "power": { - "en": "Power", - "ar": "القوة" - }, - "diameter": { - "en": "Diameter", - "ar": "القطر" - }, - "remarks": { - "en": "", - "ar": "ملاحظات: " - }, - "activeMedications": { - "en": "Active Medications", - "ar": "الأدوية النشطة" - }, - "expDate": { - "en": "Active Exp Date :", - "ar": "تاريخ انتهاء الصلاحية:" - }, - "route": { - "en": "", - "ar": "الطريق" - }, - "frequency": { - "en": "", - "ar": "التكرار" - }, - "dailyQuantity": { - "en": "Daily Quantity :", - "ar": "الكمية اليومية:" - }, - "addReminder": { - "en": "Add Reminder", - "ar": "إضافة تذكير" - }, - "cancelReminder": { - "en": "Cancel Reminder", - "ar": "إلغاء التذكير" - }, - "reminderDes": { - "en": "Please select treatment start day and time to be notified when it's time to take the medicine", - "ar": "يرجى تحديد يوم ووقت بدء العلاج ليتم إعلامك عندما يحين وقت تناول الدواء" - }, - "pleaseSelectAllQuestionToContinue": { - "en": "Please answer all questions to continue...", - "ar": "يرجى الإجابة على جميع الأسئلة للمتابعة..." - }, - "startDay": { - "en": "Start Day", - "ar": "يوم البدء" - }, - "endDay": { - "en": "End Day", - "ar": "يوم الانتهاء" - }, - "days": { - "en": "Days ", - "ar": "أيام " - }, - "pleaseVerify": { - "en": "Please Verify ", - "ar": "يرجى التحقق " - }, - "scheduleTime": { - "en": "Schedule time", - "ar": "وقت الجدولة" - }, - "askDoctor": { - "en": "Ask Doctor", - "ar": "اسأل الطبيب" - }, - "doctorResponses": { - "en": "Doctor Responses", - "ar": "ردود الطبيب" - }, - "ne_w": { - "en": "New", - "ar": "جديد" - }, - "all": { - "en": "All", - "ar": "الكل" - }, - "dailyWater": { - "en": "Daily Water Check", - "ar": "متابعة الماء اليومية" - }, - "questionHere": { - "en": "Enter the question here...", - "ar": "أدخل السؤال هنا..." - }, - "viewDoctorResponses": { - "en": "View Doctor Responses", - "ar": "عرض ردود الطبيب" - }, - "serviceInformationButton": { - "en": "LOGIN / REGISTER", - "ar": "تسجيل الدخول / التسجيل" - }, - "serviceInformationTitle": { - "en": "Service Information", - "ar": "معلومات الخدمة" - }, - "serviceInformation": { - "en": "Service Information", - "ar": "معلومات الخدمة" - }, - "homeHealthCare": { - "en": "Home Health Care", - "ar": "الرعاية الصحية المنزلية" - }, - "noAppointmentAvailable": { - "en": "No Available Appointments", - "ar": "لا توجد مواعيد متاحة" - }, - "homeHealthCareText": { - "en": "This service provides a set of home health care services, continuous and comprehensive follow-up in their places of residence for those who cannot access health facilities, such as (laboratory analyzes - radiology - vaccinations - physical therapy), etc.", - "ar": "تقدم هذه الخدمة مجموعة من خدمات الرعاية الصحية المنزلية، والمتابعة المستمرة والشاملة في أماكن إقامتهم لأولئك الذين لا يمكنهم الوصول إلى المرافق الصحية، مثل (تحليلات المختبر - الأشعة - التطعيمات - العلاج الطبيعي)، إلخ." - }, - "loginRegister": { - "en": "Login/Register", - "ar": "تسجيل الدخول / التسجيل" - }, - "orderLog": { - "en": "Order Log", - "ar": "سجل الطلب" - }, - "infoLab": { - "en": "This service allows you to view the results of all laboratory tests performed in Al Habib Medical Group as well as sending the report via e-mail.", - "ar": "تتيح لك هذه الخدمة عرض نتائج جميع الفحوصات المخبرية التي أجريت في مجموعة الحبيب الطبية بالإضافة إلى إرسال التقرير عبر البريد الإلكتروني." - }, - "infoRadiology": { - "en": "This service allows you to view the reports and photos of radiology in Al Habib Medical Group as well as send the report by e-mail.", - "ar": "تتيح لك هذه الخدمة عرض تقارير وصور الأشعة في مجموعة الحبيب الطبية بالإضافة إلى إرسال التقرير عبر البريد الإلكتروني." - }, - "noReviewsAvailable": { - "en": "No Reviews Available", - "ar": "لا توجد تقييمات متاحة" - }, - "noLocationAvailable": { - "en": "No Location Available", - "ar": "لا توجد مواقع متاحة" - }, - "orders": { - "en": "Orders", - "ar": "الطلبات" - }, - "lakum": { - "en": "", - "ar": "لكم" - }, - "lakumMsg": { - "en": "", - "ar": "لا توجد تفاصيل عن النقاط" - }, - "lakumPoint": { - "en": "Lakum Points", - "ar": "نقاط لكم" - }, - "wishlist": { - "en": "Wishlist", - "ar": "قائمة الرغبات" - }, - "products": { - "en": "Products", - "ar": "المنتجات" - }, - "reviews": { - "en": "Reviews", - "ar": "التقييمات" - }, - "brands": { - "en": "Brands", - "ar": "العلامات التجارية" - }, - "productDetails": { - "en": "Product Details", - "ar": "تفاصيل المنتج" - }, - "medicationRefill": { - "en": "Medication Refill", - "ar": "إعادة تعبئة الدواء" - }, - "pillReminder": { - "en": "Pill Reminder", - "ar": "تذكير بالدواء" - }, - "shippingAddresses": { - "en": "Shipping Addresses", - "ar": "عناوين الشحن" - }, - "reachUs": { - "en": "Reach Us", - "ar": "تواصل معنا" - }, - "ourLocations": { - "en": "Our Locations", - "ar": "مواقعنا" - }, - "edit": { - "en": "Edit", - "ar": "تعديل" - }, - "whatsApp": { - "en": "Whats App", - "ar": "واتساب" - }, - "phone": { - "en": "Phone", - "ar": "الهاتف" - }, - "delete": { - "en": "Delete", - "ar": "حذف" - }, - "deleteAddress": { - "en": "Are you sure want to delete", - "ar": "هل أنت متأكد أنك تريد الحذف" - }, - "deletedAddres": { - "en": "Address has been deleted", - "ar": "تم حذف العنوان" - }, - "addAddress": { - "en": "ADD A NEW ADDRESS", - "ar": "إضافة عنوان جديد" - }, - "addNewAddress": { - "en": "Add New Address", - "ar": "إضافة عنوان جديد" - }, - "order": { - "en": "My Order", - "ar": "طلبي" - }, - "delivered": { - "en": "Delivered", - "ar": "تم التوصيل" - }, - "pending": { - "en": "Pending", - "ar": "قيد الانتظار" - }, - "enterNameHere": { - "en": "Enter Your Name", - "ar": "أدخل اسمك هنا" - }, - "processing": { - "en": "Processing", - "ar": "جاري المعالجة" - }, - "cancelled": { - "en": "Cancelled", - "ar": "ملغى" - }, - "writeReview": { - "en": "Write Review", - "ar": "اكتب تقييمًا" - }, - "shareReview": { - "en": "SHARE REVIEW", - "ar": "شارك التقييم" - }, - "review": { - "en": " reviews", - "ar": " التقييمات" - }, - "viewMedicalFile": { - "en": "View Details", - "ar": "عرض التفاصيل" - }, - "viewAllServices": { - "en": "View All Services", - "ar": "عرض جميع الخدمات" - }, - "medicalFile": { - "en": "Medical File", - "ar": "الملف الطبي" - }, - "verified": { - "en": "Verified", - "ar": "تم التحقق" - }, - "checkup": { - "en": "Checkup", - "ar": "فحص" - }, - "hhcHome": { - "en": "Home", - "ar": "الرئيسية" - }, - "refferal": { - "en": "E-Refferal", - "ar": "إحالة إلكترونية" - }, - "refferalTitle": { - "en": "E-Refferal", - "ar": "إحالة إلكترونية" - }, - "refferalSubTitle": { - "en": "Service", - "ar": "الخدمة" - }, - "healthCare": { - "en": "Health Care", - "ar": "الرعاية الصحية" - }, - "emergency": { - "en": "Emergency", - "ar": "حالة طوارئ" - }, - "erservices": { - "en": "Emergency", - "ar": "خدمات الطوارئ" - }, - "services2": { - "en": "Services", - "ar": "الخدمات" - }, - "cantSeeProfile": { - "en": "To view your medical profile, please log in or register now", - "ar": "لرؤية ملفك الطبي، يرجى تسجيل الدخول أو التسجيل الآن" - }, - "loginRegisterNow": { - "en": "Login or Register Now", - "ar": "تسجيل الدخول أو التسجيل الآن" - }, - "hmgPharmacy": { - "en": "HMG Pharmacy", - "ar": "صيدلية مجموعة الحبيب الطبية" - }, - "ecommerceSolution": { - "en": "Ecommerce Solution", - "ar": "حلول التجارة الإلكترونية" - }, - "comprehensive": { - "en": "Comprehensive", - "ar": "شامل" - }, - "onlineConsulting": { - "en": "Online Consulting", - "ar": "استشارات عبر الإنترنت" - }, - "pendingOrder": { - "en": " PENDING", - "ar": " قيد الانتظار" - }, - "deliveredOrder": { - "en": " DELIVERED", - "ar": " تم التوصيل" - }, - "processingOrder": { - "en": " PROCESSING", - "ar": " جارٍ المعالجة" - }, - "cancelledOrder": { - "en": " CANCELLED", - "ar": " ملغى" - }, - "compare": { - "en": " Compare", - "ar": " قارن" - }, - "medicationsRefill": { - "en": " Medication Refill", - "ar": " إعادة تعبئة الأدوية" - }, - "recommended": { - "en": " Recommended for You", - "ar": " موصى به لك" - }, - "myPrescription": { - "en": " My Prescriptions", - "ar": " وصفتي" - }, - "quantity": { - "en": " QTY ", - "ar": " الكمية " - }, - "reviewAppointment": { - "en": " Review Appointment ", - "ar": " مراجعة الموعد " - }, - "backMyAccount": { - "en": "BACK TO MY ACCOUNT ", - "ar": "العودة إلى حسابي " - }, - "reviewSuccessful": { - "en": "Review Successful", - "ar": "تمت مراجعة الطلب بنجاح" - }, - "reviewShared": { - "en": "Your review has been shared on product review section", - "ar": "تمت مشاركة تقييمك في قسم تقييم المنتج" - }, - "reviewComment": { - "en": "Your reviews help other to choose better product", - "ar": "تساعد تقييماتك الآخرين على اختيار منتج أفضل" - }, - "shippedMethod": { - "en": "SHIP BY:", - "ar": "الشحن بواسطة:" - }, - "orderDetail": { - "en": "Order Details", - "ar": "تفاصيل الطلب" - }, - "orderSummary": { - "en": "Order Summary", - "ar": "ملخص الطلب" - }, - "subtotal": { - "en": "Subtotal", - "ar": "المجموع الفرعي" - }, - "shipping": { - "en": "Shipping", - "ar": "الشحن" - }, - "shipBy": { - "en": "SHIP BY:", - "ar": "الشحن بواسطة:" - }, - "lakumPoints": { - "en": "Lakum Points", - "ar": "نقاط لكم" - }, - "useLakumPoints": { - "en": "Use Lakum points", - "ar": "استخدم نقاط لكم" - }, - "use": { - "en": "USE", - "ar": "استخدم" - }, - "proceedPay": { - "en": "PROCEED TO PAY", - "ar": "المتابعة للدفع" - }, - "vat": { - "en": "VAT (15%)", - "ar": "ضريبة القيمة المضافة (15%)" - }, - "inclusiveVat": { - "en": "(inclusive VAT)", - "ar": "(شاملة ضريبة القيمة المضافة)" - }, - "items": { - "en": "item(s)", - "ar": "عنصر(عناصر)" - }, - "checkOut": { - "en": "CHECK OUT", - "ar": "الدفع" - }, - "sar": { - "en": "SAR", - "ar": "ريال سعودي" - }, - "aed": { - "en": "AED", - "ar": "درهم إماراتي" - }, - "payOnline": { - "en": "PAY ONLINE", - "ar": "الدفع عبر الإنترنت" - }, - "cancelOrder": { - "en": "CANCEL ORDER", - "ar": "إلغاء الطلب" - }, - "confirmAddress": { - "en": "CONFIRM ADDRESS ", - "ar": "تأكيد العنوان " - }, - "confirmLocation": { - "en": "CONFIRM LOCATION ", - "ar": "أكد الموقع " - }, - "conditionsHMG": { - "en": "Terms & Conditions ", - "ar": "الشروط والأحكام " - }, - "conditions": { - "en": "Terms & Conditions of Lakum", - "ar": "الشروط والأحكام لكوم" - }, - "confirmDeleteMsg": { - "en": "Are you sure! want to delete ", - "ar": "هل أنت متأكد! تريد الحذف " - }, - "confirmDelete": { - "en": "DELETE", - "ar": "حذف" - }, - "confirmCancellation": { - "en": "Are you sure! want to cancel this order ", - "ar": "هل أنت متأكد! تريد إلغاء هذا الطلب " - }, - "orderNumber": { - "en": "Order#: ", - "ar": "رقم الطلب: " - }, - "orderDate": { - "en": "Date", - "ar": "التاريخ" - }, - "itemsNo": { - "en": "items(s)", - "ar": "عنصر(عناصر)" - }, - "noOrder": { - "en": "You Don't have any orders.", - "ar": "ليس لديك أي طلبات." - }, - "noResult": { - "en": "No Result.", - "ar": "لا توجد نتيجة." - }, - "nonRecommended": { - "en": "No Recommended Products.", - "ar": "لا توجد منتجات موصى بها." - }, - "termsService": { - "en": "Terms of Service", - "ar": "شروط الخدمة" - }, - "beforeusing": { - "en": "Before using the checkup, please read Terms of Service.", - "ar": "قبل استخدام الفحص، يرجى قراءة شروط الخدمة." - }, - "accept": { - "en": "I read and accept Terms of Service and Privacy Policy", - "ar": "أقرأ وأقبل شروط الخدمة وسياسة الخصوصية" - }, - "dataSafeInfo": { - "en": "Information that you provide is anonymous and not shared with anyone.", - "ar": "المعلومات التي تقدمها مجهولة الهوية وليست مشتركة مع أي شخص." - }, - "dataSafe": { - "en": " Your data is safe.", - "ar": " بياناتك آمنة." - }, - "informational": { - "en": "Checkup is for informational purposes and is not a qualified medical opinion", - "ar": "الفحص لأغراض معلوماتية وليس رأيًا طبيًا مؤهلاً" - }, - "notUseInEmerbency": { - "en": "Do not use in emergencies.", - "ar": "لا تستخدم في حالات الطوارئ." - }, - "notUseInEmerbencyDetails": { - "en": "In case of health emergency, ", - "ar": "في حالة الطوارئ الصحية، " - }, - "notUseInEmerbencyDetailsCall": { - "en": "call the nearest emergency number immediately", - "ar": "اتصل بأقرب رقم طوارئ على الفور" - }, - "checkDiagnosis": { - "en": "Checkup is not a diagnosis.", - "ar": "الفحص ليس تشخيصًا." - }, - "remeberthat": { - "en": "Remember that", - "ar": "تذكر أن" - }, - "loginToUseService": { - "en": "You need to login to use this service", - "ar": "تحتاج إلى تسجيل الدخول لاستخدام هذه الخدمة" - }, - "offersAndPromotions": { - "en": "OFFERS & SPECIAL PROMOTIONS", - "ar": "عروض وترويجيات خاصة" - }, - "offers": { - "en": "OFFERS", - "ar": "عروض" - }, - "myPrescriptions": { - "en": "MY PRESCRIPTIONS", - "ar": "وصفاتي" - }, - "searchAndScanMedication": { - "en": "SEARCH & SCAN FOR MEDICATION", - "ar": "البحث والمسح الضوئي للدواء" - }, - "shopByBrands": { - "en": "Shop by Brands", - "ar": "تسوق حسب العلامات التجارية" - }, - "recentlyViewed": { - "en": "Recently Viewed", - "ar": "تمت مشاهدته مؤخرًا" - }, - "bestSellers": { - "en": "Best Seller", - "ar": "الأكثر مبيعًا" - }, - "deleteAllItems": { - "en": "Delete All Items", - "ar": "حذف جميع العناصر" - }, - "total": { - "en": "Total", - "ar": "الإجمالي" - }, - "totalWithColonRight": { - "en": "Total:", - "ar": "الإجمالي:" - }, - "selectAddress": { - "en": "Select Address", - "ar": "اختر العنوان" - }, - "shippingAddress": { - "en": "SHIPPING ADDRESS", - "ar": "عنوان الشحن" - }, - "changeAddress": { - "en": "Change Address", - "ar": "تغيير العنوان" - }, - "selectPaymentOption": { - "en": "Select Payment Option", - "ar": "اختر طريقة الدفع" - }, - "selectTamaraPlan": { - "en": "Select Tamara Payment Plan", - "ar": "اختر خطة دفع تمارا" - }, - "changeMethod": { - "en": "Change Method", - "ar": "تغيير الطريقة" - }, - "reviewOrder": { - "en": "Review Order", - "ar": "مراجعة الطلب" - }, - "active": { - "en": "Active", - "ar": "نشط" - }, - "inactive": { - "en": "InActive", - "ar": "غير نشط" - }, - "balance": { - "en": "Balance", - "ar": "الرصيد" - }, - "gained": { - "en": "GAINED", - "ar": "المكتسب" - }, - "consumed": { - "en": "Consumed", - "ar": "المستهلك" - }, - "transferred": { - "en": "Transferred", - "ar": "المحول" - }, - "riyal": { - "en": "RIYAL", - "ar": "ريال" - }, - "membersince": { - "en": "MEMBER SINCE", - "ar": "عضو منذ" - }, - "identification": { - "en": "Identification Number", - "ar": "رقم الهوية" - }, - "lakumMobile": { - "en": "Mobile Number", - "ar": "رقم الجوال" - }, - "waitinggained": { - "en": "Waiting gained", - "ar": "انتظار المكتسب" - }, - "expired": { - "en": "Expired", - "ar": "منتهي" - }, - "willBeExpired": { - "en": "Will Be Expired", - "ar": "سينتهي" - }, - "activateLAKUMAccount": { - "en": "Activate LAKUM Account", - "ar": "تفعيل حساب لكم" - }, - "checkBeneficiary": { - "en": "CHECK BENEFICIARY", - "ar": "تحقق من المستفيد" - }, - "beneficiaryName": { - "en": "Beneficiary Name", - "ar": "اسم المستفيد" - }, - "accountActivation": { - "en": "Account Activation", - "ar": "تفعيل الحساب" - }, - "lakumTransfer": { - "en": "Lakum Transfer", - "ar": "تحويل لكم" - }, - "acceptLbl": { - "en": "Accept", - "ar": "قبول" - }, - "declineLbl": { - "en": "Decline", - "ar": "رفض" - }, - "selectGender": { - "en": "Select Gender", - "ar": "اختر الجنس" - }, - "iAmA": { - "en": "I am a ...", - "ar": "أنا ..." - }, - "selectAge": { - "en": "Select Your Age", - "ar": "اختر عمرك" - }, - "select": { - "en": "Select", - "ar": "اختر" - }, - "iAm": { - "en": "I am", - "ar": "أنا" - }, - "yearsOld": { - "en": "years old", - "ar": "سنوات" - }, - "dragPoint": { - "en": "Drag point to change your age", - "ar": "اسحب النقطة لتغيير عمرك" - }, - "refine": { - "en": "Refine", - "ar": "تنقيح" - }, - "subGroup": { - "en": "Subgroup", - "ar": "مجموعة فرعية" - }, - "max": { - "en": "Max", - "ar": "الحد الأقصى" - }, - "compeleteOrderMsg": { - "en": "Order has been placed successfully!!", - "ar": "تم تقديم الطلب بنجاح!!" - }, - "addToCompareMsg": { - "en": "You have added a product to the Compare list", - "ar": "لقد أضفت منتجًا إلى قائمة المقارنة" - }, - "itInListMsg": { - "en": "Item is already in the list", - "ar": "العنصر موجود بالفعل في القائمة" - }, - "compareListFull": { - "en": "Your compare list is full", - "ar": "قائمة المقارنة ممتلئة" - }, - "addQuantity": { - "en": "You should add quantity", - "ar": "يجب عليك إضافة الكمية" - }, - "addToCartMsg": { - "en": "You have added a product to the cart", - "ar": "لقد أضفت منتجًا إلى عربة التسوق" - }, - "addToWishlistMsg": { - "en": "You have added a product to the Wishlist", - "ar": "لقد أضفت منتجًا إلى قائمة الرغبات" - }, - "notifyMeMsg": { - "en": "You will be notified when product available", - "ar": "سوف يتم إبلاغك عند توفر المنتج" - }, - "removeFromWishlistMsg": { - "en": "You have removed a product from the Wishlist", - "ar": "لقد أزلت منتجًا من قائمة الرغبات" - }, - "min": { - "en": "Min", - "ar": "الحد الأدنى" - }, - "reset": { - "en": "Reset", - "ar": "إعادة تعيين" - }, - "apply": { - "en": "Apply", - "ar": "تطبيق" - }, - "viewCategorise": { - "en": "View All Categories", - "ar": "عرض جميع الفئات" - }, - "viewSubCategorise": { - "en": "View All Sub Categories", - "ar": "عرض جميع الفئات الفرعية" - }, - "categorise": { - "en": "Categories", - "ar": "الفئات" - }, - "wishList": { - "en": "WishList", - "ar": "قائمة الرغبات" - }, - "cart": { - "en": "Cart", - "ar": "عربة التسوق" - }, - "alhabibapp": { - "en": "Al Habib app", - "ar": "تطبيق الحبيب" - }, - "searchProductHere": { - "en": "Search Product here", - "ar": "ابحث عن المنتج هنا" - }, - "hhcNotAuthMsg": { - "en": "This service provides a set of home health care services, continuous and comprehensive follow-up in their places of residence for those who cannot access health facilities, such as (laboratory analyzes - radiology - vaccinations - physical therapy), etc.", - "ar": "تقدم هذه الخدمة مجموعة من خدمات الرعاية الصحية المنزلية، والمتابعة المستمرة والشاملة في أماكن إقامتهم لأولئك الذين لا يمكنهم الوصول إلى المرافق الصحية، مثل (تحليلات المختبر - الأشعة - التطعيمات - العلاج الطبيعي)، إلخ." - }, - "email": { - "en": "Email *", - "ar": "البريد الإلكتروني *" - }, - "book": { - "en": "Book", - "ar": "احجز" - }, - "appointmentLabel": { - "en": "Appointment", - "ar": "موعد" - }, - "bloodType": { - "en": "Blood Type", - "ar": "فصيلة الدم" - }, - "maritalStatus": { - "en": "Marital status", - "ar": "الحالة الاجتماعية" - }, - "general": { - "en": "General", - "ar": "عام" - }, - "profile": { - "en": "My Profile", - "ar": "ملفي" - }, - "notifications": { - "en": "Notifications", - "ar": "إشعارات" - }, - "notificationDetails": { - "en": "Notification Details", - "ar": "تفاصيل الإشعار" - }, - "notificationDetailsa": { - "en": "Notification Details", - "ar": "تفاصيل الإشعار" - }, - "infoMyDoctor": { - "en": "This service allows you to see all the doctors you have visited in Al Habib Medical Group, and through this service:", - "ar": "تتيح لك هذه الخدمة رؤية جميع الأطباء الذين زرتهم في مجموعة الحبيب الطبية، ومن خلال هذه الخدمة:" - }, - "infoPrescriptions": { - "en": "This service allows you to view all the medical prescriptions issued by Al Habib Medical Group, and through this service, you can:", - "ar": "تتيح لك هذه الخدمة عرض جميع الوصفات الطبية التي أصدرتها مجموعة الحبيب الطبية، ومن خلال هذه الخدمة، يمكنك:" - }, - "infoInsuranceCards": { - "en": "This service allows you to view all the insurance cards that recorded during your visits to Al Habib Medical Group in addition to:", - "ar": "تتيح لك هذه الخدمة عرض جميع بطاقات التأمين التي تم تسجيلها خلال زياراتك لمجموعة الحبيب الطبية بالإضافة إلى:" - }, - "infoAllergies": { - "en": "This service allows you to view all types of allergies recorded during your visits to Al Habib Medical Group.", - "ar": "تتيح لك هذه الخدمة عرض جميع أنواع الحساسية المسجلة خلال زياراتك لمجموعة الحبيب الطبية." - }, - "infoSickLeaves": { - "en": "This service allows you to view all sick leaves that were taken in Al Habib Medical Group in addition to:", - "ar": "تتيح لك هذه الخدمة عرض جميع الاجازات المرضيه التي تم أخذها في مجموعة الحبيب الطبية بالإضافة إلى:" - }, - "infoApprovals": { - "en": "This service allows you to view all approvals requests that have been sent to the insurance companies in addition to:", - "ar": "تتيح لك هذه الخدمة عرض جميع طلبات الموافقة التي تم إرسالها إلى شركات التأمين بالإضافة إلى:" - }, - "infoMonthReport": { - "en": "Upon activation of this service, the system will send a monthly report automatically to the registered email which lists the vital signs and the results for the last visits made in AlHabib Medical Group.", - "ar": "عند تفعيل هذه الخدمة، سيقوم النظام بإرسال تقرير شهري تلقائيًا إلى البريد الإلكتروني المسجل يتضمن العلامات الحيوية والنتائج لآخر الزيارات التي تمت في مجموعة الحبيب الطبية." - }, - "languageSetting": { - "en": "SMS, WhatsApp and Confirmation Calls Language", - "ar": "الرسائل القصيرة، واتساب، لغة مكالمات التأكيد" - }, - "alert": { - "en": "Alerts", - "ar": "تنبيهات" - }, - "emailAlert": { - "en": "Alert by Email", - "ar": "تنبيه عبر البريد الإلكتروني" - }, - "smsAlert": { - "en": "Alert by SMS", - "ar": "تنبيه عبر الرسائل القصيرة" - }, - "contactInfo": { - "en": "Contact Information", - "ar": "معلومات الاتصال" - }, - "emrgName": { - "en": "Emergency Contact Name", - "ar": "اسم جهة الاتصال في حالات الطوارئ" - }, - "emrgNo": { - "en": "Emergency Contact Number", - "ar": "رقم جهة الاتصال في حالات الطوارئ" - }, - "modes": { - "en": "Modes", - "ar": "الأوضاع" - }, - "vibration": { - "en": "Vibration Touch Feedback", - "ar": "اهتزاز عند اللمس" - }, - "blindModes": { - "en": "Modes for Partially Blind", - "ar": "أوضاع للمكفوفين جزئيًا" - }, - "invertTheme": { - "en": "Invert", - "ar": "عكس" - }, - "offTheme": { - "en": "Off", - "ar": "إيقاف" - }, - "dimTheme": { - "en": "Dim", - "ar": "خافت" - }, - "bwTheme": { - "en": "Black and White", - "ar": "أسود وأبيض" - }, - "permissions": { - "en": "Permission", - "ar": "إذن" - }, - "cameraPermission": { - "en": "Camera", - "ar": "الكاميرا" - }, - "locationPermission": { - "en": "Location", - "ar": "الموقع" - }, - "needPrescription": { - "en": "This product requires a prescription", - "ar": "يتطلب هذا المنتج وصفة طبية" - }, - "outOfStockMsg": { - "en": "You have added product which is out of stock now, Please remove that!", - "ar": "لقد أضفت منتجًا غير متوفر حاليًا، يرجى إزالته!" - }, - "noArabicLetters": { - "en": "It Is Not Allow to Use Arabic Letters", - "ar": "لا يُسمح باستخدام الحروف العربية" - }, - "noOffersAvailable": { - "en": "No Offers Available!", - "ar": "لا توجد عروض متاحة!" - }, - "accessibility": { - "en": "Accessibility Mode", - "ar": "وضع الوصول" - }, - "orderStatus": { - "en": "Order Status", - "ar": "حالة الطلب" - }, - "findUs": { - "en": "Find Us", - "ar": "اعثر علينا" - }, - "liveChat": { - "en": "Live Chat", - "ar": "دردشة مباشرة" - }, - "service": { - "en": "Service", - "ar": "خدمة" - }, - "hmgServiceLabel": { - "en": "HMG Service", - "ar": "خدمة مجموعة الحبيب الطبية" - }, - "healthWeatherIndicators": { - "en": "Health Weather Indicators", - "ar": "مؤشرات الطقس الصحية" - }, - "healthTipsBasedOnCurrentWeather": { - "en": "Health Tips Based On Current Weather", - "ar": "نصائح صحية بناءً على الطقس الحالي" - }, - "moreDetails": { - "en": "More details", - "ar": "المزيد من التفاصيل" - }, - "resendOrder": { - "en": "Refill and Delivery", - "ar": "إعادة التعبئة والتوصيل" - }, - "ports": { - "en": "Ports", - "ar": "المنافذ" - }, - "way": { - "en": "Way", - "ar": "الطريقة" - }, - "dailyDoses": { - "en": "Daily Doses", - "ar": "الجرعات اليومية" - }, - "period": { - "en": "Period", - "ar": "الفترة" - }, - "duration": { - "en": "المدة", - "ar": "المدة" - }, - "cm": { - "en": "CM", - "ar": "سم" - }, - "ft": { - "en": "ft", - "ar": "قدم" - }, - "kg": { - "en": "kg", - "ar": "كجم" - }, - "lb": { - "en": "lb", - "ar": "رطل" - }, - "birthDate": { - "en": "Birth Date", - "ar": "تاريخ الميلاد" - }, - "dateOfBirth": { - "en": "Date of Birth", - "ar": "تاريخ الميلاد" - }, - "mass": { - "en": "Mass", - "ar": "الكتلة" - }, - "tempC": { - "en": "°C", - "ar": "°م" - }, - "bpm": { - "en": "bpm", - "ar": "نبضة في الدقيقة" - }, - "respirationSigns": { - "en": "Respiration", - "ar": "التنفس" - }, - "sysDias": { - "en": "SBP/DBP", - "ar": "SBP/DBP" - }, - "body": { - "en": "Body Mass", - "ar": "مؤشر كتلة الجسم" - }, - "bodyString": { - "en": "Body", - "ar": "الجسم" - }, - "face": { - "en": "Face", - "ar": "وجه" - }, - "retouch": { - "en": "Re-touch", - "ar": "روتوش" - }, - "bikini": { - "en": "Bikini", - "ar": "بيكيني" - }, - "totalMinutes": { - "en": "Total Minutes", - "ar": "إجمالي الدقائق" - }, - "feedback": { - "en": "Feedback", - "ar": "ملاحظات" - }, - "likeToHear": { - "en": "We would love to hear the feedback, concerns on healthcare services and eServices experience. Please use the below form", - "ar": "نود سماع ملاحظاتك، ومخاوفك بشأن خدمات الرعاية الصحية وتجربة الخدمات الإلكترونية. يرجى استخدام النموذج أدناه" - }, - "emptySubject": { - "en": "Please enter the subject", - "ar": "يرجى إدخال الموضوع" - }, - "emptyMessage": { - "en": "Please enter message", - "ar": "يرجى إدخال الرسالة" - }, - "selectAttachment": { - "en": "Select Attachment", - "ar": "اختر المرفق" - }, - "complainAppo": { - "en": "Complaint for appointment", - "ar": "شكوى بخصوص الموعد" - }, - "complainAppoAlt": { - "en": "Complaint without appointment", - "ar": "شكوى بدون موعد" - }, - "messageType": { - "en": "Message Type", - "ar": "نوع الرسالة" - }, - "feedbackType": { - "en": "Feedback Type", - "ar": "نوع الملاحظات" - }, - "compliment": { - "en": "Appreciation", - "ar": "تقدير" - }, - "suggestion": { - "en": "Suggestion", - "ar": "اقتراح" - }, - "yourFeedback": { - "en": "Your feedback was sent", - "ar": "تم إرسال ملاحظاتك" - }, - "selectPart": { - "en": "Please select the part that complain about", - "ar": "يرجى اختيار الجزء الذي تشتكي منه" - }, - "number": { - "en": "Number", - "ar": "رقم" - }, - "notClassified": { - "en": "Not classified", - "ar": "غير مصنف" - }, - "selectClinic": { - "en": "Select Clinic", - "ar": "اختر العيادة" - }, - "selectProject": { - "en": "Select Hospital", - "ar": "اختر المستشفى" - }, - "searchItemError": { - "en": "Item name should be more than 3 character", - "ar": "يجب أن يكون اسم العنصر أكثر من 3 أحرف" - }, - "youCanFind": { - "en": "You Can Find ", - "ar": "يمكنك العثور على " - }, - "itemInSearch": { - "en": " Item in Search", - "ar": " عنصر في البحث" - }, - "bloodDonation": { - "en": "Blood Donation", - "ar": "التبرع بالدم" - }, - "bloodDonationInfo": { - "en": "Through this service, you can register your name as a blood donor where the blood bank in the Habib Medical Group will communicate you in case of need for blood type.", - "ar": "من خلال هذه الخدمة، يمكنك تسجيل اسمك كمتبرع بالدم حيث سيتواصل معك بنك الدم في مجموعة الحبيب الطبية في حالة الحاجة إلى فصيلة الدم." - }, - "bloodInstruction": { - "en": "Enter the required information, in order to register for Blood Donation Service", - "ar": "أدخل المعلومات المطلوبة، من أجل التسجيل في خدمة التبرع بالدم" - }, - "viewTerms": { - "en": "To view the terms and conditions", - "ar": "لعرض الشروط والأحكام" - }, - "wantConnectHmgNetwork": { - "en": "Dear customer there is no internet access, do you want to connect with HMG network to use our app, make sure you are in range of HMG network", - "ar": "عزيزي العميل، لا يوجد وصول إلى الإنترنت، هل ترغب في الاتصال بشبكة مجموعة الحبيب الطبية لاستخدام تطبيقنا، تأكد من أنك في نطاق شبكة مجموعة الحبيب الطبية" - }, - "failedToAccessHmgServices": { - "en": "Connected with HMG Network,\n\nBut failed to access HMG services", - "ar": "متصل بشبكة مجموعة الحبيب الطبية،\n\nلكن فشل في الوصول إلى خدمات مجموعة الحبيب الطبية" - }, - "offerAndPackages": { - "en": "Offers and Packages", - "ar": "عروض وباقات" - }, - "offerAndPackagesDetails": { - "en": "This service allows you to view all HMG Offers:", - "ar": "تتيح لك هذه الخدمة عرض جميع عروض مجموعة الحبيب الطبية:" - }, - "invoiceNo": { - "en": "Invoice No", - "ar": "رقم الفاتورة" - }, - "invoiceDate": { - "en": "Invoice Date", - "ar": "تاريخ الفاتورة" - }, - "specialResult": { - "en": "Special Result", - "ar": "نتيجة خاصة" - }, - "generalResult": { - "en": "General Result", - "ar": "نتيجة عامة" - }, - "showMoreBtn": { - "en": "Flow Chart", - "ar": "مخطط التدفق" - }, - "value": { - "en": "Value", - "ar": "القيمة" - }, - "report": { - "en": "Radiology Report", - "ar": "تقرير الأشعة" - }, - "openRad": { - "en": "Open Image", - "ar": "فتح الصورة" - }, - "sendCopy": { - "en": "Email the Report", - "ar": "إرسال التقرير عبر البريد الإلكتروني" - }, - "appoSurvey": { - "en": "Survey", - "ar": "استطلاع" - }, - "appoSurveySubtitle": { - "en": "Survey", - "ar": "استطلاع" - }, - "labResults": { - "en": "Lab Results", - "ar": "نتائج المختبر" - }, - "doctorRating": { - "en": "Doctor Rating", - "ar": "تقييم الطبيب" - }, - "good": { - "en": "Good", - "ar": "جيد" - }, - "vGood": { - "en": "Very Good", - "ar": "جيد جدًا" - }, - "excellent": { - "en": "Excellent", - "ar": "ممتاز" - }, - "average": { - "en": "Average", - "ar": "متوسط" - }, - "infoSigns": { - "en": "This service allows you to view all vital signs were performed in the Habib Medical Group, e.x (height, weight, body mass index, heart rate, etc.) as well shows some statistics charts.", - "ar": "تتيح لك هذه الخدمة عرض جميع العلامات الحيوية التي تم قياسها في مجموعة الحبيب الطبية، مثل (الطول، الوزن، مؤشر كتلة الجسم، معدل ضربات القلب، إلخ.) بالإضافة إلى عرض بعض الرسوم البيانية الإحصائية." - }, - "infoAdvancePayment": { - "en": "This service designed so that you can deposit an amount in advance either in your account or in someone else's account with Al Habib Medical Group.", - "ar": "تم تصميم هذه الخدمة بحيث يمكنك إيداع مبلغ مقدم إما في حسابك أو في حساب شخص آخر، في مجموعة الحبيب الطبية." - }, - "infoMyBalance": { - "en": "This service allows you to check your balance in all branchs", - "ar": "تتيح لك هذه الخدمة التحقق من رصيدك في جميع الفروع" - }, - "erContant": { - "en": "This service displays nearest branch among all the branches of Al Habib Medical Group based on your current location.", - "ar": "تظهر هذه الخدمة أقرب فرع من بين جميع فروع مجموعة الحبيب الطبية بناءً على موقعك الحالي." - }, - "infoAmbulance": { - "en": "Through this service, you can request evacuation by ambulance, whether from home or to home, in addition to a set of other services", - "ar": "من خلال هذه الخدمة، يمكنك طلب الإخلاء بواسطة سيارة إسعاف، سواء من المنزل أو إلى المنزل، بالإضافة إلى مجموعة من الخدمات الأخرى" - }, - "infoMyAppointments": { - "en": "This service allows you to see all the appointment you have visited in Al Habib Medical Group, and through this service:", - "ar": "تتيح لك هذه الخدمة رؤية جميع المواعيد التي زرتها في مجموعة الحبيب الطبية، ومن خلال هذه الخدمة:" - }, - "infoTodo": { - "en": "This service is designed to enable you to have a quick link to the list of tasks that need to be done", - "ar": "تم تصميم هذه الخدمة لتمكينك من الحصول على رابط سريع لقائمة المهام التي تحتاج القيام بها" - }, - "familyInfo": { - "en": "Through this service, you will be able to link your family medical files to your medical file so that you can manage their records by login to your medical file.", - "ar": "من خلال هذه الخدمة، ستتمكن من ربط ملفات عائلتك الطبية بملفك الطبي حتى تتمكن من إدارة سجلاتهم عن طريق تسجيل الدخول إلى ملفك الطبي." - }, - "rrtdDetails": { - "en": "The Rapid response team provides a comprehensive medical service for all sorts of urgent and stable cases of all ages, including adult and paediatric patients, the service is covered by a fully equipped and highly trained medical team capable of providing the best medical care at the patient’s home.", - "ar": "تقدم فريق الاستجابة السريعة خدمة طبية شاملة لجميع أنواع الحالات العاجلة والمستقرة من جميع الأعمار، بما في ذلك البالغين والمرضى الأطفال، وتغطي الخدمة فريق طبي مدرب تدريبًا عاليًا ومجهز تجهيزًا كاملًا قادرًا على تقديم أفضل رعاية طبية في منزل المريض." - }, - "onlineCheckInAgreement": { - "en": "The online check-in is for non-life threatening situation. Call the red crescent (997) or go to the nearest emergency department if there are: \n\nsigns of stroke or heart attack \nhistory of seizure or syncope \nthere is limb or life threatening injury \npicture of severe injuries", - "ar": "تسجيل الوصول عبر الإنترنت مخصص للحالات التي لا تهدد الحياة. اتصل بالهلال الأحمر (997) أو اذهب إلى أقرب قسم طوارئ إذا كان هناك: \n\nعلامات السكتة الدماغية أو النوبة القلبية \nhالة من النوبات أو الإغماء \nهناك إصابة تهدد الطرف أو الحياة \nصورة لإصابات خطيرة" - }, - "infoEreferral": { - "en": "This service allows you to submit a Referral request from any health care providers either inside or outside the kingdom of Saudi Arabia to any of HMG Hospitals, by filling some of the patient's data and attaching the medical reports, moreover you can track the request status (Under process, Accepted or Rejected)", - "ar": "تتيح لك هذه الخدمة تقديم طلب إحالة من أي مقدم رعاية صحية سواء داخل أو خارج المملكة العربية السعودية إلى أي من مستشفيات HMG، عن طريق ملء بعض بيانات المريض وإرفاق التقارير الطبية، علاوة على ذلك يمكنك تتبع حالة الطلب (قيد المعالجة، مقبول أو مرفوض)" - }, - "erConsultation": { - "en": "This service allows you to make an online virtual consultation via video call directly with the doctor from anywhere at any time.", - "ar": "تتيح لك هذه الخدمة إجراء استشارة افتراضية عبر الإنترنت عبر مكالمة فيديو مباشرة مع الطبيب من أي مكان وفي أي وقت." - }, - "myInvoice": { - "en": "List", - "ar": "القائمة" - }, - "invoiceList": { - "en": "My Invoice", - "ar": "فواتيري" - }, - "thisItemIsNotAvailable": { - "en": "This item is not available", - "ar": "هذا العنصر غير متوفر" - }, - "beforeAfterImages": { - "en": "Before & After Images", - "ar": "صور قبل وبعد" - }, - "clinicAcceptLivecare": { - "en": "No need to wait or visit You can now get medical consultation via Video call (LiveCare service) in The name of the clinic clinic and the doctor will contact you immediately", - "ar": "لا حاجة للانتظار أو الزيارة يمكنك الآن الحصول على استشارة طبية عبر مكالمة فيديو (لايف كير) في اسم العيادة وسيتصل بك الطبيب على الفور" - }, - "livecareModalTop": { - "en": "This Clinic is Accepting LiveCare services", - "ar": "تقبل هذه العيادة خدمات ال لايف كير" - }, - "livecarePoint2": { - "en": "A Specialized doctor will contact you", - "ar": "سوف يتصل بك طبيب متخصص" - }, - "livecarePoint3": { - "en": "A Doctor will be able to see your full medical file history", - "ar": "سيكون لدى الطبيب القدرة على رؤية تاريخ ملفك الطبي الكامل" - }, - "livecarePoint4": { - "en": "Free Medicine Delivery Available", - "ar": "تتوفر خدمة توصيل الأدوية المجانية" - }, - "livecarePoint5": { - "en": "No need to visit the service is in your place", - "ar": "لا حاجة للزيارة، الخدمة في مكانك" - }, - "bookImmediateLivecare": { - "en": "I accept to get the service immediately", - "ar": "أوافق على الحصول على الخدمة على الفور" - }, - "bookVideoLivecare2": { - "en": "I don't need to visit the clinic", - "ar": "لا أحتاج لزيارة العيادة" - }, - "noThankyou": { - "en": "No Thanks", - "ar": "لا شكرًا" - }, - "visitClinic": { - "en": "Schedule appointment with the doctor", - "ar": "جدولة موعد مع الطبيب" - }, - "generateCovidCertificate": { - "en": "Generate Covid-19 Certificate", - "ar": "إصدار شهادة كوفيد-19" - }, - "isReportOutsideKsa": { - "en": "Is the certificate needed for outside KSA?", - "ar": "هل الشهادة مطلوبة خارج المملكة العربية السعودية؟" - }, - "passportNumber": { - "en": "Passport Number", - "ar": "رقم جواز السفر" - }, - "enterPassportNumber": { - "en": "Please confirm or update your passport number:", - "ar": "يرجى تأكيد أو تحديث رقم جواز السفر الخاص بك:" - }, - "validPassportNumber": { - "en": "Please enter valid passport number", - "ar": "يرجى إدخال رقم جواز سفر صالح" - }, - "continuePlan": { - "en": "Continue with the treatment plan?", - "ar": "متابعة خطة العلاج؟" - }, - "aboutApp": { - "en": "About the app", - "ar": "حول التطبيق" - }, - "dontHaveAccount": { - "en": "Don't have an account?", - "ar": "ليس لديك حساب؟" - }, - "loginOrRegister": { - "en": "Login or Register", - "ar": "تسجيل الدخول أو التسجيل" - }, - "myFiles": { - "en": "My Files", - "ar": "ملفاتي" - }, - "resultsPending": { - "en": "Results pending", - "ar": "النتائج معلقة" - }, - "resultsAvailable": { - "en": "Results available", - "ar": "النتائج متاحة" - }, - "viewReport": { - "en": "View Report", - "ar": "عرض التقرير" - }, - "checkAvailability": { - "en": "Check Availability", - "ar": "التحقق من التوفر" - }, - "readInstructions": { - "en": "Read Instructions", - "ar": "قراءة التعليمات" - }, - "searchLabReport": { - "en": "Search Lab Report", - "ar": "ابحث عن تقرير المختبر" - }, - "prescriptionDeliveryError": { - "en": "This Clinic Does Not Support Refill And Delivery.", - "ar": "هذه العيادة لا تدعم إعادة التعبئة والتسليم." - }, - "receiveOtpToast": { - "en": "Where would you like to receive OTP?", - "ar": "أين تود تلقي رمز التحقق OTP؟" - }, - "enterPhoneNumber": { - "en": "Enter Phone Number", - "ar": "أدخل رقم الهاتف" - }, - "enterEmailDesc": { - "en": "Enter your email to complete medical profile creation process", - "ar": "أدخل عنوان بريدك الإلكتروني لإكمال عملية إنشاء ملف طبي" - }, - "enterPhoneDesc": { - "en": "Enter your phone number to receive OTP ", - "ar": "أدخل رقم هاتفك لتلقي رمز التحقق " - }, - "pleaseChooseOption": { - "en": "Please select from the below options to receive OTP", - "ar": "الرجاء اختيار من الخيارات أدناه لتلقي رمز التحقق OTP" - }, - "prepareToElevate": { - "en": "Prepared to elevate your health and well-being?", - "ar": "هل أنت مستعد لتحسين صحتك ورفاهيتك؟" - }, - "iAcceptTermsConditions": { - "en": "I Accept the Terms and Conditions", - "ar": "أوافق على الشروط والأحكام" - }, - "alreadyHaveAccount": { - "en": "Already have an account?", - "ar": "هل لديك حساب بالفعل؟" - }, - "loginNow": { - "en": "Login Now", - "ar": "تسجيل الدخول الآن" - }, - "notice": { - "en": "Notice", - "ar": "إشعار" - }, - "oR": { - "en": "OR", - "ar": "أو" - }, - "sendOTPWHATSAPP": { - "en": "Send me OTP on Whatsapp", - "ar": "أرسل لي OTP عبر واتساب" - }, - "sendOTPSMS": { - "en": "Send me OTP on SMS", - "ar": "أرسل لي OTP عبر الرسائل القصيرة" - }, - "fullName": { - "en": "Full Name", - "ar": "الاسم الكامل" - }, - "married": { - "en": "Married", - "ar": "متزوج" - }, - "uae": { - "en": "United Arab Emirates", - "ar": "الإمارات العربية المتحدة" - }, - "malE": { - "en": "Male", - "ar": "ذكر" - }, - "loginBy": { - "en": "Login By", - "ar": "تسجيل الدخول بواسطة" - }, - "loginByOTP": { - "en": "Login By OTP", - "ar": "تسجيل الدخول بواسطة OTP" - }, - "guest": { - "en": "Guest", - "ar": "زائر" - }, - "switchAccount": { - "en": "Switch Account", - "ar": "تبديل الحساب" - }, - "lastLoginBy": { - "en": "Last login by", - "ar": "آخر تسجيل دخول بواسطة" - }, - "allSet": { - "en": "All Set! Now you can login with Face ID or Biometric", - "ar": "جاهز! الآن يمكنك تسجيل الدخول باستخدام Face ID أو البصمة" - }, - "enableQuickLogin": { - "en": "Enable Quick Login", - "ar": "تمكين تسجيل الدخول السريع" - }, - "enableMsg": { - "en": "Enabling the quick login will verify through your existing device Face ID / Biometric", - "ar": "تمكين تسجيل الدخول السريع سيسمح بالتحقق من خلال Face ID / Biometric الخاص بجهازك الحالي" - }, - "notNow": { - "en": "Not Now", - "ar": "ليس الآن" - }, - "pendingActivation": { - "en": "Pending Activation", - "ar": "في انتظار التنشيط" - }, - "awaitingApproval": { - "en": "Awaiting Approval", - "ar": "انتظر القبول" - }, - "news": { - "en": "News", - "ar": "أخبار" - }, - "ready": { - "en": "Ready", - "ar": "جاهز" - }, - "enterValidNationalId": { - "en": "Please enter a valid national ID or file number", - "ar": "الرجاء إدخال رقم الهوية الوطنية أو رقم الملف الصحيح" - }, - "enterValidPhoneNumber": { - "en": "Please enter a valid phone number", - "ar": "الرجاء إدخال رقم هاتف صالح" - }, - "cannotEnterSaudiOrUAENumber": { - "en": "You cannot enter Saudi Arabia (00966) or UAE (00971) phone numbers when 'Others' country is selected", - "ar": "لا يمكنك إدخال أرقام هواتف السعودية (00966) أو الإمارات (00971) عند اختيار دولة 'أخرى'" - }, - "medicalCentersWithCount": { - "en": "{count} Medical Centers", - "ar": "{count} مراكز طبية" - }, - "medicalCenters": { - "en": " Medical Centers", - "ar": "مراكز طبية" - }, - "hospitalsWithCount": { - "en": "{count} Hospitals", - "ar": "{count} مستشفيات" - }, - "selectRegion": { - "en": "Select Region", - "ar": "اختر المنطقة" - }, - "selectFacility": { - "en": "Select Facilities", - "ar": "اختر المرافق" - }, - "selectFacilitiesSubTitle": { - "en": "Please select the facility for the appointment", - "ar": "يرجى اختيار المرفق للموعد" - }, - "selectHospitalSubTitle": { - "en": "Please select the hospital for the appointment", - "ar": "يرجى اختيار المستشفى للموعد" - }, - "iAcceptThe": { - "en": "I Accept the", - "ar": "أوافق على" - }, - "personalDetailsVerification": { - "en": "Personal Details Verification", - "ar": "التحقق من التفاصيل الشخصية" - }, - "otpVerification": { - "en": "OTP Verification", - "ar": "التحقق من OTP" - }, - "weHaveSendOTP": { - "en": "We have sent you the OTP code on", - "ar": "لقد أرسلنا OTP إلى" - }, - "via": { - "en": "via", - "ar": "عبر" - }, - "forRegistrationVerification": { - "en": "for registration verification", - "ar": "للتحقق من التسجيل" - }, - "didntReceiveIt": { - "en": "Didn't receive it?", - "ar": "لم تستلمه؟" - }, - "resendOTP": { - "en": "Resend", - "ar": "إعادة إرسال" - }, - "resendIn": { - "en": "resend in", - "ar": "إعادة الإرسال في" - }, - "pleaseEnterAnationalID": { - "en": "Please enter a national ID", - "ar": "يرجى إدخال رقم الهوية الوطنية" - }, - "pleaseEnterAFileNumber": { - "en": "Please enter a file number", - "ar": "يرجى إدخال رقم الملف" - }, - "pleaseEnterAValidEmail": { - "en": "Please enter a valid email", - "ar": "يرجى إدخال بريد إلكتروني صالح" - }, - "pleaseEnterFullName": { - "en": "Please enter full name", - "ar": "يرجى إدخال الاسم الكامل" - }, - "pleaseAcceptTermsConditions": { - "en": "Please accept the terms and conditions", - "ar": "يرجى قبول الشروط والأحكام" - }, - "pleaseEnterAValidIqamaID": { - "en": "Please enter a valid Iqama ID", - "ar": "يرجى إدخال رقم إقامة صالح" - }, - "pleaseEnterAValidNationalID": { - "en": "Please enter a valid national ID", - "ar": "يرجى إدخال رقم هوية وطنية صالح" - }, - "pleaseEnterAValidDateOfBirth": { - "en": "Please enter a valid date of birth", - "ar": "يرجى إدخال تاريخ ميلاد صالح" - }, - "pleaseEnterAValidName": { - "en": "Please enter a valid name", - "ar": "يرجى إدخال اسم صالح" - }, - "pleaseSelectAGender": { - "en": "Please select a gender", - "ar": "يرجى اختيار الجنس" - }, - "pleaseSelectAMaritalStatus": { - "en": "Please select a marital status", - "ar": "يرجى اختيار الحالة الاجتماعية" - }, - "pleaseSelectACountry": { - "en": "Please select a country", - "ar": "يرجى اختيار الدولة" - }, - "pleaseEnterEmail": { - "en": "Please enter email", - "ar": "يرجى إدخال البريد الإلكتروني" - }, - "pleaseEnterAValidEmailFormat": { - "en": "Please enter a valid email format", - "ar": "يرجى إدخال تنسيق بريد إلكتروني صالح" - }, - "selectCountry": { - "en": "Select Country", - "ar": "اختر الدولة" - }, - "forLoginVerification": { - "en": "for login verification", - "ar": "للتحقق من تسجيل الدخول" - }, - "searchHospital": { - "en": "Search Hospital", - "ar": "بحث في المستشفى" - }, - "skip": { - "en": "Skip", - "ar": "تخطي" - }, - "getStarted": { - "en": "Get Started", - "ar": "ابدأ الآن" - }, - "onboardingHeading1": { - "en": "Booking appointment has never been easy", - "ar": "حجز المواعيد لم يكن أسهل من الآن." - }, - "onboardingBody1": { - "en": "In few clicks find yourself having consultation with the doctor of your choice.", - "ar": "ببضع نقرات فقط يمكنك استشارة الطبيب الذي تختاره." - }, - "onboardingHeading2": { - "en": "Access the medical history on finger tips", - "ar": "الوصول إلى السجل الطبي بين يديك" - }, - "onboardingBody2": { - "en": "Keep track on your medical history including labs, prescription, insurance, etc", - "ar": "تتبع تاريخك الطبي بما في ذلك الفحوصات المخبرية، الوصفات الطبية، التأمين، وغيرها." - }, - "hmgHospitals": { - "en": "HMG Hospitals", - "ar": "مستشفيات مجموعة الحبيب الطبية" - }, - "hmcMedicalClinic": { - "en": "HMC Medical Centers", - "ar": "مراكز مجموعة الحبيب الطبية" - }, - "applyFilter": { - "en": "Apply Filter", - "ar": "تطبيق الفلتر" - }, - "facilityAndLocation": { - "en": "Facility and Location", - "ar": "المرفق والموقع" - }, - "regionAndLocation": { - "en": "Region And Locations", - "ar": "المنطقة والمواقع" - }, - "clearAllFilters": { - "en": "Clear all filters", - "ar": "مسح جميع الفلاتر" - }, - "filters": { - "en": "Filters", - "ar": "فلاتر" - }, - "searchClinic": { - "en": "Search Clinic", - "ar": "بحث عن عيادة" - }, - "normal": { - "en": "Normal", - "ar": "عادي" - }, - "attention": { - "en": "Attention", - "ar": "انتباه" - }, - "monitor": { - "en": "Monitor", - "ar": "مراقبة" - }, - "noSpecialResult": { - "en": "No Special Results", - "ar": "لا توجد نتائج خاصة" - }, - "setTheDateRange": { - "en": "Set The Date Range", - "ar": "تعيين النطاق الزمني" - }, - "historyFlowchart": { - "en": "History FlowChart", - "ar": "مخطط تدفق التاريخ" - }, - "to": { - "en": "to", - "ar": "إلى" - }, - "startDate": { - "en": "Start Date", - "ar": "تاريخ البدء" - }, - "endDate": { - "en": "End Date", - "ar": "تاريخ الانتهاء" - }, - "walkin": { - "en": "Walk In", - "ar": "زيارة بدون موعد" - }, - "laserClinic": { - "en": "Laser Clinic", - "ar": "عيادة الليزر" - }, - "continueString": { - "en": "Continue", - "ar": "يكمل" - }, - "covid_info": { - "en": "Dr. Sulaiman Al Habib hospitals are conducting a test for the emerging corona virus and issuing travel certificates 24/7 in a short time and with high accuracy...", - "ar": "تجري مستشفيات د. سليمان الحبيب فحص فيروس كورونا المستجد وتصدر شهادات السفر على مدار الساعة..." - }, - "appointmentDetails": { - "en": "Appointment Details", - "ar": "تفاصيل الموعد" - }, - "checkingDoctorAvailability": { - "en": "Checking doctor availability...", - "ar": "جاري التحقق من توفر الطبيب..." - }, - "cancellingAppointmentPleaseWait": { - "en": "Cancelling Appointment, Please Wait...", - "ar": "جاري إلغاء الموعد، يرجى الانتظار..." - }, - "appointmentCancelledSuccessfully": { - "en": "Appointment Cancelled Successfully", - "ar": "تم إلغاء الموعد بنجاح" - }, - "notConfirmed": { - "en": "Not Confirmed", - "ar": "غير مؤكد" - }, - "appointmentStatus": { - "en": "Appointment Status", - "ar": "حالة الموعد" - }, - "doctorWillCallYou": { - "en": "The doctor will call you once the appointment time approaches.", - "ar": "سيتصل بك الطبيب عندما يقترب موعدك." - }, - "getDirections": { - "en": "Get Directions", - "ar": "الحصول على الاتجاهات" - }, - "notifyMeBeforeAppointment": { - "en": "Notify me before the appointment", - "ar": "أبلغني قبل الموعد" - }, - "fetchingLabResults": { - "en": "Fetching Lab Results...", - "ar": "جاري جلب نتائج المختبر..." - }, - "fetchingRadiologyResults": { - "en": "Fetching Radiology Results...", - "ar": "جاري جلب نتائج الأشعة..." - }, - "fetchingAppointmentPrescriptions": { - "en": "Fetching Appointment Prescriptions...", - "ar": "جاري جلب وصفات الموعد..." - }, - "noPrescriptionsForAppointment": { - "en": "You don't have any prescriptions for this appointment.", - "ar": "ليس لديك أي وصفات طبية لهذا الموعد." - }, - "amountBeforeTax": { - "en": "Amount before tax", - "ar": "المبلغ قبل الضريبة" - }, - "rebookAppointment": { - "en": "Re-book Appointment", - "ar": "إعادة حجز الموعد" - }, - "fetchingDoctorSchedulePleaseWait": { - "en": "Fetching Doctor Schedule, Please Wait...", - "ar": "جاري جلب جدول الطبيب، يرجى الانتظار..." - }, - "pickADate": { - "en": "Pick a Date", - "ar": "اختر تاريخاً" - }, - "confirmingAppointmentPleaseWait": { - "en": "Confirming Appointment, Please Wait...", - "ar": "جاري تأكيد الموعد، يرجى الانتظار..." - }, - "appointmentConfirmedSuccessfully": { - "en": "Appointment Confirmed Successfully", - "ar": "تم تأكيد الموعد بنجاح" - }, - "appointmentPayment": { - "en": "Appointment Payment", - "ar": "دفع الموعد" - }, - "checkingPaymentStatusPleaseWait": { - "en": "Checking payment status, Please wait...", - "ar": "جاري التحقق من حالة الدفع، يرجى الانتظار..." - }, - "paymentFailedPleaseTryAgain": { - "en": "Payment Failed! Please try again.", - "ar": "فشل الدفع! يرجى المحاولة مرة أخرى." - }, - "appointmentCheckIn": { - "en": "Appointment check in", - "ar": "تسجيل حضور الموعد" - }, - "insuranceExpiredOrInactive": { - "en": "Insurance expired or inactive", - "ar": "التأمين منتهي الصلاحية أو غير نشط" - }, - "totalAmountToPay": { - "en": "Total amount to pay", - "ar": "المبلغ الإجمالي المستحق" - }, - "vat15": { - "en": "VAT 15%", - "ar": "ضريبة القيمة المضافة 15%" - }, - "liveCare": { - "en": "LiveCare", - "ar": "لايف كير" - }, - "recentVisits": { - "en": "Recent Visits", - "ar": "الزيارات الأخيرة" - }, - "searchByClinic": { - "en": "Search By Clinic", - "ar": "البحث حسب العيادة" - }, - "tapToSelectClinic": { - "en": "Tap to select clinic", - "ar": "انقر لاختيار العيادة" - }, - "searchByDoctor": { - "en": "Search By Doctor", - "ar": "البحث حسب الطبيب" - }, - "tapToSelect": { - "en": "Tap to select", - "ar": "انقر للاختيار" - }, - "searchByRegion": { - "en": "Search By Region", - "ar": "البحث حسب المنطقة" - }, - "centralRegion": { - "en": "Central Region", - "ar": "المنطقة الوسطى" - }, - "immediateConsultation": { - "en": "Immediate Consultation", - "ar": "استشارة فورية" - }, - "scheduledConsultation": { - "en": "Scheduled Consultation", - "ar": "استشارة مجدولة" - }, - "pharmaLiveCare": { - "en": "Pharma LiveCare", - "ar": "لايف كير الصيدلية" - }, - "notSureHelpMeChooseClinic": { - "en": "Not sure? help me choose a clinic!", - "ar": "غير متأكد؟ ساعدني في اختيار عيادة!" - }, - "mentionYourSymptomsAndFindDoctors": { - "en": "Mention your symptoms and find the list of doctors accordingly", - "ar": "اذكر أعراضك واعثر على قائمة الأطباء وفقاً لذلك" - }, - "immediateService": { - "en": "Immediate service", - "ar": "خدمة فورية" - }, - "noNeedToWaitGetMedicalConsultation": { - "en": "No need to wait, you will get medical consultation immediately via video call", - "ar": "لا حاجة للانتظار، ستحصل على استشارة طبية فورية عبر مكالمة فيديو" - }, - "noVisitRequired": { - "en": "No visit required", - "ar": "لا حاجة للزيارة" - }, - "doctorWillContact": { - "en": "Doctor will contact", - "ar": "سيتصل بك الطبيب" - }, - "specialisedDoctorWillContactYou": { - "en": "A specialised doctor will contact you and will be able to view your medical history", - "ar": "سيتصل بك طبيب متخصص وسيكون قادراً على الاطلاع على تاريخك الطبي" - }, - "freeMedicineDelivery": { - "en": "Free medicine delivery", - "ar": "توصيل مجاني للأدوية" - }, - "offersFreeMedicineDelivery": { - "en": "Offers free medicine delivery for the LiveCare appointment", - "ar": "يوفر توصيل مجاني للأدوية لموعد لايف كير" - }, - "dentalChiefComplaints": { - "en": "Dental Chief Complaints", - "ar": "الشكاوى الرئيسة للأسنان" - }, - "viewAvailableAppointments": { - "en": "View available appointments", - "ar": "عرض المواعيد المتاحة" - }, - "doctorProfile": { - "en": "Doctor Profile", - "ar": " ملف الطبيب" - }, - "waitingAppointment": { - "en": "Waiting Appointment", - "ar": "موعد الانتظار" - }, - "hospitalInformation": { - "en": "Hospital Information", - "ar": "معلومات المستشفى" - }, - "fetchingAppointmentShare": { - "en": "Fetching Appointment Share...", - "ar": "جاري جلب تفاصيل الموعد..." - }, - "bookingYourAppointment": { - "en": "Booking your appointment...", - "ar": "جاري حجز موعدك..." - }, - "selectLiveCareClinic": { - "en": "Select LiveCare Clinic", - "ar": "اختر عيادة لايف كير" - }, - "checkingForExistingDentalPlan": { - "en": "Checking for an existing dental plan, Please wait...", - "ar": "جاري التحقق من وجود خطة أسنان حالية، يرجى الانتظار..." - }, - "dentalTreatmentPlan": { - "en": "Dental treatment plan", - "ar": "خطة علاج الأسنان" - }, - "youHaveExistingTreatmentPlan": { - "en": "You have an existing treatment plan: ", - "ar": "لديك خطة علاج حالية: " - }, - "mins": { - "en": "Mins", - "ar": "دقيقة" - }, - "totalTimeRequired": { - "en": "Total time required", - "ar": "إجمالي الوقت المطلوب" - }, - "wouldYouLikeToContinue": { - "en": "Would you like to continue it?", - "ar": "هل تريد متابعتها؟" - }, - "chooseDoctor": { - "en": "Choose Doctor", - "ar": "اختر الطبيب" - }, - "viewNearestAppos": { - "en": "View nearest available appointments", - "ar": "عرض أقرب المواعيد المتاحة" - }, - "noDoctorFound": { - "en": "No Doctor found for selected criteria...", - "ar": "لم يتم العثور على طبيب مطابق للمعايير المحددة..." - }, - "yesPleasImInAHurry": { - "en": "Yes please, I am in a hurry", - "ar": "نعم من فضلك، أنا في عجلة من أمري" - }, - "fetchingFeesPleaseWait": { - "en": "Fetching fees, Please wait...", - "ar": "جاري جلب الرسوم، يرجى الانتظار..." - }, - "noThanksPhysicalVisit": { - "en": "No, Thanks. I would like a physical visit", - "ar": "لا، شكراً. أفضل الزيارة الشخصية" - }, - "offline": { - "en": "Offline", - "ar": "غير متصل" - }, - "videoCall": { - "en": "Video Call", - "ar": "مكالمة فيديو" - }, - "liveVideoCallWithHMGDoctors": { - "en": "Live Video Call with HMG Doctors", - "ar": "مكالمة فيديو مباشرة مع أطباء مجموعة الحبيب الطبية" - }, - "liveAudioCallWithHMGDoctors": { - "en": "Live Audio Call with HMG Doctors", - "ar": "مكالمة صوتية مباشرة مع أطباء مجموعة الحبيب الطبية" - }, - "audioCall": { - "en": "Audio Call", - "ar": "مكالمة صوتية" - }, - "phoneCall": { - "en": "Phone Call", - "ar": "مكالمة هاتفية" - }, - "livePhoneCallWithHMGDoctors": { - "en": "Live Phone Call with HMG Doctors", - "ar": "مكالمة هاتفية مباشرة مع أطباء مجموعة الحبيب الطبية" - }, - "reviewLiveCareRequest": { - "en": "Review LiveCare Request", - "ar": "مراجعة طلب لايف كير" - }, - "selectedLiveCareType": { - "en": "Selected LiveCare Type", - "ar": "نوع لايف كير المحدد" - }, - "selectLiveCareCallType": { - "en": "Select LiveCare call type", - "ar": "اختر نوع مكالمة لايف كير" - }, - "confirmingLiveCareRequest": { - "en": "Confirming LiveCare request, Please wait...", - "ar": "جاري تأكيد طلب لايف كير، يرجى الانتظار..." - }, - "unknownErrorOccurred": { - "en": "Unknown error occurred...", - "ar": "حدث خطأ غير معروف..." - }, - "liveCarePermissionsMessage": { - "en": "LiveCare requires Camera, Microphone, Location & Notifications permissions to enable virtual consultation between patient & doctor...", - "ar": "يتطلب لايف كير أذونات الكاميرا والميكروفون والموقع والإشعارات لتمكين الاستشارة الافتراضية..." - }, - "liveCarePayment": { - "en": "LiveCare Payment", - "ar": "دفع لايف كير" - }, - "mada": { - "en": "Mada", - "ar": "مدى" - }, - "visaOrMastercard": { - "en": "Visa or Mastercard", - "ar": "فيزا أو ماستركارد" - }, - "tamara": { - "en": "Tamara", - "ar": "تمارا" - }, - "fetchingApplePayDetails": { - "en": "Fetching Apple Pay details, Please wait...", - "ar": "جاري جلب تفاصيل Apple Pay، يرجى الانتظار..." - }, - "liveCarePendingRequest": { - "en": "LiveCare Pending Request", - "ar": "طلب لايف كير قيد الانتظار" - }, - "callLiveCareSupport": { - "en": "Call LiveCare Support", - "ar": "اتصل بدعم لايف كير" - }, - "whatIsWaitingAppointment": { - "en": "What is Waiting Appointment?", - "ar": "ما هو موعد الانتظار؟" - }, - "waitingAppointmentsFeature": { - "en": "The waiting appointments feature allows you to book an appointment while you are inside the hospital building...", - "ar": "تتيح لك ميزة مواعيد الانتظار حجز موعد أثناء تواجدك داخل مبنى المستشفى..." - }, - "appointmentWithDoctorConfirmed": { - "en": "The appointment with the doctor is confirmed, but the time of entry is uncertain.", - "ar": "الموعد مع الطبيب مؤكد، ولكن وقت الدخول غير محدد." - }, - "paymentWithinTenMinutes": { - "en": "Note: You must have to pay within 10 minutes of booking, otherwise your appointment will be cancelled automatically", - "ar": "ملاحظة: يجب عليك الدفع خلال 10 دقائق من الحجز، وإلا سيتم إلغاء موعدك تلقائياً" - }, - "liveLocation": { - "en": "Live Location", - "ar": "الموقع المباشر" - }, - "verifyYourLocationAtHospital": { - "en": "Verify your location to be at hospital to check in", - "ar": "تحقق من موقعك في المستشفى لتسجيل الحضور" - }, - "error": { - "en": "Error", - "ar": "خطأ" - }, - "ensureWithinHospitalLocation": { - "en": "Please ensure you're within the hospital location to perform online check-in.", - "ar": "يرجى التأكد من أنك داخل موقع المستشفى لإجراء تسجيل الحضور عبر الإنترنت." - }, - "nfcNearFieldCommunication": { - "en": "NFC (Near Field Communication)", - "ar": "NFC (الاتصال قريب المدى)" - }, - "scanPhoneViaNFC": { - "en": "Scan your phone via NFC board to check in", - "ar": "امسح هاتفك عبر لوحة NFC لتسجيل الحضور" - }, - "qrCode": { - "en": "QR Code", - "ar": "رمز QR" - }, - "scanQRCodeToCheckIn": { - "en": "Scan QR code with your camera to check in", - "ar": "امسح رمز QR بالكاميرا لتسجيل الحضور" - }, - "processingCheckIn": { - "en": "Processing Check-In...", - "ar": "جاري معالجة تسجيل الحضور..." - }, - "bookingWaitingAppointment": { - "en": "Booking Waiting Appointment, Please wait...", - "ar": "جاري حجز موعد الانتظار، يرجى الانتظار..." - }, - "enterValidIDorIqama": { - "en": "Please enter a valid national ID or file number", - "ar": "يرجى إدخال رقم هوية وطنية أو رقم ملف صالح" - }, - "selectAppointment": { - "en": "Select Appointment", - "ar": "حدد الموعد" - }, - "rebookSameDoctor": { - "en": "Rebook with same doctor", - "ar": "أعد الحجز مع نفس الطبيب" - }, - "queueing": { - "en": "Queueing", - "ar": "قائمة الانتظار" - }, - "inQueue": { - "en": "In Queue", - "ar": "في قائمة الانتظار" - }, - "yourTurn": { - "en": "Your Turn", - "ar": "دورك" - }, - "halaFirstName": { - "en": "Hala {firstName}!!!", - "ar": "هلا {firstName}!!!" - }, - "thankYouForPatience": { - "en": "Thank you for your patience, here is your queue number.", - "ar": "شكراً لصبرك، هذا هو رقم قائمة الانتظار الخاص بك." - }, - "servingNow": { - "en": "Serving Now", - "ar": "يُخدم الآن" - }, - "callForVitalSigns": { - "en": "Call for vital signs", - "ar": "نداء للعلامات الحيوية" - }, - "callForDoctor": { - "en": "Call for Doctor", - "ar": "نداء للطبيب" - }, - "thingsToAskDoctor": { - "en": "Things to ask your doctor today", - "ar": "أشياء تسأل طبيبك عنها اليوم" - }, - "improveOverallHealth": { - "en": "What can I do to improve my overall health?", - "ar": "ماذا يمكنني أن أفعل لتحسين صحتي العامة؟" - }, - "routineScreenings": { - "en": "Are there any routine screenings I should get?", - "ar": "هل هناك أي فحوصات روتينية يجب أن أجريها؟" - }, - "whatIsThisMedicationFor": { - "en": "What is this medication for?", - "ar": "لماذا هذا الدواء؟" - }, - "sideEffectsToKnow": { - "en": "Are there any side effects I should know about?", - "ar": "هل هناك أي آثار جانبية يجب أن أعرفها؟" - }, - "whenFollowUp": { - "en": "When should I come back for a follow-up?", - "ar": "متى يجب أن أعود للمتابعة؟" - }, - "goToHomepage": { - "en": "Go to homepage", - "ar": "الذهاب إلى الصفحة الرئيسية" - }, - "appointmentsList": { - "en": "Appointments List", - "ar": "قائمة المواعيد" - }, - "allAppt": { - "en": "All Appt.", - "ar": "جميع المواعيد" - }, - "upcoming": { - "en": "Upcoming", - "ar": "القادمة" - }, - "completed": { - "en": "Completed", - "ar": "المكتملة" - }, - "noAppointmentsYet": { - "en": "You don't have any appointments yet.", - "ar": "ليس لديك أي مواعيد بعد." - }, - "viewProfile": { - "en": "View Profile", - "ar": "عرض الملف الشخصي" - }, - "choosePreferredHospitalForService": { - "en": "Choose your preferred hospital for the service", - "ar": "اختر المستشفى المفضل لديك للخدمة" - }, - "noHospitalsFound": { - "en": "No hospitals Found", - "ar": "لم يتم العثور على مستشفيات" - }, - "cancelOrderConfirmation": { - "en": "Are you sure you want to cancel this order?", - "ar": "هل أنت متأكد أنك تريد إلغاء هذا الطلب؟" - }, - "orderCancelledSuccessfully": { - "en": "Order has been cancelled successfully", - "ar": "تم إلغاء الطلب بنجاح" - }, - "requestID": { - "en": "Request ID:", - "ar": "معرف الطلب:" - }, - "noCMCOrdersYet": { - "en": "You don't have any CMC orders yet.", - "ar": "ليس لديك أي طلبات فحص شامل بعد." - }, - "cmcOrders": { - "en": "CMC Orders", - "ar": "طلبات الفحص الشامل" - }, - "summary": { - "en": "Summary", - "ar": "الملخص" - }, - "selectedService": { - "en": "Selected Service", - "ar": "الخدمة المحددة" - }, - "requestSubmittedSuccessfully": { - "en": "Your request has been successfully submitted.", - "ar": "تم إرسال طلبك بنجاح." - }, - "hereIsYourRequestNumber": { - "en": "Here is your request #: ", - "ar": "هذا هو رقم طلبك #: " - }, - "pleaseSelectHospitalToContinue": { - "en": "Please select a hospital to continue", - "ar": "يرجى اختيار مستشفى للمتابعة" - }, - "confirmSubmitRequest": { - "en": "Are you sure you want to submit this request?", - "ar": "هل أنت متأكد أنك تريد إرسال هذا الطلب؟" - }, - "pendingOrderWait": { - "en": "You have a pending order. Please wait for it to be processed.", - "ar": "لديك طلب معلق. يرجى الانتظار حتى تتم معالجته." - }, - "noServicesAvailable": { - "en": "No services available", - "ar": "لا توجد خدمات متاحة" - }, - "selectAService": { - "en": "Select a Service", - "ar": "اختر خدمة" - }, - "comprehensiveCheckup": { - "en": "Comprehensive Checkup", - "ar": "الفحص الشامل" - }, - "viewNearestHMGLocations": { - "en": "View your nearest HMG locations", - "ar": "عرض أقرب مواقع مجموعة الحبيب الطبية" - }, - "provideFeedbackOnServices": { - "en": "Provide your feedback on our services", - "ar": "قدم ملاحظاتك على خدماتنا" - }, - "liveChatWithHMG": { - "en": "Live chat option with HMG", - "ar": "خيار الدردشة المباشرة مع مجموعة الحبيب الطبية" - }, - "send": { - "en": "Send", - "ar": "إرسال" - }, - "status": { - "en": "Status", - "ar": "الحالة" - }, - "sendingFeedback": { - "en": "Sending Feedback...", - "ar": "جاري إرسال الملاحظات..." - }, - "selectFeedbackType": { - "en": "Select Feedback Type", - "ar": "اختر نوع الملاحظات" - }, - "loadingAppointmentsList": { - "en": "Loading appointments list...", - "ar": "جاري تحميل قائمة المواعيد..." - }, - "noAppointmentsForFeedback": { - "en": "You do not have any appointments to submit a feedback.", - "ar": "ليس لديك أي مواعيد لتقديم ملاحظات عنها." - }, - "selectedAppointment": { - "en": "Selected Appointment:", - "ar": "الموعد المحدد:" - }, - "subject": { - "en": "Subject", - "ar": "الموضوع" - }, - "enterSubjectHere": { - "en": "Enter subject here", - "ar": "أدخل الموضوع هنا" - }, - "message": { - "en": "Message", - "ar": "الرسالة" - }, - "enterMessageHere": { - "en": "Enter message here", - "ar": "أدخل الرسالة هنا" - }, - "filesSelected": { - "en": "{count} file(s) selected", - "ar": "تم تحديد {count} ملف(ات)" - }, - "otherDetails": { - "en": "Other Details", - "ar": "تفاصيل أخرى" - }, - "medicalReport": { - "en": "Medical Report", - "ar": "التقرير الطبي" - }, - "medicalReportNumber": { - "en": "Medical Report {number}", - "ar": "التقرير الطبي {number}" - }, - "patientIsInsured": { - "en": "Patient Is Insured", - "ar": "المريض مؤمن عليه" - }, - "insuranceDocument": { - "en": "Insurance Document", - "ar": "وثيقة التأمين" - }, - "selectBranch": { - "en": "Select Branch", - "ar": "اختر الفرع" - }, - "patientInformation": { - "en": "Patient Information", - "ar": "معلومات المريض" - }, - "patientLocation": { - "en": "Where the patient is located", - "ar": "أين يتواجد المريض" - }, - "identificationNumber": { - "en": "Identification Number", - "ar": "رقم الهوية" - }, - "enterIdentificationNumber": { - "en": "Enter Identification Number*", - "ar": "أدخل رقم الهوية*" - }, - "patientName": { - "en": "Patient Name*", - "ar": "اسم المريض*" - }, - "referralRequesterInformation": { - "en": "Referral Requester Information", - "ar": "معلومات مقدم طلب الإحالة" - }, - "enterReferralRequesterName": { - "en": "Enter Referral Requester Name*", - "ar": "أدخل اسم مقدم طلب الإحالة*" - }, - "requesterName": { - "en": "Requester Name", - "ar": "اسم مقدم الطلب" - }, - "relationship": { - "en": "Relationship", - "ar": "العلاقة" - }, - "selectRelation": { - "en": "Select Relation", - "ar": "اختر العلاقة" - }, - "otherName": { - "en": "Other Name", - "ar": "اسم آخر" - }, - "otherNameHint": { - "en": "Other Name*", - "ar": "اسم آخر*" - }, - "requesterNameRequired": { - "en": "Referral requester name is required", - "ar": "اسم مقدم طلب الإحالة مطلوب" - }, - "selectRelationshipRequired": { - "en": "Please select a relationship", - "ar": "يرجى اختيار العلاقة" - }, - "otherRelationshipNameRequired": { - "en": "Other relationship name is required", - "ar": "اسم العلاقة الأخرى مطلوب" - }, - "identificationNumberRequired": { - "en": "Identification number is required", - "ar": "رقم الهوية مطلوب" - }, - "patientNameRequired": { - "en": "Patient name is required", - "ar": "اسم المريض مطلوب" - }, - "enterPatientPhoneRequired": { - "en": "Please Enter patient phone number", - "ar": "يرجى إدخال رقم هاتف المريض" - }, - "selectPatientCityRequired": { - "en": "Please select patient city", - "ar": "يرجى اختيار مدينة المريض" - }, - "medicalReportRequired": { - "en": "At least one medical report is required", - "ar": "مطلوب تقرير طبي واحد على الأقل" - }, - "selectBranchRequired": { - "en": "Please select a branch", - "ar": "يرجى اختيار الفرع" - }, - "insuranceDocumentRequired": { - "en": "Insurance document is required for insured patients", - "ar": "وثيقة التأمين مطلوبة للمرضى المؤمن عليهم" - }, - "searchResult": { - "en": "Search Result", - "ar": "نتيجة البحث" - }, - "referralNo": { - "en": "Referral No {number}", - "ar": "رقم الإحالة {number}" - }, - "eReferral": { - "en": "E Referral", - "ar": "الإحالة الإلكترونية" - }, - "referralCreatedSuccessfully": { - "en": "Your Referral has been created Successfully.", - "ar": "تم إنشاء إحالتك بنجاح." - }, - "hereIsYourReferralNumber": { - "en": "Here is your Referral #: ", - "ar": "هذا هو رقم الإحالة الخاص بك #: " - }, - "searchEReferral": { - "en": "Search E-Referral", - "ar": "البحث عن إحالة إلكترونية" - }, - "enterRequiredInfoToSearch": { - "en": "Please enter the required information to search for an e-referral", - "ar": "يرجى إدخال المعلومات المطلوبة للبحث عن إحالة إلكترونية" - }, - "selectPickupDirection": { - "en": "Select Pickup Direction", - "ar": "اختر اتجاه الاستلام" - }, - "selectDirection": { - "en": "Select Direction", - "ar": "اختر الاتجاه" - }, - "toHospital": { - "en": "To Hospital", - "ar": "إلى المستشفى" - }, - "fromHospital": { - "en": "From Hospital", - "ar": "من المستشفى" - }, - "selectWay": { - "en": "Select Way", - "ar": "اختر الطريقة" - }, - "oneWay": { - "en": "One Way", - "ar": "اتجاه واحد" - }, - "twoWay": { - "en": "Two Way", - "ar": "اتجاهين" - }, - "selectPickupDetails": { - "en": "Select Pickup Details", - "ar": "اختر تفاصيل الاستلام" - }, - "pleaseSelectDetailsOfPickup": { - "en": " Please select the details of pickup", - "ar": " يرجى تحديد تفاصيل الاستلام" - }, - "selectDetails": { - "en": "Select Details", - "ar": "اختر التفاصيل" - }, - "work": { - "en": "Work", - "ar": "العمل" - }, - "pick": { - "en": "Pick", - "ar": "استلام" - }, - "insideTheHome": { - "en": "Inside the home", - "ar": "داخل المنزل" - }, - "haveAnyAppointment": { - "en": "Have any appointment", - "ar": "هل لديك أي موعد" - }, - "amountPaidAtHospital": { - "en": "Amount will be paid at the hospital", - "ar": "سيتم دفع المبلغ في المستشفى" - }, - "submitRequest": { - "en": "Submit Request", - "ar": "إرسال الطلب" - }, - "enterPickupLocationManually": { - "en": "Enter Pickup Location Manually", - "ar": "أدخل موقع الاستلام يدوياً" - }, - "enterPickupLocation": { - "en": "Enter Pickup Location", - "ar": "أدخل موقع الاستلام" - }, - "trackingDetails": { - "en": "Tracking Details", - "ar": "تفاصيل التتبع" - }, - "cancelRequest": { - "en": "Cancel Request", - "ar": "إلغاء الطلب" - }, - "shareLocationWhatsapp": { - "en": "Share Your Live Location on Whatsapp", - "ar": "مشاركة موقعك المباشر على واتساب" - }, - "pleaseWaitForCall": { - "en": "Please wait for the call", - "ar": "يرجى انتظار المكالمة" - }, - "toHospitalLower": { - "en": "to hospital", - "ar": "إلى المستشفى" - }, - "contact": { - "en": "Contact", - "ar": "اتصال" - }, - "failed": { - "en": "Failed", - "ar": "فشل" - }, - "confirmationCall": { - "en": "Confirmation Call", - "ar": "مكالمة التأكيد" - }, - "pickupFromHome": { - "en": "Pickup Up from Home", - "ar": "الاستلام من المنزل" - }, - "onTheWayToHospital": { - "en": " On The Way To Hospital", - "ar": " في الطريق إلى المستشفى" - }, - "arrivedAtHospital": { - "en": "Arrived at Hospital", - "ar": "وصل إلى المستشفى" - }, - "orderCancel": { - "en": "Order Cancel", - "ar": "إلغاء الطلب" - }, - "emergencyCheckIn": { - "en": "Emergency Check-In", - "ar": "تسجيل الطوارئ الإلكتروني" - }, - "erOnlineCheckInDescription": { - "en": "This service lets patients register their ER appointment prior to arrival.", - "ar": "تتيح هذه الخدمة للمرضى تسجيل موعد الطوارئ قبل الوصول." - }, - "erOnlineCheckInSuccess": { - "en": "Your ER Online Check-In has been successfully done. Please proceed to the waiting area.", - "ar": "تم تسجيل وصول الطوارئ بنجاح. الرجاء التوجه إلى منطقة الانتظار." - }, - "erOnlineCheckInError": { - "en": "Unexpected error occurred during check-in. Please contact support.", - "ar": "حدث خطأ غير متوقع أثناء عملية التسجيل. يرجى التواصل مع الدعم." - }, - "fetchingHospitalsList": { - "en": "Fetching hospitals list...", - "ar": "جاري جلب قائمة المستشفيات..." - }, - "fetchingPaymentInformation": { - "en": "Fetching payment information...", - "ar": "جاري جلب معلومات الدفع..." - }, - "erVisitDetails": { - "en": "ER Visit Details", - "ar": "تفاصيل زيارة الطوارئ" - }, - "erClinic": { - "en": "ER Clinic", - "ar": "عيادة الطوارئ" - }, - "vatWithAmount": { - "en": "VAT 15% ({amount})", - "ar": "الضريبة 15% ({amount})" - }, - "erAppointmentBookedSuccess": { - "en": "Your appointment has been booked successfully. Please perform Check-In once you arrive at the hospital.", - "ar": "تم حجز موعدك بنجاح. يرجى إتمام إجراءات تسجيل الوصول عند وصولك إلى المستشفى." - }, - "underProcessing": { - "en": "Under processing", - "ar": "قيد المعالجة" - }, - "canceledByPatient": { - "en": "Cancelled by patient", - "ar": "ملغى بواسطة المريض" - }, - "rapidResponseTeam": { - "en": "Rapid Response Team", - "ar": "فريق الاستجابة السريع" - }, - "allFacilities": { - "en": "All Facilities", - "ar": "جميع المرافق" - }, - "selectLocation": { - "en": "Select Location", - "ar": "اختر الموقع" - }, - "pleaseSelectTheLocation": { - "en": "Please select the location", - "ar": "يرجى اختيار الموقع" - }, - "viewLocationGoogleMaps": { - "en": "View Location on Google Maps", - "ar": "عرض الموقع على خرائط جوجل" - }, - "callAmbulance": { - "en": "Call Ambulance", - "ar": "استدعاء سيارة إسعاف" - }, - "requestAmbulanceInEmergency": { - "en": "Request an ambulance in emergency from home or hospital", - "ar": "طلب سيارة إسعاف في حالة الطوارئ من المنزل أو المستشفى" - }, - "confirmation": { - "en": "Confirmation", - "ar": "تأكيد" - }, - "areYouSureYouWantToCallAmbulance": { - "en": "Are you sure you want to call an ambulance?", - "ar": "هل أنت متأكد أنك تريد استدعاء سيارة إسعاف؟" - }, - "getDetailsOfNearestBranch": { - "en": "Get the details of nearest branch including directions", - "ar": "احصل على تفاصيل أقرب فرع بما في ذلك الاتجاهات" - }, - "areYouSureYouWantToCallRRT": { - "en": "Are you sure you want to call Rapid Response Team (RRT)?", - "ar": "هل أنت متأكد أنك تريد استدعاء فريق الاستجابة السريعة (RRT)؟" - }, - "priorERCheckInToSkipLine": { - "en": "Prior ER Check-In to skip the line & payment at the reception.", - "ar": "تسجيل الوصول المسبق في الطوارئ لتجاوز الطابور والدفع في الاستقبال." - }, - "areYouSureYouWantToMakeERCheckIn": { - "en": "Are you sure you want to make ER Check-In?", - "ar": "هل أنت متأكد أنك تريد إجراء تسجيل وصول الطوارئ؟" - }, - "checkingYourERAppointmentStatus": { - "en": "Checking your ER Appointment status...", - "ar": "جاري التحقق من حالة موعد الطوارئ الخاص بك..." - }, - "transportOptions": { - "en": "Transport Options", - "ar": "خيارات النقل" - }, - "selectHospitalForAdvancePayment": { - "en": "Please select the hospital you want to make an advance payment for.", - "ar": "يرجى اختيار المستشفى الذي ترغب في دفع مبلغ مقدم له." - }, - "recharge": { - "en": "Recharge", - "ar": "إعادة الشحن" - }, - "activityLevel": { - "en": "Activity Level", - "ar": "مستوى النشاط" - }, - "selectActivityLevel": { - "en": "Select Activity Level", - "ar": "حدد مستوى النشاط" - }, - "caloriesPerDay": { - "en": "Calories Per Day", - "ar": "السعرات الحرارية في اليوم الواحد" - }, - "dietType": { - "en": "Diet Type", - "ar": "نوع النظام الغذائي" - }, - "selectDietType": { - "en": "Select Diet Type", - "ar": "حدد نوع النظام الغذائي" - }, - "bodyFrameSize": { - "en": "Body Frame Size", - "ar": "حجم إطار الجسم" - }, - "selectBodyFrameSize": { - "en": "Select Body Frame Size", - "ar": "حدد حجم إطار الجسم" - }, - "averageCycleLength": { - "en": "Average Cycle Length (Usually 28 days)", - "ar": "متوسط طول الدورة الشهرية (عادةً 28 يومًا)" - }, - "averageLutealPhase": { - "en": "Average Luteal Phase Length(Usually 14 days)", - "ar": "متوسط طول المرحلة الأصفرية (عادةً 14 يومًا)" - }, - "convert": { - "en": "Convert", - "ar": "يتحول" - }, - "calculate": { - "en": "Calculate", - "ar": "احسب" - }, - "healthCalculators": { - "en": "Health Calculators", - "ar": "حاسبات الصحة" - }, - "healthConverters": { - "en": "Health Converters", - "ar": "محولات الصحة" - }, - "generalHealth": { - "en": "General Health", - "ar": "الصحة العامة" - }, - "relatedToBMICalories": { - "en": "Related To BMI, calories, body fat, etc to stay updated with your health.", - "ar": "متعلق بمؤشر كتلة الجسم والسعرات الحرارية ودهون الجسم وما إلى ذلك للبقاء على اطلاع دائم بصحتك." - }, - "selectCalculator": { - "en": "Select Calculator", - "ar": "اختر الآلة الحاسبة" - }, - "womensHealth": { - "en": "Women's Health", - "ar": "صحة المرأة" - }, - "relatedToPeriodsOvulation": { - "en": "Related To periods, ovulation, pregnancy, and other topics.", - "ar": "متعلق بالدورة الشهرية والإباضة والحمل ومواضيع أخرى." - }, - "bloodSugar": { - "en": "Blood Sugar", - "ar": "سكر الدم" - }, - "trackYourGlucoseLevels": { - "en": "Track your glucose levels, understand trends, and get personalized insights for better health.", - "ar": "تتبع مستويات الجلوكوز لديك، وفهم الاتجاهات، واحصل على رؤى مخصصة لصحة أفضل." - }, - "bloodCholesterol": { - "en": "Blood Cholesterol", - "ar": "كوليسترول الدم" - }, - "monitorCholesterolLevels": { - "en": "Monitor cholesterol levels, assess heart health risks, and take proactive steps for well-being.", - "ar": "راقب مستويات الكوليسترول، وقيّم مخاطر صحة القلب، واتخذ خطوات استباقية للرفاهية." - }, - "triglyceridesFatBlood": { - "en": "Triglycerides Fat Blood", - "ar": "الدهون الثلاثية في الدم" - }, - "understandTriglyceridesImpact": { - "en": "Understand triglycerides' impact on heart health with personalized insights and expert recommendations.", - "ar": "افهم تأثير الدهون الثلاثية على صحة القلب مع رؤى مخصصة وتوصيات الخبراء." - }, - "bmiCalculator": { - "en": "BMI\nCalculator", - "ar": "حاسبة\nمؤشر كتلة الجسم" - }, - "caloriesCalculator": { - "en": "Calories\nCalculator", - "ar": "حاسبة\nالسعرات الحرارية" - }, - "bmrCalculator": { - "en": "BMR\nCalculator", - "ar": "حاسبة\nمعدل الأيض الأساسي" - }, - "idealBodyWeight": { - "en": "Ideal Body\nWeight", - "ar": "الوزن المثالي\nللجسم" - }, - "bodyFatCalculator": { - "en": "Body Fat\nCalculator", - "ar": "حاسبة\nدهون الجسم" - }, - "carbsProteinFat": { - "en": "Carbs\nProtein & Fat", - "ar": "الكربوهيدرات\nالبروتين والدهون" - }, - "ovulationPeriod": { - "en": "Ovulation\nPeriod", - "ar": "فترة\nالإباضة" - }, - "deliveryDueDate": { - "en": "Delivery\nDue Date", - "ar": "تاريخ الولادة\nالمتوقع" - }, - "low": { - "en": "Low", - "ar": "منخفض" - }, - "preDiabetic": { - "en": "Pre-diabetic", - "ar": "ما قبل السكري" - }, - "high": { - "en": "High", - "ar": "مرتفع" - }, - "elevated": { - "en": "Elevated", - "ar": "مرتفع قليلاً" - }, - "recorded": { - "en": "Recorded", - "ar": "مسجل" - }, - "noRecordsYet": { - "en": "No records yet", - "ar": "لا توجد سجلات بعد" - }, - "lastRecord": { - "en": "Last Record", - "ar": "آخر سجل" - }, - "addBloodSugar": { - "en": "Add Blood Sugar", - "ar": "إضافة سكر الدم" - }, - "addBloodPressure": { - "en": "Add Blood Pressure", - "ar": "إضافة ضغط الدم" - }, - "addWeight": { - "en": "Add Weight", - "ar": "إضافة الوزن" - }, - "bloodSugarDataSavedSuccessfully": { - "en": "Blood Sugar Data saved successfully", - "ar": "تم حفظ بيانات سكر الدم بنجاح" - }, - "bloodPressureDataSavedSuccessfully": { - "en": "Blood Pressure Data saved successfully", - "ar": "تم حفظ بيانات ضغط الدم بنجاح" - }, - "weightDataSavedSuccessfully": { - "en": "Weight Data saved successfully", - "ar": "تم حفظ بيانات الوزن بنجاح" - }, - "pleaseWait": { - "en": "Please wait", - "ar": "يرجى الانتظار" - }, - "selectUnit": { - "en": "Select Unit", - "ar": "اختر الوحدة" - }, - "selectMeasureTime": { - "en": "Select Measure Time", - "ar": "اختر وقت القياس" - }, - "selectArm": { - "en": "Select Arm", - "ar": "اختر الذراع" - }, - "enterBloodSugar": { - "en": "Enter Blood Sugar", - "ar": "أدخل سكر الدم" - }, - "enterSystolicValue": { - "en": "Enter Systolic Value", - "ar": "أدخل القيمة الانقباضية" - }, - "enterDiastolicValue": { - "en": "Enter Diastolic Value", - "ar": "أدخل القيمة الانبساطية" - }, - "enterWeight": { - "en": "Enter Weight", - "ar": "أدخل الوزن" - }, - "selectDuration": { - "en": "Select Duration", - "ar": "اختر المدة" - }, - "systolic": { - "en": "Systolic", - "ar": "الانقباضي" - }, - "diastolic": { - "en": "Diastolic", - "ar": "الانبساطي" - }, - "sendReportByEmail": { - "en": "Send Report by Email", - "ar": "إرسال التقرير عبر البريد الإلكتروني" - }, - "enterYourEmailToReceiveReport": { - "en": "Enter your email address to receive the report", - "ar": "أدخل عنوان بريدك الإلكتروني لاستلام التقرير" - }, - "addNewRecord": { - "en": "Add new Record", - "ar": "إضافة سجل جديد" - }, - "healthTrackers": { - "en": "Health Trackers", - "ar": "متتبعات الصحة" - }, - "monitorBloodPressureLevels": { - "en": "Monitor your blood pressure levels, track systolic and diastolic readings, and maintain a healthy heart.", - "ar": "راقب مستويات ضغط الدم لديك، وتتبع القراءات الانقباضية والانبساطية، وحافظ على صحة قلبك." - }, - "trackWeightProgress": { - "en": "Track your weight progress, set goals, and maintain a healthy body mass for overall wellness.", - "ar": "تتبع تقدم وزنك، وضع الأهداف، وحافظ على كتلة جسم صحية من أجل العافية الشاملة." - }, - "bookAppointment": { - "en": "Book Appointment", - "ar": "احجز موعد" - }, - "completeCheckup": { - "en": "Complete Checkup", - "ar": "الفحص الشامل" - }, - "indoorNavigation": { - "en": "Indoor Navigation", - "ar": "الملاحة الداخلية" - }, - "eReferralServices": { - "en": "E-Referral Services", - "ar": "خدمات الإحالة الإلكترونية" - }, - "dailyWaterMonitor": { - "en": "Daily Water Monitor", - "ar": "مراقب الماء اليومي" - }, - "fetchingYourWaterIntakeDetails": { - "en": "Fetching your water intake details.", - "ar": "جاري جلب تفاصيل استهلاك الماء الخاص بك." - }, - "healthCalculatorsServices": { - "en": "Health\nCalculators", - "ar": "حاسبات\nالصحة" - }, - "healthConvertersServices": { - "en": "Health\nConverters", - "ar": "محولات\nالصحة" - }, - "smartWatchesServices": { - "en": "Smart\nWatches", - "ar": "الساعات\nالذكية" - }, - "exploreServices": { - "en": "Explore Services", - "ar": "استكشف الخدمات" - }, - "medicalAndCareServices": { - "en": "Medical & Care Services", - "ar": "الخدمات الطبية والرعاية" - }, - "hmgServices": { - "en": "HMG Services", - "ar": "خدمات مجموعة الحبيب الطبية" - }, - "personalServices": { - "en": "Personal Services", - "ar": "الخدمات الشخصية" - }, - "habibWallet": { - "en": "Habib Wallet", - "ar": "محفظة الحبيب" - }, - "loginToViewWalletBalance": { - "en": "Login to view your wallet balance", - "ar": "سجل الدخول لعرض رصيد محفظتك" - }, - "loginToViewMedicalFile": { - "en": "Login to view your medical file", - "ar": "سجل الدخول لعرض ملفك الطبي" - }, - "addMember": { - "en": "Add Member", - "ar": "إضافة عضو" - }, - "addFamilyMember": { - "en": "Add Family Member", - "ar": "إضافة فرد من العائلة" - }, - "pleaseFillBelowFieldToAddNewFamilyMember": { - "en": "Please fill the below field to add a new family member to your profile", - "ar": "يرجى ملء الحقل أدناه لإضافة فرد جديد من العائلة إلى ملفك الشخصي" - }, - "healthTools": { - "en": "Health Tools", - "ar": "أدوات الصحة" - }, - "supportServices": { - "en": "Support Services", - "ar": "خدمات الدعم" - }, - "virtualTour": { - "en": "Virtual Tour", - "ar": "جولة افتراضية" - }, - "carParking": { - "en": "Car Parking", - "ar": "موقف السيارات" - }, - "latestNews": { - "en": "Latest News", - "ar": "آخر الأخبار" - }, - "hmgContact": { - "en": "HMG Contact", - "ar": "اتصل بمجموعة الحبيب الطبية" - }, - "durationCannotExceed90": { - "en": "Duration can not exceed 90 mins", - "ar": "لا يجوز أن تتجاوز المدة 90 دقيقة" - }, - "unexpectedError": { - "en": "Unexpected Error Occurred", - "ar": "حدث خطأ غير متوقع" - }, - "gettingAmbulanceTransportOption": { - "en": "Getting Ambulance Transport Option", - "ar": "جاري الحصول على خيارات نقل الإسعاف" - }, - "fetchingAppointment": { - "en": "Fetching Appointment", - "ar": "جاري جلب الموعد" - }, - "doYouWantToCancelTheRequest": { - "en": "Do you want to cancel the request", - "ar": "هل تريد إلغاء الطلب" - }, - "cancellingRequest": { - "en": "Cancelling request", - "ar": "جاري إلغاء الطلب" - }, - "fetchingTermsAndConditions": { - "en": "Fetching Terms And Conditions", - "ar": "جاري جلب الشروط والأحكام" - }, - "selectLocationPrescriptionDelivery": { - "en": "Please select the location for prescription delivery", - "ar": "يرجى تحديد موقع توصيل الوصفة الطبية" - }, - "noRadiologyOrders": { - "en": "No Radiology Orders Found", - "ar": "لم يتم العثور على أي طلبات تصوير شعاعي" - }, - "ageIsRequired": { - "en": "Age is required", - "ar": "العمر مطلوب" - }, - "invalidAge": { - "en": "Invalid age", - "ar": "العمر غير صالح" - }, - "ageMustBeBetween11And120": { - "en": "Age must be between 11 and 120", - "ar": "يجب أن يكون العمر بين 11 و 120" - }, - "heightIsRequired": { - "en": "Height is required", - "ar": "الطول مطلوب" - }, - "invalidHeight": { - "en": "Invalid height", - "ar": "الطول غير صالح" - }, - "weightIsRequired": { - "en": "Weight is required", - "ar": "الوزن مطلوب" - }, - "invalidWeight": { - "en": "Invalid weight", - "ar": "الوزن غير صالح" - }, - "timeToDrinkWater": { - "en": "Time to Drink Water! 💧", - "ar": "حان وقت شرب الماء! 💧" - }, - "stayHydratedDrinkWater": { - "en": "Stay hydrated! Drink {amount}ml of water.", - "ar": "ابق رطبًا! اشرب {amount} مل من الماء." - }, - "visitPharmacyOnline": { - "en": "Visit Pharmacy Online", - "ar": "زيارة الصيدلية على الانترنت" - }, - "howAreYouFeelingToday": { - "en": "How are you feeling today?", - "ar": "كيف حالك اليوم؟" - }, - "checkYourSymptomsWithScale": { - "en": "Check your symptoms with this scale", - "ar": "تحقق من أعراضك باستخدام ذا المقياس" - }, - "checkYourSymptoms": { - "en": "Check your symptoms", - "ar": "تحقق من أعراضك" - }, - "noUpcomingAppointmentPleaseBook": { - "en": "You do not have any upcoming appointment. Please book an appointment", - "ar": "ليس لديك أي مواعيد قادمة. يرجى حجز موعد" - }, - "youHaveEROnlineCheckInRequest": { - "en": "You have ER Online Check-In Request", - "ar": "لديك طلب تسجيل وصول عبر الإنترنت للطوارئ" - }, - "quickLinks": { - "en": "Quick Links", - "ar": "روابط سريعة" - }, - "viewMedicalFileLandingPage": { - "en": "View medical file", - "ar": "عرض الملف الطبي" - }, - "immediateLiveCareRequest": { - "en": "Immediate LiveCare Request", - "ar": "طلب لايف كير فوري" - }, - "yourTurnIsAfterPatients": { - "en": "Your turn is after {count} patients.", - "ar": "دورك بعد {count} مريض." - }, - "dontHaveHHCOrders": { - "en": "You don't have any Home Health Care orders yet.", - "ar": "ليس لديك أي أوامر رعاية صحية منزلية حتى الآن." - }, - "hhcOrders": { - "en": "HHC Orders", - "ar": "أوامر الرعاية الصحية المنزلية" - }, - "requestedServices": { - "en": "Requested Services", - "ar": "الخدمات المطلوبة" - }, - "selectServices": { - "en": "Select Services", - "ar": "اختر الخدمات" - }, - "selectedServices": { - "en": "Selected Services", - "ar": "الخدمات المختارة" - }, - "createNewRequest": { - "en": "Create new request", - "ar": "إنشاء طلب جديد" - }, - "youHaveNoPendingRequests": { - "en": "You have no pending requests.", - "ar": "ليس لديك أي طلبات معلقة." - }, - "noInsuranceDataFound": { - "en": "No insurance data found...", - "ar": "لم يتم العثور على بيانات التأمين..." - }, - "noInsuranceUpdateRequest": { - "en": "No insurance update requests found.", - "ar": "لم يتم العثور على أي طلبات لتحديث بيانات التأمين." - }, - "policyNumberInsurancePage": { - "en": "Policy: {number}", - "ar": "الوثيقة: {number}" - }, - "insuranceExpired": { - "en": "Insurance Expired", - "ar": "التأمين منتهي الصلاحية" - }, - "insuranceActive": { - "en": "Insurance Active", - "ar": "التأمين نشط" - }, - "patientCardID": { - "en": "Patient Card ID: {id}", - "ar": "رقم بطاقة المريض: {id}" - }, - "noInsuranceApprovals": { - "en": "You don't have any insurance approvals yet.", - "ar": "لم تحصل على أي موافقات تأمينية حتى الآن." - }, - "noInsuranceWithHMG": { - "en": "You don't have an insurance registered with HMG.", - "ar": "ليس لديك تأمين مسجل لدى مجموعة الحبيب الطبية." - }, - "referenceRange": { - "en": "Reference Range", - "ar": "النطاق المرجعي" - }, - "downloadReport": { - "en": "Download Report", - "ar": "تنزيل التقرير" - }, - "generatingReport": { - "en": "Generating Report, Please wait...", - "ar": "جارٍ إنشاء التقرير، يرجى الانتظار..." - }, - "noLabResults": { - "en": "You don't have any lab results yet.", - "ar": "ليس لديك أي نتائج مختبرية حتى الآن." - }, - "labResultDetails": { - "en": "Lab Result Details", - "ar": "تفاصيل نتائج المختبر" - }, - "resultOf": { - "en": "Result of {date}", - "ar": "نتيجة {date}" - }, - "whatIsThisResult": { - "en": "What is this result?", - "ar": "ما هي هذه النتيجة؟" - }, - "lastTested": { - "en": "Last Tested", - "ar": "آخر اختبار" - }, - "byVisit": { - "en": "By Visit", - "ar": "حسب الزيارة" - }, - "byTest": { - "en": "By Test", - "ar": "حسب التحليل" - }, - "results": { - "en": "results", - "ar": "نتائج" - }, - "viewResults": { - "en": "View Results", - "ar": "عرض النتائج" - }, - "rebook": { - "en": "Rebook", - "ar": "إعادة الحجز" - }, - "noOphthalmologyAppointments": { - "en": "No Ophthalmology appointments found...", - "ar": "لم يتم العثور على أي مواعيد في قسم طب العيون..." - }, - "noVitalSignsRecordedYet": { - "en": "No vital signs recorded yet", - "ar": "لا توجد علامات حيوية مسجلة بعد" - }, - "appointmentsAndVisits": { - "en": "Appointments & visits", - "ar": "المواعيد والزيارات" - }, - "labAndRadiology": { - "en": "Lab & Radiology", - "ar": "المختبر والأشعة" - }, - "activeMedicationsAndPrescriptions": { - "en": "Active Medications & Prescriptions", - "ar": "الأدوية النشطة والوصفات الطبية" - }, - "allPrescriptions": { - "en": "All Prescriptions", - "ar": "جميع الوصفات" - }, - "allMedications": { - "en": "All Medications", - "ar": "جميع الأدوية" - }, - "youDontHaveAnyPrescriptionsYet": { - "en": "You don't have any prescriptions yet.", - "ar": "ليس لديك أي وصفات طبية بعد." - }, - "youDontHaveAnyCompletedVisitsYet": { - "en": "You don't have any completed visits yet", - "ar": "ليس لديك أي زيارات مكتملة بعد" - }, - "others": { - "en": "Others", - "ar": "أخرى" - }, - "allergyInfo": { - "en": "Allergy Info", - "ar": "معلومات الحساسية" - }, - "vaccineInfo": { - "en": "Vaccine Info", - "ar": "معلومات اللقاحات" - }, - "updateInsuranceInfo": { - "en": "Update Insurance", - "ar": "تحديث التأمين" - }, - "myInvoicesList": { - "en": "My Invoices List", - "ar": "قائمة فواتيري" - }, - "ancillaryOrdersList": { - "en": "Ancillary Orders List", - "ar": "قائمة الطلبات المساعدة" - }, - "youDontHaveAnySickLeavesYet": { - "en": "You don't have any sick leaves yet.", - "ar": "ليس لديك أي إجازات مرضية بعد." - }, - "medicalReports": { - "en": "Medical Reports", - "ar": "التقارير الطبية" - }, - "sickLeaveReport": { - "en": "Sick Leave Report", - "ar": "تقرير الإجازة المرضية" - }, - "weightTracker": { - "en": "Weight Tracker", - "ar": "متتبع الوزن" - }, - "askYourDoctor": { - "en": "Ask Your Doctor", - "ar": "اسأل طبيبك" - }, - "internetPairing": { - "en": "Internet Pairing", - "ar": "الاقتران بالإنترنت" - }, - "requested": { - "en": "Requested", - "ar": "مطلوب" - }, - "youDontHaveAnyMedicalReportsYet": { - "en": "You don't have any medical reports yet.", - "ar": "ليس لديك أي تقارير طبية بعد." - }, - "requestMedicalReport": { - "en": "Request medical report", - "ar": "طلب تقرير طبي" - }, - "youDoNotHaveAnyAppointmentsToRequestMedicalReport": { - "en": "You do not have any appointments to request a medical report.", - "ar": "ليس لديك أي مواعيد لطلب تقرير طبي." - }, - "areYouSureYouWantToRequestMedicalReport": { - "en": "Are you sure you want to request a medical report for this appointment?", - "ar": "هل أنت متأكد أنك تريد طلب تقرير طبي لهذا الموعد؟" - }, - "yourMedicalReportRequestSubmittedSuccessfully": { - "en": "Your medical report request has been successfully submitted.", - "ar": "تم إرسال طلب التقرير الطبي بنجاح." - }, - "monthlyHealthSummaryReportDisclaimer": { - "en": "This monthly health summary report reflects the health indicators and analysis results of the latest visits. Please note that this will be sent automatically from the system and it's not considered as a official report so no medical decision should be taken based on it", - "ar": "يعكس تقرير الملخص الصحي الشهري هذا المؤشرات الصحية ونتائج التحليل لأحدث الزيارات. يرجى ملاحظة أن هذا سيتم إرساله تلقائيًا من النظام ولا يعتبر تقريرًا رسميًا لذا لا ينبغي اتخاذ أي قرار طبي بناءً عليه" - }, - "updatingMonthlyReportStatus": { - "en": "Updating Monthly Report Status...", - "ar": "جاري تحديث حالة التقرير الشهري..." - }, - "monthlyReportStatusUpdatedSuccessfully": { - "en": "Monthly Report Status Updated Successfully", - "ar": "تم تحديث حالة التقرير الشهري بنجاح" - }, - "whoCanViewMyMedicalFile": { - "en": "Who can view my medical file?", - "ar": "من يمكنه عرض ملفي الطبي؟" - }, - "acceptedYourRequestToBeYourFamilyMember": { - "en": "{status} your request to be your family member", - "ar": "{status} طلب الانضمام الى أفراد عائلتك" - }, - "canViewYourFile": { - "en": "can view your file", - "ar": "يمكنه عرض ملفك" - }, - "hasARequestPendingToBeYourFamilyMember": { - "en": "has a request {status} to be your family member", - "ar": "لديه طلب {status} ليكون فردًا من عائلتك" - }, - "wantsToAddYouAsTheirFamilyMember": { - "en": "wants to add you as their family member", - "ar": "يرغب في إضافتك كفرد من أفراد العائلة" - }, - "rejectedYourRequestToBeYourFamilyMember": { - "en": "{status} your request to be your family member", - "ar": "{status} طلب الانضمام إلى عائلتك" - }, - "rejectedYourFamilyMemberRequest": { - "en": "{status} your family member request", - "ar": "{status} طلب أحد أفراد عائلتك" - }, - "notAvailable": { - "en": "N/A", - "ar": "غير متاح" - }, - "selectAProfile": { - "en": "Please select a profile", - "ar": "الرجاء تحديد ملف تعريف" - }, - "switchFamilyFile": { - "en": "Switch from the below list of medical file", - "ar": "قم بالتبديل من قائمة الملفات الطبية أدناه" - }, - "medicalFiles": { - "en": "Medical Files", - "ar": "الملفات الطبية" - }, - "addANewFamilyMember": { - "en": "Add a new family member", - "ar": "إضافة فرد جديد من العائلة" - }, - "viewInvoiceDetails": { - "en": "View invoice details", - "ar": "عرض تفاصيل الفاتورة" - }, - "outPatient": { - "en": "OutPatient", - "ar": "مريض خارجي" - }, - "invoiceDetails": { - "en": "Invoice Details", - "ar": "تفاصيل الفاتورة" - }, - "sendingEmailPleaseWait": { - "en": "Sending email, Please wait...", - "ar": "جاري إرسال البريد الإلكتروني، يرجى الانتظار..." - }, - "emailSentSuccessfullyMessage": { - "en": "Email sent successfully.", - "ar": "تم إرسال البريد الإلكتروني بنجاح." - }, - "discount": { - "en": "Discount", - "ar": "خصم" - }, - "paid": { - "en": "Paid", - "ar": "مدفوع" - }, - "fetchingInvoiceDetails": { - "en": "Fetching invoice details, Please wait...", - "ar": "جارٍ جلب تفاصيل الفاتورة، يرجى الانتظار..." - }, - "scanQRCode": { - "en": "Scan QR code", - "ar": "مسح رمز الاستجابة السريعة" - }, - "parkingSlotDetails": { - "en": "Parking Slot Details", - "ar": "تفاصيل موقف السيارة" - }, - "slotNumber": { - "en": "Slot: {code}", - "ar": "رقم الموقف: {code}" - }, - "basement": { - "en": "Basement: {description}", - "ar": "الطابق: {description}" - }, - "parkingDate": { - "en": "Date: {date}", - "ar": "التاريخ: {date}" - }, - "parkedSince": { - "en": "Parked Since: {time}", - "ar": "متوقف منذ: {time}" - }, - "resetDirection": { - "en": "Reset Direction", - "ar": "إعادة تعيين الاتجاه" - }, - "noPrescriptionOrdersYet": { - "en": "You don't have any prescription orders yet.", - "ar": "ليس لديك أي طلبات وصفات طبية حتى الآن." - }, - "fetchingPrescriptionPDFPleaseWait": { - "en": "Fetching prescription PDF, Please wait...", - "ar": "جاري جلب ملف الوصفة الطبية، يرجى الانتظار..." - }, - "ratingValue": { - "en": "Rating: {rating}", - "ar": "التقييم: {rating}" - }, - "downloadPrescription": { - "en": "Download Prescription", - "ar": "تحميل الوصفة الطبية" - }, - "fetchingPrescriptionDetails": { - "en": "Fetching prescription details...", - "ar": "جاري جلب تفاصيل الوصفة الطبية..." - }, - "switchBackFamilyFile": { - "en": "Switch Back To Family File", - "ar": "العودة إلى ملف العائلة" - }, - "profileAndSettings": { - "en": "Profile & Settings", - "ar": "الملف الشخصي والإعدادات" - }, - "quickActions": { - "en": "Quick Actions", - "ar": "إجراءات سريعة" - }, - "notificationsSettings": { - "en": "Notifications Settings", - "ar": "إعدادات الإشعارات" - }, - "touchIDFaceIDServices": { - "en": "Touch ID / Face ID Services", - "ar": "خدمات Touch ID / Face ID" - }, - "personalInformation": { - "en": "Personal Information", - "ar": "المعلومات الشخصية" - }, - "updateEmailAddress": { - "en": "Update Email Address", - "ar": "تحديث عنوان البريد الإلكتروني" - }, - "helpAndSupport": { - "en": "Help & Support", - "ar": "المساعدة والدعم" - }, - "permissionsProfile": { - "en": "Permissions", - "ar": "الأذونات" - }, - "privacyPolicy": { - "en": "Privacy Policy", - "ar": "سياسة الخصوصية" - }, - "deactivateAccount": { - "en": "Deactivate account", - "ar": "إلغاء تنشيط الحساب" - }, - "ageYearsOld": { - "en": "{age} {yearsOld}", - "ar": "{age} {yearsOld}" - }, - "youDontHaveRadiologyOrders": { - "en": "You don't have any radiology results yet.", - "ar": "ليس لديك أي نتائج للأشعة حتى الآن." - }, - "radiologyResult": { - "en": "Radiology Result", - "ar": "نتيجة الأشعة" - }, - "viewRadiologyImage": { - "en": "View Radiology Image", - "ar": "عرض صورة الأشعة" - }, - "rateClinic": { - "en": "Rate Clinic", - "ar": "تقييم العيادة" - }, - "back": { - "en": "Back", - "ar": "رجوع" - }, - "rateDoctor": { - "en": "Rate Doctor", - "ar": "تقييم الطبيب" - }, - "howWasYourLastVisitWithDoctor": { - "en": "How was your last visit with doctor?", - "ar": "كيف كانت زيارتك الأخيرة مع الطبيب؟" - }, - "dateOfBirthSymptoms": { - "en": "What is your Date of Birth?", - "ar": "ما هو تاريخ ميلادك؟" - }, - "genderSymptoms": { - "en": "What is your gender?", - "ar": "ما هو جنسك؟" - }, - "heightSymptoms": { - "en": "How tall are you?", - "ar": "كم طولك؟" - }, - "weightSymptoms": { - "en": "What is your weight?", - "ar": "ما هو وزنك؟" - }, - "femaleGender": { - "en": "Female", - "ar": "أنثى" - }, - "previous": { - "en": "Previous", - "ar": "سابق" - }, - "selectedOrgans": { - "en": "Selected Organs", - "ar": "الهيئات المختارة" - }, - "noOrgansSelected": { - "en": "No organs selected yet", - "ar": "لم يتم تحديد أي أعضاء بعد" - }, - "organSelector": { - "en": "Organ Selector", - "ar": "محدد الأعضاء" - }, - "noPredictionsAvailable": { - "en": "No Predictions available", - "ar": "لا توجد تنبؤات متاحة" - }, - "areYouSureYouWantToRestartOrganSelection": { - "en": "Are you sure you want to restart the organ selection?", - "ar": "هل أنت متأكد أنك تريد إعادة تشغيل اختيار الأعضاء؟" - }, - "possibleConditions": { - "en": "Possible Conditions", - "ar": "الحالات المحتملة" - }, - "pleaseSelectAtLeastOneRiskBeforeProceeding": { - "en": "Please select at least one risk before proceeding", - "ar": "يرجى اختيار عامل خطر واحد على الأقل قبل المتابعة" - }, - "aboveYouSeeCommonRiskFactors": { - "en": "Above you see the most common risk factors. Although /diagnosis may return questions about risk factors, ", - "ar": "أعلاه ترى عوامل الخطر الأكثر شيوعًا. على الرغم من أن /diagnosis قد تعيد أسئلة حول عوامل الخطر، " - }, - "readMore": { - "en": "Read more", - "ar": "اقرأ المزيد" - }, - "riskFactors": { - "en": "Risk Factors", - "ar": "عوامل الخطر" - }, - "noRiskFactorsFound": { - "en": "No risk factors found", - "ar": "لم يتم العثور على عوامل خطر" - }, - "basedOnYourSelectedSymptomsNoRiskFactors": { - "en": "Based on your selected symptoms, no additional risk factors were identified.", - "ar": "بناءً على الأعراض المحددة، لم يتم تحديد عوامل خطر إضافية." - }, - "messageNotification": { - "en": "Message", - "ar": "الرسالة" - }, - "attachedImage": { - "en": "Attached Image", - "ar": "الصورة المرفقة" - }, - "failedToLoadImage": { - "en": "Failed to load image", - "ar": "فشل تحميل الصورة" - }, - "typeNotification": { - "en": "Type", - "ar": "النوع" - }, - "pleaseSelectAtLeastOneOptionBeforeProceeding": { - "en": "Please select at least one option before proceeding", - "ar": "يرجى اختيار خيار واحد على الأقل قبل المتابعة" - }, - "suggestions": { - "en": "Suggestions", - "ar": "الاقتراحات" - }, - "pleaseGoBackAndSelectOrgansFirst": { - "en": "Please go back and select organs first", - "ar": "يرجى العودة واختيار الأعضاء أولاً" - }, - "symptomsSelector": { - "en": "Symptoms Selector", - "ar": "محدد الأعراض" - }, - "possibleSymptomsRelatedTo": { - "en": "Possible symptoms related to", - "ar": "الأعراض المحتملة المتعلقة بـ" - }, - "suggestionAIListDescription": { - "en": "This is a list of symptoms suggested by our AI, based on the information gathered so far during the interview", - "ar": "هذه قائمة بالأعراض المقترحة من قبل الذكاء الاصطناعي، بناءً على المعلومات التي تم جمعها حتى الآن خلال المقابلة" - }, - "analyzing": { - "en": "Analyzing...", - "ar": "جاري التحليل..." - }, - "seekMedicalAdvice": { - "en": "Seek Medical Advice", - "ar": "اطلب المشورة الطبية" - }, - "monitorDescription": { - "en": "No need to seek medical advice. Just keep healthy routine.", - "ar": "لا حاجة لطلب المشورة الطبية. فقط حافظ على روتين صحي." - }, - "seekMedicalAdviceDescription": { - "en": "Not emergency but better to monitor the symptoms.", - "ar": "ليست حالة طوارئ ولكن من الأفضل مراقبة الأعراض." - }, - "emergencyDescription": { - "en": "Need to consult doctor as soon as possible before getting too late.", - "ar": "تحتاج إلى استشارة الطبيب في أقرب وقت ممكن قبل فوات الأوان." - }, - "colorScience": { - "en": "Color Science", - "ar": "دلالات الألوان" - }, - "noNeedToVisitDoctor": { - "en": "No need to visit doctor", - "ar": "لا حاجة لزيارة الطبيب" - }, - "commonSymptom": { - "en": "Common Symptom", - "ar": "الأعراض الشائعة" - }, - "notApplicable": { - "en": "Not Applicable", - "ar": "لا ينطبق" - }, - "emergencyTriage": { - "en": "Emergency", - "ar": "طوارئ" - }, - "emergencyEvidenceDetected": { - "en": "Emergency evidence detected. Please seek medical attention.", - "ar": "تم اكتشاف دليل طوارئ. يرجى طلب العناية الطبية." - }, - "noQuestionItemsAvailable": { - "en": "No question items available", - "ar": "لا توجد عناصر أسئلة متاحة" - }, - "pleaseAnswerAllQuestionsBeforeProceeding": { - "en": "Please answer all questions before proceeding", - "ar": "يرجى الإجابة على جميع الأسئلة قبل المتابعة" - }, - "triage": { - "en": "Triage", - "ar": "الفرز" - }, - "areYouSureYouWantToExitProgress": { - "en": "Are you sure you want to exit? Your progress will be lost.", - "ar": "هل أنت متأكد أنك تريد الخروج؟ سيتم فقدان تقدمك." - }, - "noQuestionAvailable": { - "en": "No question available", - "ar": "لا يوجد سؤال متاح" - }, - "possibleSymptom": { - "en": "Possible symptom: ", - "ar": "عرض محتمل: " - }, - "symptomsCheckerFindingScore": { - "en": "- Symptoms checker finding score", - "ar": "- درجة نتائج فاحص الأعراض" - }, - "notSet": { - "en": "Not set", - "ar": "غير محدد" - }, - "years": { - "en": "Years", - "ar": "سنوات" - }, - "symptomsChecker": { - "en": "Symptoms Checker", - "ar": "فاحص الأعراض" - }, - "helloIsYourInformationUpToDate": { - "en": "Hello {name}, Is your information up to date?", - "ar": "مرحباً {name}، هل معلوماتك محدثة؟" - }, - "noEditAll": { - "en": "No, Edit all", - "ar": "لا، تعديل الكل" - }, - "yesItIs": { - "en": "Yes, It is", - "ar": "نعم، إنها كذلك" - }, - "age": { - "en": "Age", - "ar": "العمر" - }, - "youDontHaveAnyAncillaryOrdersYet": { - "en": "You don't have any ancillary orders yet.", - "ar": "ليس لديك أي طلبات مساعدة بعد." - }, - "invoiceWithNumber": { - "en": "Invoice: {invoiceNo}", - "ar": "الفاتورة: {invoiceNo}" - }, - "queued": { - "en": "Queued", - "ar": "في قائمة الانتظار" - }, - "checkInReady": { - "en": "Check-in Ready", - "ar": "جاهز للتسجيل" - }, - "checkIn": { - "en": "Check In", - "ar": "تسجيل الوصول" - }, - "viewDetails": { - "en": "View Details", - "ar": "عرض التفاصيل" - }, - "selectPaymentMethod": { - "en": "Select Payment Method", - "ar": "اختر طريقة الدفع" - }, - "processingPaymentPleaseWait": { - "en": "Processing payment, Please wait...", - "ar": "جاري معالجة الدفع، يرجى الانتظار..." - }, - "finalizingPaymentPleaseWait": { - "en": "Finalizing payment, Please wait...", - "ar": "جاري إتمام الدفع، يرجى الانتظار..." - }, - "generatingInvoicePleaseWait": { - "en": "Generating invoice, Please wait...", - "ar": "جاري إنشاء الفاتورة، يرجى الانتظار..." - }, - "hereIsYourInvoiceNumber": { - "en": "Here is your invoice #: ", - "ar": "هذا هو رقم فاتورتك #: " - }, - "paymentCompletedSuccessfully": { - "en": "Payment Completed Successfully", - "ar": "تم الدفع بنجاح" - }, - "failedToInitializeApplePay": { - "en": "Failed to initialize Apple Pay. Please try again.", - "ar": "فشل في تهيئة Apple Pay. يرجى المحاولة مرة أخرى." - }, - "cash": { - "en": "Cash", - "ar": "نقدي" - }, - "approved": { - "en": "Approved", - "ar": "موافق عليه" - }, - "approvalRejectedPleaseVisitReceptionist": { - "en": "Approval Rejected - Please visit receptionist", - "ar": "تم رفض الموافقة - يرجى زيارة موظف الاستقبال" - }, - "sentForApproval": { - "en": "Sent For Approval", - "ar": "تم إرساله للموافقة" - }, - "ancillaryOrderDetails": { - "en": "Ancillary Order Details", - "ar": "تفاصيل الطلبات المساندة" - }, - "noProceduresAvailableForSelectedOrder": { - "en": "No Procedures available for the selected order.", - "ar": "لا توجد إجراءات متاحة للطلب المحدد." - }, - "procedures": { - "en": "Procedures", - "ar": "الإجراءات" - }, - "totalAmount": { - "en": "Total Amount", - "ar": "المبلغ الإجمالي" - }, - "covered": { - "en": "Covered", - "ar": "مغطى" - }, - "vatPercent": { - "en": "VAT (15%)", - "ar": "ضريبة القيمة المضافة (15%)" - }, - "proceedToPayment": { - "en": "Proceed to Payment", - "ar": "المتابعة للدفع" - }, - "supportedSmartWatches": { - "en": "Supported Smart Watches", - "ar": "الساعات الذكية المدعومة" - }, - "pleaseMakeSureSamsungWatchConnected": { - "en": "Please make sure that your Samsung Watch is connected to your Phone, is actively synced & updated.", - "ar": "يرجى التأكد من أن ساعة Samsung الخاصة بك متصلة بهاتفك، ومتزامنة ومحدثة بشكل نشط." - }, - "beforeSyncingDataFollowInstructions": { - "en": "Before syncing data, please make sure that you have followed the instructions properly.", - "ar": "قبل مزامنة البيانات، يرجى التأكد من اتباع التعليمات بشكل صحيح." - }, - "viewWatchInstructions": { - "en": "View watch instructions", - "ar": "عرض تعليمات الساعة" - }, - "healthConnectAppNotInstalled": { - "en": "Seems like you do not have Health Connect App installed. Please install it from the Play Store to sync your health data.", - "ar": "يبدو أنه ليس لديك تطبيق Health Connect مثبتًا. يرجى تثبيته من متجر Play لمزامنة بيانات صحتك." - }, - "setTimerOfReminder": { - "en": "Set the timer of reminder", - "ar": "ضبط مؤقت التذكير" - }, - "youHaveAppointmentWithDr": { - "en": "You have appointment with Dr. ", - "ar": "لديك موعد مع د. " - }, - "hours": { - "en": "Hours", - "ar": "ساعات" - }, - "secs": { - "en": "Secs", - "ar": "ثواني" - }, - "noAllergiesDataFound": { - "en": "No allergies data found...", - "ar": "لم يتم العثور على بيانات الحساسية..." - }, - "heartRateDescription": { - "en": "Your heart rate indicates how many times your heart beats per minute", - "ar": "معدل ضربات قلبك يشير إلى عدد المرات التي ينبض فيها قلبك في الدقيقة" - }, - "bloodOxygenDescription": { - "en": "Blood oxygen level indicates how much oxygen your red blood cells are carrying", - "ar": "مستوى الأكسجين في الدم يشير إلى كمية الأكسجين التي تحملها خلايا الدم الحمراء" - }, - "stepsDescription": { - "en": "Number of steps taken throughout the day", - "ar": "عدد الخطوات المتخذة على مدار اليوم" - }, - "caloriesDescription": { - "en": "Calories burned during physical activity", - "ar": "السعرات الحرارية المحروقة أثناء النشاط البدني" - }, - "distanceDescription": { - "en": "Distance covered throughout the day", - "ar": "المسافة المقطوعة على مدار اليوم" - }, - "overview": { - "en": "Overview", - "ar": "نظرة عامة" - }, - "details": { - "en": "Details", - "ar": "التفاصيل" - }, - "healthy": { - "en": "Healthy", - "ar": "صحي" - }, - "warning": { - "en": "Warning", - "ar": "تحذير" - }, - "vitalSignDetails": { - "en": "Vital Sign Details", - "ar": "تفاصيل العلامات الحيوية" - }, - "resultOfNoDate": { - "en": "Result of --", - "ar": "نتيجة --" - }, - "referenceRangeBetween": { - "en": "Reference range: {low} – {high} {unit}", - "ar": "النطاق المرجعي: {low} – {high} {unit}" - }, - "referenceRangeMin": { - "en": "Reference range: ≥ {low} {unit}", - "ar": "النطاق المرجعي: ≥ {low} {unit}" - }, - "referenceRangeMax": { - "en": "Reference range: ≤ {high} {unit}", - "ar": "النطاق المرجعي: ≤ {high} {unit}" - }, - "noHistoryAvailable": { - "en": "No history available", - "ar": "لا يوجد تاريخ متاح" - }, - "bmiDescription": { - "en": "BMI is a measurement based on height and weight that estimates body fat.", - "ar": "مؤشر كتلة الجسم هو قياس يعتمد على الطول والوزن لتقدير دهون الجسم." - }, - "heightDescription": { - "en": "Height is measured in centimeters and is used to calculate BMI and dosage recommendations.", - "ar": "يقاس الطول بالسنتيمتر ويستخدم لحساب مؤشر كتلة الجسم وتوصيات الجرعات." - }, - "weightDescription": { - "en": "Weight helps track overall health, nutrition, and changes over time.", - "ar": "الوزن يساعد في تتبع الصحة العامة والتغذية والتغيرات مع مرور الوقت." - }, - "bloodPressureDescription": { - "en": "Blood pressure reflects the force of blood against artery walls. It is shown as systolic/diastolic.", - "ar": "ضغط الدم يعكس قوة الدم على جدران الشرايين. يظهر كانقباضي/انبساطي." - }, - "temperatureDescription": { - "en": "Body temperature reflects how hot your body is and may change with infection or inflammation.", - "ar": "درجة حرارة الجسم تعكس مدى سخونة جسمك وقد تتغير مع العدوى أو الالتهاب." - }, - "heartRateDescriptionVital": { - "en": "Heart rate refers to the number of heart beats per minute.", - "ar": "معدل ضربات القلب يشير إلى عدد نبضات القلب في الدقيقة." - }, - "respiratoryRateDescription": { - "en": "Respiratory rate is the number of breaths taken per minute.", - "ar": "معدل التنفس هو عدد الأنفاس المأخوذة في الدقيقة." - }, - "bmiAdvice": { - "en": "Maintain a balanced diet and regular activity. If your BMI is high or low, consider consulting your doctor.", - "ar": "حافظ على نظام غذائي متوازن ونشاط منتظم. إذا كان مؤشر كتلة جسمك مرتفعًا أو منخفضًا، فكر في استشارة طبيبك." - }, - "heightAdvice": { - "en": "No action is needed unless your measurement looks incorrect. Update it during your next visit.", - "ar": "لا حاجة لاتخاذ أي إجراء إلا إذا بدا قياسك غير صحيح. قم بتحديثه في زيارتك القادمة." - }, - "weightAdvice": { - "en": "Monitor weight changes. Sudden gain or loss may require medical advice.", - "ar": "راقب تغيرات الوزن. الزيادة أو الخسارة المفاجئة قد تتطلب استشارة طبية." - }, - "bloodPressureAdvice": { - "en": "Keep tracking your blood pressure. High or low readings should be discussed with your doctor.", - "ar": "استمر في تتبع ضغط دمك. يجب مناقشة القراءات المرتفعة أو المنخفضة مع طبيبك." - }, - "temperatureAdvice": { - "en": "If you have a persistent fever or symptoms, contact your healthcare provider.", - "ar": "إذا كان لديك حمى مستمرة أو أعراض، اتصل بمقدم الرعاية الصحية." - }, - "heartRateAdvice": { - "en": "Track your heart rate trends. If you feel dizziness or chest pain, seek medical care.", - "ar": "تتبع اتجاهات معدل ضربات قلبك. إذا شعرت بدوار أو ألم في الصدر، اطلب الرعاية الطبية." - }, - "respiratoryRateAdvice": { - "en": "If you notice shortness of breath or abnormal breathing, seek medical advice.", - "ar": "إذا لاحظت ضيقًا في التنفس أو تنفسًا غير طبيعي، اطلب المشورة الطبية." - }, - "whatShouldIDoNext": { - "en": "What should I do next?", - "ar": "ماذا يجب أن أفعل بعد ذلك؟" - }, - "customizeDrinkCup": { - "en": "Customize your drink cup", - "ar": "قم بتخصيص كوب مشروبك" - }, - "tipsToStayHydrated": { - "en": "Tips to stay hydrated", - "ar": "نصائح للبقاء رطبًا" - }, - "drinkBeforeYouFeelThirsty": { - "en": "Drink before you feel thirsty", - "ar": "اشرب قبل أن تشعر بالعطش" - }, - "keepRefillableBottleNextToYou": { - "en": "Keep a refillable bottle next to you", - "ar": "احتفظ بزجاجة قابلة لإعادة التعبئة بجانبك" - }, - "trackYourDailyIntakeToStayMotivated": { - "en": "Track your daily intake to stay motivated", - "ar": "تتبع كمية الماء اليومية للحفاظ على الحافز" - }, - "chooseSparklingWaterInsteadOfSoda": { - "en": "Choose sparkling water instead of soda", - "ar": "اختر الماء الفوار بدلاً من الصودا" - }, - "switchCup": { - "en": "Switch Cup", - "ar": "تبديل الكوب" - }, - "plainWater": { - "en": "Plain Water", - "ar": "ماء عادي" - }, - "yourGoal": { - "en": "Your Goal", - "ar": "هدفك" - }, - "remaining": { - "en": "Remaining", - "ar": "المتبقي" - }, - "hydrationStatus": { - "en": "Hydration Status", - "ar": "حالة الترطيب" - }, - "areYouSureYouWantToCancelAllWaterReminders": { - "en": "Are you sure you want to cancel all water reminders?", - "ar": "هل أنت متأكد أنك تريد إلغاء جميع تذكيرات الماء؟" - }, - "remindersSet": { - "en": "Reminders Set!", - "ar": "تم ضبط التذكيرات!" - }, - "dailyWaterRemindersScheduledAt": { - "en": "Daily water reminders scheduled at:", - "ar": "تم جدولة تذكيرات الماء اليومية في:" - }, - "waterConsumption": { - "en": "Water Consumption", - "ar": "استهلاك المياه" - }, - "selectNumberOfReminders": { - "en": "Select Number of Reminders", - "ar": "حدد عدد التذكيرات" - }, - "h2oSettings": { - "en": "H20 Settings", - "ar": "إعدادات H20" - }, - "settingsSavedSuccessfully": { - "en": "Settings saved successfully", - "ar": "تم حفظ الإعدادات بنجاح" - }, - "yourName": { - "en": "Your Name", - "ar": "اسمك" - }, - "ageYears": { - "en": "Age (11-120) yrs", - "ar": "العمر (11-120) سنة" - }, - "numberOfRemindersInADay": { - "en": "Number of reminders in a day", - "ar": "عدد التذكيرات في اليوم" - }, - "medications": { - "en": "Medications", - "ar": "الأدوية" - }, - "someRemarksAboutPrescription": { - "en": "some remarks about the prescription will be here", - "ar": "ستجدون هنا بعض الملاحظات حول الوصفة الطبية" - }, - "notifyMeBeforeConsumptionTime": { - "en": "Notify me before the consumption time", - "ar": "أبلغني قبل وقت الاستهلاك" - }, - "noMedicationsToday": { - "en": "No medications today", - "ar": "لا أدوية اليوم" - }, - "reminders": { - "en": "Reminders", - "ar": "تذكيرات" - }, - "reminderAddedToCalendar": { - "en": "Reminder added to calendar ✅", - "ar": "تمت إضافة تذكير إلى التقويم ✅" - }, - "errorWhileSettingCalendar": { - "en": "Error while setting calendar: {error}", - "ar": "حدث خطأ أثناء ضبط التقويم:{error}" - }, - "instructions": { - "en": "Instructions", - "ar": "التعليمات" - }, - "requests": { - "en": "Requests", - "ar": "الطلبات" - }, - "thisWeek": { - "en": "This Week", - "ar": "هذا الأسبوع" - }, - "lastMonth": { - "en": "Last Month", - "ar": "الشهر الماضي" - }, - "lastSixMonths": { - "en": "Last 6 Months", - "ar": "آخر 6 أشهر" - }, - "selectTime": { - "en": "Select Time", - "ar": "حدد الوقت" - }, - "pleaseWaitYouWillBeCalledForVitalSigns": { - "en": "Please wait! you will be called for vital signs", - "ar": "يرجى الانتظار! سيتم استدعاؤك لقياس العلامات الحيوية" - }, - "pleaseVisitRoomForVitalSigns": { - "en": "Please visit Room {roomNumber} for vital signs", - "ar": "يرجى زيارة الغرفة {roomNumber} لقياس العلامات الحيوية" - }, - "pleaseVisitRoomToTheDoctor": { - "en": "Please visit Room {roomNumber} to the Doctor", - "ar": "يرجى زيارة الغرفة {roomNumber} لمقابلة الطبيب" - }, - "erOnlineCheckInRequest": { - "en": "ER Online Check-In Request", - "ar": "طلب تسجيل الوصول عبر الإنترنت لقسم الطوارئ" - }, - "indoor": { - "en": "Indoor", - "ar": "داخلي" - }, - "navigation": { - "en": "Navigation", - "ar": "الملاحة" - }, - "health": { - "en": "Health", - "ar": "الصحة" - }, - "calculators": { - "en": "Calculators", - "ar": "الحاسبات" - }, - "converters": { - "en": "Converters", - "ar": "المحولات" - }, - "guide": { - "en": "Guide", - "ar": "الدليل" - }, - "liveCareServiceDesc": { - "en": "Get medical advice with a specialist doctor Via a video call", - "ar": "احصل على استشارة طبية من طبيب متخصص عبر مكالمة فيديو" - }, - "bloodGroup": { - "en": "Blood: {bloodType}", - "ar": "فصيلة الدم: {bloodType}" - }, - "medicalServices": { - "en": "Medical Services", - "ar": "الخدمات الطبية" - }, - "insuranceAndPayments": { - "en": "Insurance & Payments", - "ar": "التأمين والمدفوعات" - }, - "trackerAndOthers": { - "en": "Tracker & Others", - "ar": "المتتبع وأخرى" - }, - "bmi": { - "en": "BMI", - "ar": "مؤشر كتلة الجسم" - }, - "yesPleaseINeedHelp": { - "en": "Yes, Please I need help", - "ar": "نعم، من فضلك أريد المساعدة" - }, - "aiOverView": { - "en": "AI Overview", - "ar": "AI ملخص" - }, - "generateAiAnalysis": { - "en": "Generate AI analysis for this order", - "ar": "قم بإجراء تحليل لهذا الطلب AI" - }, - "aiAnalysis": { - "en": "AI Analysis", - "ar": "AI تحليل" - }, - "prediction": { - "en": "Prediction", - "ar": "تنبؤ" - }, - "prevention": { - "en": "Prevention", - "ar": "وقاية" - }, - "disclaimer": { - "en": "Disclaimer", - "ar": "تنصل" - }, - "thisAboveInfo": { - "en": "The above information is generated by AI based on your lab results and is intended for informational purposes only. It should not be considered a medical diagnosis or treatment plan. Always consult with your healthcare provider for personalized medical advice and before making any health-related decisions.", - "ar": "المعلومات المذكورة أعلاه مُولّدة بواسطة AI بناءً على نتائج تحاليلك المخبرية، وهي لأغراض إعلامية فقط. لا ينبغي اعتبارها تشخيصًا طبيًا أو خطة علاجية. استشر طبيبك دائمًا للحصول على نصيحة طبية مُخصصة قبل اتخاذ أي قرارات تتعلق بصحتك." - }, - "aiDisclaimer": { - "en": "Your lab result data will be securely shared with our AI Analyzer for analysis. This helps provide personalized health insights. Do you want to proceed?", - "ar": "سيتم مشاركة بيانات نتائج تحاليلك المخبرية بشكل آمن مع خدمة الذكاء الاصطناعي لدينا لتحليلها. يساعد هذا في تقديم رؤى صحية مُخصصة. هل ترغب في المتابعة؟" - }, - "consent": { - "en": "Consent", - "ar": "موافقة" - }, - "bmiNormalDescription": { - "en": "Your BMI is within the healthy range. Continue a balanced diet, regular physical activity, and routine checkups to maintain good health. Monitor any significant changes over time.", - "ar": "مؤشر كتلة جسمك ضمن المعدل الصحي. استمر في اتباع نظام غذائي متوازن، وممارسة النشاط البدني بانتظام، وإجراء الفحوصات الدورية للحفاظ على صحة جيدة. راقب أي تغييرات ملحوظة مع مرور الوقت." - }, - "bmiUnderweightDescription": { - "en": "BMI suggests you are underweight. Consider increasing calorie intake with nutrient-dense foods, include resistance training to build muscle, and consult a healthcare professional to check for underlying causes.", - "ar": "يشير مؤشر كتلة الجسم إلى أنك تعاني من نقص الوزن. لذا، يُنصح بزيادة السعرات الحرارية المتناولة من خلال تناول الأطعمة الغنية بالعناصر الغذائية، وممارسة تمارين المقاومة لبناء العضلات، واستشارة أخصائي رعاية صحية للتحقق من وجود أسباب كامنة." - }, - "bmiOverweightDescription": { - "en": "BMI suggests overweight. It is advised to aim for gradual, sustainable weight loss through moderate calorie reduction, regular physical activity, and healthy food choices. Consult your doctor before making any major lifestyle changes.", - "ar": "يشير مؤشر كتلة الجسم إلى زيادة الوزن. لذا، يُنصح بالسعي إلى إنقاص الوزن تدريجياً وبشكل مستدام من خلال تقليل السعرات الحرارية بشكل معتدل، وممارسة النشاط البدني بانتظام، واختيار الأطعمة الصحية. استشر طبيبك قبل إجراء أي تغييرات جذرية في نمط حياتك." - }, - "caloriesMaintenanceDescription": { - "en": "Estimated daily calories to maintain your current weight based on your activity level and metabolic rate. Use this as a baseline: slightly increase for muscle gain or slightly decrease for gradual weight loss. Monitor progress and adjust every 2–4 weeks.", - "ar": "السعرات الحرارية اليومية المُقدَّرة للحفاظ على وزنك الحالي بناءً على مستوى نشاطك ومعدل الأيض لديك. استخدم هذه الكمية كخط أساس: زدها قليلاً لزيادة الكتلة العضلية، أو قللها قليلاً لإنقاص الوزن تدريجياً. تابع تقدمك وعدّل الخطة كل أسبوعين إلى أربعة أسابيع." - }, - "caloriesModerateDeficitDescription": { - "en": "A moderate calorie reduction plan designed for steady, sustainable weight loss (typically 0.25 to 0.5 kg per week). Combine with resistance training and adequate protein to preserve muscle mass. Avoid sharp calorie drops and consult a professional if you have medical conditions.", - "ar": "نظام غذائي معتدل لتقليل السعرات الحرارية مصمم لإنقاص الوزن بشكل ثابت ومستدام (عادةً من 0.25 إلى 0.5 كيلوغرام أسبوعيًا). يُنصح بدمجه مع تمارين المقاومة وتناول كمية كافية من البروتين للحفاظ على الكتلة العضلية. تجنب التخفيضات الحادة في السعرات الحرارية واستشر طبيبًا مختصًا إذا كنت تعاني من أي حالة صحية." - }, - "caloriesAggressiveDeficitDescription": { - "en": "A large calorie reduction that may produce faster weight loss but can be hard to sustain and increase risk of nutrient deficiencies, fatigue, or muscle loss. Not recommended long-term; seek guidance from a healthcare or nutrition professional before continuing.", - "ar": "يؤدي خفض السعرات الحرارية بشكل كبير إلى فقدان الوزن بشكل أسرع، ولكنه قد يصعب الاستمرار عليه ويزيد من خطر نقص العناصر الغذائية والإرهاق وفقدان الكتلة العضلية. لا يُنصح باتباعه على المدى الطويل؛ استشر طبيبًا أو أخصائي تغذية قبل الاستمرار." - }, - "bodyFatEssentialDescription": { - "en": "Your body fat percentage is in the essential/athletic range. This level is typical for athletes and indicates very low body fat. While this may be optimal for performance, ensure you maintain adequate nutrition and hormone function. Consult a healthcare professional if you experience fatigue, hormonal issues, or other health concerns.", - "ar": "نسبة الدهون في جسمك ضمن النطاق الأساسي/الرياضي. هذا المستوى شائع لدى الرياضيين ويشير إلى انخفاض نسبة الدهون في الجسم. مع أن هذا قد يكون مثاليًا للأداء، تأكد من الحفاظ على تغذية سليمة ووظائف هرمونية متوازنة. استشر طبيبًا إذا شعرت بالتعب، أو واجهت مشاكل هرمونية، أو أي مخاوف صحية أخرى." - }, - "bodyFatFitnessDescription": { - "en": "Your body fat percentage is in the fitness range. This indicates a healthy level of body fat associated with good physical conditioning. Maintain your current lifestyle habits including regular exercise and balanced nutrition to sustain this healthy range.", - "ar": "نسبة الدهون في جسمك ضمن النطاق الصحي. وهذا يدل على مستوى صحي من الدهون في الجسم يرتبط بلياقة بدنية جيدة. حافظ على نمط حياتك الحالي، بما في ذلك ممارسة الرياضة بانتظام واتباع نظام غذائي متوازن، للحفاظ على هذا المستوى الصحي." - }, - "bodyFatAverageDescription": { - "en": "Your body fat percentage is in the average/acceptable range. This is considered a healthy range for general population. To improve body composition, consider incorporating strength training, cardiovascular exercise, and a balanced diet. Focus on gradual, sustainable changes for long-term health.", - "ar": "نسبة الدهون في جسمك ضمن المعدل الطبيعي/المقبول، وهي نسبة تُعتبر صحية لعموم الناس. لتحسين تكوين جسمك، يُنصح بممارسة تمارين القوة، وتمارين القلب والأوعية الدموية، واتباع نظام غذائي متوازن. ركّز على التغييرات التدريجية والمستدامة للحفاظ على صحتك على المدى الطويل." - }, - "bodyFatObeseDescription": { - "en": "Your body fat percentage is above the recommended healthy range. This may increase health risks including cardiovascular disease, diabetes, and joint problems. Consider consulting a healthcare provider or registered dietitian to develop a personalized plan that includes balanced nutrition, regular physical activity, and lifestyle modifications for sustainable weight management.", - "ar": "نسبة الدهون في جسمك أعلى من المعدل الصحي الموصى به. قد يزيد هذا من المخاطر الصحية، بما في ذلك أمراض القلب والأوعية الدموية، والسكري، ومشاكل المفاصل. يُنصح باستشارة طبيب أو أخصائي تغذية معتمد لوضع خطة علاجية شخصية تشمل التغذية المتوازنة، والنشاط البدني المنتظم، وتعديلات نمط الحياة لتحقيق إدارة مستدامة للوزن." - }, - "bmrNormalDescription": { - "en": "Your Basal Metabolic Rate (BMR) is within the expected range for your profile. BMR is the energy your body needs at rest to maintain vital functions (breathing, circulation, temperature). Use this value as the baseline for estimating total daily energy needs by applying an activity multiplier. Maintain a balanced diet and regular physical activity to support metabolic health.", - "ar": "معدل الأيض الأساسي لديك ضمن النطاق المتوقع لحالتك. معدل الأيض الأساسي هو الطاقة التي يحتاجها جسمك في حالة الراحة للحفاظ على وظائفه الحيوية (التنفس، الدورة الدموية، درجة الحرارة). استخدم هذه القيمة كأساس لتقدير إجمالي احتياجاتك اليومية من الطاقة من خلال تطبيق مُعامل النشاط. حافظ على نظام غذائي متوازن وممارسة النشاط البدني بانتظام لدعم صحة التمثيل الغذائي." - }, - "bmrLowDescription": { - "en": "Your BMR is lower than typical for your profile. Possible causes include lower lean muscle mass, age-related metabolic decline, or metabolic adaptation from prolonged calorie restriction. Consider focusing on resistance training to build/maintain muscle, ensure adequate protein and micronutrient intake, and consult a healthcare professional if this is unexpected.", - "ar": "معدل الأيض الأساسي لديك أقل من المعدل الطبيعي لحالتك. تشمل الأسباب المحتملة انخفاض كتلة العضلات، أو تراجع التمثيل الغذائي المرتبط بالتقدم في السن، أو التكيف الأيضي الناتج عن تقييد السعرات الحرارية لفترة طويلة. يُنصح بالتركيز على تمارين المقاومة لبناء العضلات والحفاظ عليها، والتأكد من تناول كميات كافية من البروتين والمغذيات الدقيقة، واستشارة أخصائي رعاية صحية إذا كان هذا الأمر غير متوقع." - }, - "bmrHighDescription": { - "en": "Your BMR is higher than average for your profile. This can reflect greater lean mass, younger age, or a naturally higher metabolic rate, meaning you burn more energy at rest. Use this information to tailor calorie targets: higher needs for maintenance or muscle gain, moderate deficit for weight loss. Seek medical advice if you notice rapid unexplained changes.", - "ar": "معدل الأيض الأساسي لديك أعلى من المتوسط ​​بالنسبة لحالتك. قد يعكس هذا زيادة في كتلة العضلات، أو صغر السن، أو ارتفاع معدل الأيض لديك بشكل طبيعي، مما يعني أنك تحرق طاقة أكبر أثناء الراحة. استخدم هذه المعلومات لتحديد احتياجاتك من السعرات الحرارية: احتياجات أعلى للحفاظ على الوزن أو بناء العضلات، ونقص معتدل في السعرات الحرارية لإنقاص الوزن. استشر طبيبك إذا لاحظت أي تغيرات سريعة غير مبررة." - }, - "ibwAtTargetDescription": { - "en": "Your weight is at the ideal target. Maintain your current habits — balanced diet and regular activity — to keep this.", - "ar": "وزنك في النطاق المثالي. حافظ على عاداتك الحالية — نظام غذائي متوازن ونشاط بدني منتظم — للاستمرار على هذا المستوى." - }, - "ibwBelowTargetDescription": { - "en": "You are below the ideal weight by {kg} kg. Aim to gradually increase weight with a modest calorie surplus, nutrient-dense foods, and resistance training.", - "ar": "أنتِ أقل من الوزن المثالي بمقدار {kg} كجم. يُنصح بزيادة الوزن تدريجيًا من خلال فائضٍ بسيط في السعرات الحرارية، وتناول أطعمة غنية بالعناصر الغذائية، مع ممارسة تمارين المقاومة." - }, - "ibwAboveTargetDescription": { - "en": "You are above the ideal weight by {kg} kg. Aim for a gradual, sustainable weight reduction through a moderate calorie deficit, increased activity, and balanced nutrition.", - "ar": "أنتِ أعلى من الوزن المثالي بمقدار {kg} كجم. يُنصح باتباع خفضٍ تدريجي ومستدام للوزن من خلال عجزٍ معتدل في السعرات الحرارية، وزيادة مستوى النشاط البدني، واتباع تغذية متوازنة." - }, - "ibwCloseToRangeDescription": { - "en": "Your weight is close to the ideal range. Maintain a balanced diet and regular activity; follow personalized advice from a healthcare professional if needed.", - "ar": "وزنك قريب من النطاق المثالي. حافظ على نظام غذائي متوازن ونشاط بدني منتظم، مع اتباع إرشادات شخصية من مختص صحي عند الحاجة." - }, - "ibwUnderweightDescription": { - "en": "You are below the ideal weight by {kg} kg. Focus on increasing calorie intake with nutrient-dense foods, prioritize protein and resistance training to build healthy mass, and consider consulting a healthcare professional.", - "ar": "أنت أقل من الوزن المثالي بمقدار {kg} كجم. ركّز على زيادة السعرات الحرارية من خلال أطعمة غنية بالعناصر الغذائية، وأعط الأولوية للبروتين وتمارين المقاومة لبناء كتلة صحية، مع اتباع إرشادات شخصية من مختص صحي." - }, - "ibwUnderweightGenericDescription": { - "en": "You appear underweight compared to the ideal. Consider increasing calorie intake with nutrient-dense foods and resistance training; seek professional guidance if needed.", - "ar": "يبدو أنكِ أقل من الوزن المثالي. يُنصح بزيادة السعرات الحرارية من خلال أطعمة غنية بالعناصر الغذائية وممارسة تمارين المقاومة؛ مع الحصول على استشارة مختص صحي عند الحاجة." - }, - "ibwOverweightDescription": { - "en": "You are above the ideal weight by {kg} kg. Aim for a gradual, sustainable weight loss strategy — moderate calorie deficit, regular physical activity, and balanced nutrition. Consult a professional before major changes.", - "ar": "أنت أعلى من الوزن المثالي بمقدار {kg} كجم. يُنصح باتباع استراتيجية تدريجية ومستدامة لفقدان الوزن — من خلال عجزٍ معتدل في السعرات الحرارية، وممارسة نشاط بدني منتظم، وتغذية متوازنة. يُفضّل استشارة مختص صحي قبل إجراء تغييرات كبيرة." - }, - "ibwOverweightGenericDescription": { - "en": "You appear above the ideal weight. Consider a gradual, sustainable calorie deficit combined with activity and balanced nutrition; consult a professional if needed.", - "ar": "يبدو أنك أعلى من الوزن المثالي. يُنصح باتباع عجزٍ تدريجي ومستدام في السعرات الحرارية مع ممارسة النشاط البدني واتباع تغذية متوازنة؛ مع الحصول على استشارة مختص صحي عند الحاجة." - }, - "dietVeryLowCarbsDescription": { - "en": "Very low‑carb (ketogenic) approach: minimal carbohydrates, higher fat and moderate protein. May support rapid weight loss and improved blood sugar control for some, but can be hard to sustain and may cause nutrient gaps. Monitor hydration/electrolytes and consult a professional for long‑term use.", - "ar": "نهج منخفض الكربوهيدرات جدًا (الكيتوني): تقليل الكربوهيدرات إلى الحد الأدنى مع زيادة الدهون وبروتين معتدل. قد يساعد على فقدان الوزن بسرعة وتحسين التحكم في سكر الدم لدى بعض الأشخاص، لكنه قد يكون صعب الاستمرار عليه وقد يسبب نقصًا في بعض العناصر الغذائية. يجب مراقبة الترطيب ، والحصول على استشارة مختص صحي عند استخدامه لفترة طويلة." - }, - "dietLowCarbsDescription": { - "en": "Low‑carb, higher‑protein plan: reduced carbohydrates with increased protein to support satiety and muscle maintenance. Helpful for weight management and glycemic control when balanced with vegetables and healthy fats. Ensure adequate fiber and micronutrients.", - "ar": "خطة منخفضة الكربوهيدرات وعالية البروتين: تقليل الكربوهيدرات مع زيادة البروتين لدعم الشعور بالشبع والحفاظ على الكتلة العضلية. مفيدة لإدارة الوزن وضبط سكر الدم عند موازنتها مع الخضروات والدهون الصحية. احرص على الحصول على كمية كافية من الألياف والعناصر الدقيقة (الفيتامينات والمعادن)." - }, - "dietModerateCarbsDescription": { - "en": "Moderate carbohydrate intake with balanced protein and fats: provides steady energy for daily activity and exercise while allowing flexibility. Suitable for many people aiming for sustainable weight management and performance.", - "ar": "تناول معتدل للكربوهيدرات مع توازن في البروتين والدهون: يوفر طاقة مستقرة للأنشطة اليومية والتمارين مع قدر من المرونة. مناسب لكثير من الأشخاص الذين يسعون لإدارة وزن مستدامة وتحسين الأداء." - }, - "dietUSDAGuidelinesDescription": { - "en": "USDA‑based balanced pattern: emphasizes fruits, vegetables, whole grains, lean proteins, and limited added sugars and saturated fats. Evidence‑based framework for general health, nutrient adequacy, and chronic disease prevention.", - "ar": "نمط متوازن مستند إلى (USDA): يركز على الفواكه والخضروات والحبوب الكاملة والبروتينات قليلة الدهن، مع الحد من السكريات المضافة والدهون المشبعة. يُعد إطارًا قائمًا على الأدلة لدعم الصحة العامة، وكفاية العناصر الغذائية، والوقاية من الأمراض المزمنة." - }, - "dietZoneDietDescription": { - "en": "Zone Diet (~40% carbs / 30% protein / 30% fat): emphasizes hormonal balance and portion control. May improve body composition and energy for some, but requires planning; personalize with a nutrition professional.", - "ar": "حمية الزون (~40٪ كربوهيدرات / 30٪ بروتين / 30٪ دهون): تركز على التوازن الهرموني وضبط الحصص الغذائية. قد تُحسّن تركيب الجسم ومستوى الطاقة لدى بعض الأشخاص، لكنها تتطلب تخطيطًا جيدًا؛ ويُفضّل تخصيصها بالتعاون مع مختص تغذية." - }, - "contextDependent": { - "en": "Context Dependent", - "ar": "يعتمد السياق" - }, - "calculatedValue": { - "en": "Calculated Value", - "ar": "القيمة المحسوبة" - }, - "calculationFormula": { - "en": "Calculation Formula", - "ar": "صيغة الحساب" - }, - "confirmYourLocation": { - "en": "Confirm your location", - "ar": "قم بتأكيد موقعك" - }, - "confirmYourLocationDesc": { - "en": "Please confirm your current location to show appropriate directions.", - "ar": "يرجى تأكيد موقعك الحالي لعرض الاتجاهات المناسبة." - }, - "insideHospital": { - "en": "I am inside the hospital", - "ar": "أنا داخل المستشفى" - }, - "outsideHospital": { - "en": "I am outside the hospital", - "ar": "أنا خارج المستشفى" - }, - "servicePriceList": { - "en": "Service Price List", - "ar": "قائمة أسعار الخدمات" - }, - "servicePriceListDesc": { - "en": "The service price list below shows the fees for health services provided to patients on a cash payment basis. Regarding services covered by insurance, insurance coverage will be applied, eligibility verified, and co-payment percentages calculated according to the terms of the insurance policy and the approved benefit schedule for each insurance company.", - "ar": "توضح قائمة أسعار الخدمات أدناه رسوم الخدمات الصحية المقدمة للمرضى بنظام الدفع النقدي. أما فيما يتعلق بالخدمات المشمولة بالتأمين، فسيتم تطبيق التغطية التأمينية والتحقق من الأهلية واحتساب نسب التحمل وفقًا لشروط وثيقة التأمين وجدول المنافع المعتمد لكل شركة تأمين." - }, - "servicePriceListRights": { - "en": "The patient is entitled to a free follow-up within 14 days of the first visit", - "ar": "يحق للمريض الحصول على متابعة مجانية في غضون 14 يومًا من الزيارة الأولى" - }, - "serviceName": { - "en": "Service Name", - "ar": "اسم الخدمة" - }, - "noFreeSlot": { - "en": "There are no appointments available on the selected date. Please choose another date or try again later.", - "ar": "لا توجد مواعيد متاحة في التاريخ المحدد. يرجى اختيار تاريخ آخر أو إعادة المحاولة لاحقاً." - }, - "noThanksIKnowTheClinic": { - "en": "No, thanks. I know the clinic.", - "ar": "لا، شكراً. أنا أعرف العيادة." - }, - "unableToSendOTP": { - "en": "Unable to send One-Time Password", - "ar": "تعذر إرسال رمز التحقق لمرة واحدة" - }, - "loadingAIAnalysis": { - "en": "Analysing your lab results, Please be patient and let the AI do the magic, This might take some time.", - "ar": "جارٍ تحليل نتائج المختبر، يرجى التحلي بالصبر والسماح للذكاء الاصطناعي بالقيام بالمهمة، قد يستغرق هذا بعض الوقت." - }, - "symptoms": { - "en": "Symptoms", - "ar": "أعراض" - }, - "insuranceInActive": { - "en": "Insurance Inactive", - "ar": "التأمين غير نشط" - }, - "insuranceInActiveContactSupport": { - "en": "You have a valid insurance but it is currently inactive in HMG. Please contact HMG customer support to activate it.", - "ar": "لديك تأمين ساري المفعول، ولكنه غير مُفعّل حاليًا في مجموعة حبيب الطبية. يُرجى التواصل مع خدمة عملاء مجموعة حبيب الطبية." - }, - "updateAppNow": { - "en": "Update App Now", - "ar": "تحديث التطبيق الآن" - }, - "Dr": { - "en": "Dr.", - "ar": "الدكتور." - }, - "reschedulingAppo": { - "en": "Rescheduling Appointment, Please wait...", - "ar": "إعادة جدولة الموعد، يرجى الانتظار..." - }, - "invalidEligibility": { - "en": "You cannot make online payment because you are not eligible to use the provided service.", - "ar": "لا يمكنك إجراء الدفع عبر الإنترنت لأنك غير مؤهل لاستخدام الخدمة المقدمة." - }, - "invalidInsurance": { - "en": "You cannot make online payment because you do not have a valid insurance.", - "ar": "لا يمكنك إجراء الدفع عبر الإنترنت لأنه ليس لديك تأمين صالح." - }, - "continueCash": { - "en": "Continue as cash", - "ar": "متابعة الدفع نقدًا" - }, - "timeFor": { - "en": "Time For", - "ar": "الوقت" - }, - "hmgPolicies": { - "en": "HMG Policies", - "ar": "سياسات مجموعة الحبيب الطبية" - }, - "darkMode": { - "en": "Dark Mode", - "ar": "المظهر الداكن" - }, - "generateAiAnalysisResult": { - "en": "Generate AI analysis for this result", - "ar": "قم بإجراء تحليل لهذا المختبر AI" - } -} \ No newline at end of file diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index 99f62aad..6ad7b7ce 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -234,6 +234,7 @@ class ApiConsts { // ************ static values for Api **************** static final double appVersionID = 20.3; + // static final double appVersionID = 50.7; static final int appChannelId = 3; static final String appIpAddress = "10.20.10.20"; @@ -777,8 +778,7 @@ var GET_CUSTOMER_INFO = "VerifyCustomer"; //Pharmacy -var GET_PHARMACY_CATEGORISE = - 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id=0'; +var GET_PHARMACY_CATEGORISE = 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id=0'; var GET_OFFERS_CATEGORISE = 'discountcategories'; var GET_OFFERS_PRODUCTS = 'offerproducts/'; var GET_CATEGORISE_PARENT = 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id='; diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 3f9327fc..93901497 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -258,12 +258,12 @@ extension EmailValidator on String { style: TextStyle(color: color ?? AppColors.blackColor, fontSize: 17.f, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal, fontFamily: isEnglishOnly ? "Poppins" : getIt.get().getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins'), ); - Widget toText18({Color? color, FontWeight? weight, bool isBold = false, bool isCenter = false, int? maxlines, TextOverflow? textOverflow}) => Text( + Widget toText18({Color? color, FontWeight? weight, bool isBold = false, bool isCenter = false, int? maxlines, TextOverflow? textOverflow, bool isEnglishOnly = false,}) => Text( maxLines: maxlines, textAlign: isCenter ? TextAlign.center : null, this, overflow: textOverflow, - style: TextStyle(fontSize: 18.f, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal), color: color ?? AppColors.blackColor, letterSpacing: -0.4), + style: TextStyle(fontSize: 18.f, fontWeight: weight ?? (isBold ? FontWeight.bold : FontWeight.normal), color: color ?? AppColors.blackColor, letterSpacing: -0.4, fontFamily: (isEnglishOnly ? "Poppins" : getIt.get().getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins'),), ); Widget toText19({Color? color, bool isBold = false}) => Text( diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart index 4dd103b8..676a299a 100644 --- a/lib/features/book_appointments/book_appointments_view_model.dart +++ b/lib/features/book_appointments/book_appointments_view_model.dart @@ -536,6 +536,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { clearSearchFilters(); getFiltersFromDoctorList(); _groupDoctorsList(); + setIsNearestAppointmentSelected(true); notifyListeners(); if (onSuccess != null) { onSuccess(apiResponse); diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 2ba5dbc4..73a18102 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1578,5 +1578,6 @@ abstract class LocaleKeys { static const hmgPolicies = 'hmgPolicies'; static const darkMode = 'darkMode'; static const generateAiAnalysisResult = 'generateAiAnalysisResult'; + static const ratings = 'ratings'; } diff --git a/lib/presentation/appointments/widgets/appointment_card.dart b/lib/presentation/appointments/widgets/appointment_card.dart index 89a18bf5..210de466 100644 --- a/lib/presentation/appointments/widgets/appointment_card.dart +++ b/lib/presentation/appointments/widgets/appointment_card.dart @@ -161,9 +161,13 @@ class AppointmentCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - (isLoading ? 'John Doe' : "${patientAppointmentHistoryResponseModel.doctorTitle} ${patientAppointmentHistoryResponseModel.doctorNameObj!}") - .toText16(isBold: true, maxlines: 1) - .toShimmer2(isShow: isLoading), + Row( + children: [ + (isLoading ? 'Dr' : "${patientAppointmentHistoryResponseModel.doctorTitle}").toText16(isBold: true, maxlines: 1), + (isLoading ? 'John Doe' : " ${patientAppointmentHistoryResponseModel.doctorNameObj!.truncate(20)}") + .toText16(isBold: true, maxlines: 1, isEnglishOnly: !Utils.isArabicText(patientAppointmentHistoryResponseModel.doctorNameObj ?? "John Doe")) + ], + ).toShimmer2(isShow: isLoading), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, diff --git a/lib/presentation/appointments/widgets/appointment_doctor_card.dart b/lib/presentation/appointments/widgets/appointment_doctor_card.dart index 298e8732..ef8c76ee 100644 --- a/lib/presentation/appointments/widgets/appointment_doctor_card.dart +++ b/lib/presentation/appointments/widgets/appointment_doctor_card.dart @@ -16,11 +16,7 @@ import 'dart:ui' as ui; class AppointmentDoctorCard extends StatelessWidget { const AppointmentDoctorCard( - {super.key, - required this.patientAppointmentHistoryResponseModel, - required this.onRescheduleTap, - required this.onCancelTap, - required this.onAskDoctorTap, this.renderWidgetForERDisplay = false}); + {super.key, required this.patientAppointmentHistoryResponseModel, required this.onRescheduleTap, required this.onCancelTap, required this.onAskDoctorTap, this.renderWidgetForERDisplay = false}); final PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel; final VoidCallback onRescheduleTap; @@ -82,7 +78,7 @@ class AppointmentDoctorCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true), + patientAppointmentHistoryResponseModel.doctorNameObj!.toText16(isBold: true, isEnglishOnly: !Utils.isArabicText(patientAppointmentHistoryResponseModel.doctorNameObj ?? "")), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, @@ -107,20 +103,16 @@ class AppointmentDoctorCard extends StatelessWidget { richText: "${DateUtil.formatDateToDate(DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false)} ${DateUtil.formatDateToTimeLang( DateUtil.convertStringToDate(patientAppointmentHistoryResponseModel.appointmentDate), false, - )}".toText10(isEnglishOnly: true), + )}" + .toText10(isEnglishOnly: true), ), ), AppCustomChipWidget( labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w), - icon: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! - ? AppAssets.walkin_appointment_icon - : AppAssets.small_livecare_icon, + icon: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppAssets.walkin_appointment_icon : AppAssets.small_livecare_icon, iconColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.textColor : Colors.white, - labelText: patientAppointmentHistoryResponseModel.isLiveCareAppointment! - ? LocaleKeys.livecare.tr(context: context) - : LocaleKeys.walkin.tr(context: context), - backgroundColor: - !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.greyColor : AppColors.successColor, + labelText: patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? LocaleKeys.livecare.tr(context: context) : LocaleKeys.walkin.tr(context: context), + backgroundColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.greyColor : AppColors.successColor, textColor: !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? AppColors.textColor : Colors.white, ), ], @@ -166,20 +158,20 @@ class AppointmentDoctorCard extends StatelessWidget { : !patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? CustomButton( text: LocaleKeys.rebookSameDoctor.tr(), - onPressed: () { - onRescheduleTap(); - }, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 12.f, - fontWeight: FontWeight.w500, - borderRadius: 12.r, - padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), - height: 40.h, - icon: AppAssets.rebook_appointment_icon, - iconColor: AppColors.blackColor, - iconSize: 14.h, + onPressed: () { + onRescheduleTap(); + }, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 12.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), + height: 40.h, + icon: AppAssets.rebook_appointment_icon, + iconColor: AppColors.blackColor, + iconSize: 14.h, ) : SizedBox.shrink(); } else { diff --git a/lib/presentation/book_appointment/doctor_profile_page.dart b/lib/presentation/book_appointment/doctor_profile_page.dart index 9fb6ee1d..fdd1af0f 100644 --- a/lib/presentation/book_appointment/doctor_profile_page.dart +++ b/lib/presentation/book_appointment/doctor_profile_page.dart @@ -102,7 +102,7 @@ class DoctorProfilePage extends StatelessWidget { children: [ Utils.buildSvgWithAssets(icon: AppAssets.doctor_profile_rating_icon, width: 48.w, height: 48.h, fit: BoxFit.contain, applyThemeColor: false), SizedBox(height: 16.h), - "Ratings".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + LocaleKeys.ratings.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), bookAppointmentsViewModel.doctorsProfileResponseModel.decimalDoctorRate .toString() .toText16(isBold: true, color: AppColors.textColor, isUnderLine: true, decorationColor: AppColors.textColor, fontFamily: "Poppins"), @@ -123,7 +123,7 @@ class DoctorProfilePage extends StatelessWidget { children: [ Utils.buildSvgWithAssets(icon: AppAssets.doctor_profile_reviews_icon, width: 48.w, height: 48.h, fit: BoxFit.contain, applyThemeColor: false), SizedBox(height: 16.h), - "Reviews".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + LocaleKeys.reviews.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), bookAppointmentsViewModel.doctorsProfileResponseModel.noOfPatientsRate .toString() .toText16(isBold: true, color: AppColors.textColor, isUnderLine: true, decorationColor: AppColors.textColor, fontFamily: "Poppins"), diff --git a/lib/presentation/book_appointment/select_doctor_page.dart b/lib/presentation/book_appointment/select_doctor_page.dart index 1fc9d9ad..7947fa05 100644 --- a/lib/presentation/book_appointment/select_doctor_page.dart +++ b/lib/presentation/book_appointment/select_doctor_page.dart @@ -46,7 +46,7 @@ class _SelectDoctorPageState extends State { void initState() { _scrollController = ScrollController(); scheduleMicrotask(() { - bookAppointmentsViewModel.setIsNearestAppointmentSelected(false); + bookAppointmentsViewModel.setIsNearestAppointmentSelected(true); if (bookAppointmentsViewModel.isLiveCareSchedule) { bookAppointmentsViewModel.getLiveCareDoctorsList(); } else { diff --git a/lib/presentation/book_appointment/widgets/appointment_calendar.dart b/lib/presentation/book_appointment/widgets/appointment_calendar.dart index 9124a16b..57a045cc 100644 --- a/lib/presentation/book_appointment/widgets/appointment_calendar.dart +++ b/lib/presentation/book_appointment/widgets/appointment_calendar.dart @@ -90,59 +90,64 @@ class _AppointmentCalendarState extends State { // ), SizedBox( height: 350.h, - child: SfCalendar( - controller: _calendarController, - minDate: DateTime.now(), - showNavigationArrow: true, - headerHeight: 60.h, - headerStyle: CalendarHeaderStyle( - backgroundColor: AppColors.scaffoldBgColor, - textAlign: TextAlign.start, - textStyle: TextStyle(fontSize: 18.f, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: AppColors.primaryRedColor, fontFamily: "Poppins"), - ), - viewHeaderStyle: ViewHeaderStyle( - backgroundColor: AppColors.scaffoldBgColor, - dayTextStyle: TextStyle(fontSize: 14.f, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: AppColors.textColor), - ), - view: CalendarView.month, - todayHighlightColor: Colors.transparent, - todayTextStyle: TextStyle(color: AppColors.textColor, fontWeight: FontWeight.bold), - selectionDecoration: ShapeDecoration( - color: AppColors.transparent, - shape: SmoothRectangleBorder( - borderRadius: BorderRadius.circular(10.r), - smoothness: 1, - side: BorderSide(color: AppColors.primaryRedColor, width: 1.5), + child: Localizations.override( + context: context, + locale: const Locale('en'), + child: SfCalendar( + controller: _calendarController, + minDate: DateTime.now(), + showNavigationArrow: true, + headerHeight: 60.h, + headerStyle: CalendarHeaderStyle( + backgroundColor: AppColors.scaffoldBgColor, + textAlign: TextAlign.start, + textStyle: TextStyle(fontSize: 18.f, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: AppColors.primaryRedColor, fontFamily: "Poppins"), ), - ), - cellBorderColor: AppColors.transparent, - dataSource: MeetingDataSource(_getDataSource()), - monthCellBuilder: (context, details) => Padding( - padding: EdgeInsets.all(12.h), - child: details.date.day.toString().toText14( - isCenter: true, - color: details.date == _calendarController.selectedDate ? AppColors.primaryRedColor : AppColors.textColor, - ), - ), - monthViewSettings: MonthViewSettings( - dayFormat: "EEE", - appointmentDisplayMode: MonthAppointmentDisplayMode.indicator, - showTrailingAndLeadingDates: false, - appointmentDisplayCount: 1, - monthCellStyle: MonthCellStyle( - textStyle: TextStyle(fontSize: 19.f), + viewHeaderStyle: ViewHeaderStyle( + backgroundColor: AppColors.scaffoldBgColor, + dayTextStyle: TextStyle(fontSize: 14.f, fontWeight: FontWeight.w600, letterSpacing: -0.46, color: AppColors.textColor, fontFamily: "Poppins"), ), + view: CalendarView.month, + todayHighlightColor: Colors.transparent, + todayTextStyle: TextStyle(color: AppColors.textColor, fontWeight: FontWeight.bold, fontFamily: "Poppins"), + selectionDecoration: ShapeDecoration( + color: AppColors.transparent, + shape: SmoothRectangleBorder( + borderRadius: BorderRadius.circular(10.r), + smoothness: 1, + side: BorderSide(color: AppColors.primaryRedColor, width: 1.5), + ), + ), + cellBorderColor: AppColors.transparent, + dataSource: MeetingDataSource(_getDataSource()), + monthCellBuilder: (context, details) => Padding( + padding: EdgeInsets.all(12.h), + child: details.date.day.toString().toText14( + isCenter: true, + color: details.date == _calendarController.selectedDate ? AppColors.primaryRedColor : AppColors.textColor, + isEnglishOnly: true, + ), + ), + monthViewSettings: MonthViewSettings( + dayFormat: "EEE", + appointmentDisplayMode: MonthAppointmentDisplayMode.indicator, + showTrailingAndLeadingDates: false, + appointmentDisplayCount: 1, + monthCellStyle: MonthCellStyle( + textStyle: TextStyle(fontSize: 19.f), + ), + ), + onTap: (CalendarTapDetails details) { + _calendarController.selectedDate = details.date; + _onDaySelected(details.date!); + }, ), - onTap: (CalendarTapDetails details) { - _calendarController.selectedDate = details.date; - _onDaySelected(details.date!); - }, ), ), SizedBox(height: 10.h), Transform.translate( offset: const Offset(0.0, -10.0), - child: selectedDateDisplay.toText16(weight: FontWeight.w500), + child: selectedDateDisplay.toText16(weight: FontWeight.w500, isEnglishOnly: true), ), //TODO: Add Next Day Span here dayEvents.isNotEmpty @@ -153,23 +158,23 @@ class _AppointmentCalendarState extends State { child: Wrap( direction: Axis.horizontal, alignment: WrapAlignment.start, - spacing: 6.h, - runSpacing: 6.h, - children: List.generate( - dayEvents.length, // Generate a large number of items to ensure scrolling - (index) => TimeSlotChip( - label: dayEvents[index].isoTime!, - isSelected: index == selectedButtonIndex, - onTap: () { - setState(() { - selectedButtonIndex = index; - selectedTime = dayEvents[index].isoTime!; - }); - }, + spacing: 6.h, + runSpacing: 6.h, + children: List.generate( + dayEvents.length, // Generate a large number of items to ensure scrolling + (index) => TimeSlotChip( + label: dayEvents[index].isoTime!, + isSelected: index == selectedButtonIndex, + onTap: () { + setState(() { + selectedButtonIndex = index; + selectedTime = dayEvents[index].isoTime!; + }); + }, + ), + ), + ), ), - ), - ), - ), ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noFreeSlot.tr(context: context)), @@ -179,7 +184,7 @@ class _AppointmentCalendarState extends State { isDisabled: dayEvents.isEmpty, onPressed: () async { if (appState.isAuthenticated) { - if(selectedTime == LocaleKeys.waitingAppointment.tr(context: context)){ + if (selectedTime == LocaleKeys.waitingAppointment.tr(context: context)) { bookAppointmentsViewModel.setWaitingAppointmentProjectID(bookAppointmentsViewModel.selectedDoctor.projectID!); bookAppointmentsViewModel.setWaitingAppointmentDoctor(bookAppointmentsViewModel.selectedDoctor); @@ -351,26 +356,20 @@ class TimeSlotChip extends StatelessWidget { side: BorderSide(color: isSelected ? AppColors.warningColorYellow : AppColors.borderOnlyColor.withOpacity(0.2), width: 1), ), ), - child: label.toText12( - color: isSelected ? AppColors.whiteColor : Colors.black87, - fontWeight: FontWeight.w500, - ), + child: label.toText12(color: isSelected ? AppColors.whiteColor : Colors.black87, fontWeight: FontWeight.w500, isEnglishOnly: true), ) : Container( padding: EdgeInsets.symmetric(horizontal: 14.h, vertical: 8.h), decoration: ShapeDecoration( - color: AppColors.whiteColor, - shape: SmoothRectangleBorder( - borderRadius: BorderRadius.circular(8.h), - smoothness: 1, - side: BorderSide(color: isSelected ? AppColors.primaryRedColor : AppColors.borderOnlyColor.withOpacity(0.2), width: 1), - ), - ), - child: label.toText12( - color: isSelected ? AppColors.primaryRedColor : AppColors.textColor, - fontWeight: FontWeight.w500, - ), - ), + color: AppColors.whiteColor, + shape: SmoothRectangleBorder( + borderRadius: BorderRadius.circular(8.h), + smoothness: 1, + side: BorderSide(color: isSelected ? AppColors.primaryRedColor : AppColors.borderOnlyColor.withOpacity(0.2), width: 1), + ), + ), + child: label.toText12(color: isSelected ? AppColors.primaryRedColor : AppColors.textColor, fontWeight: FontWeight.w500, isEnglishOnly: true), + ), ); } } diff --git a/lib/presentation/book_appointment/widgets/doctor_card.dart b/lib/presentation/book_appointment/widgets/doctor_card.dart index 6eecf5f8..02b2e55d 100644 --- a/lib/presentation/book_appointment/widgets/doctor_card.dart +++ b/lib/presentation/book_appointment/widgets/doctor_card.dart @@ -109,7 +109,7 @@ class DoctorCard extends StatelessWidget { : doctorsListResponseModel.speciality!.first) : "") .toString() - .toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor, maxLine: 2) + .toText12(fontWeight: FontWeight.w500, color: AppColors.textColor, maxLine: 2, isEnglishOnly: true) .toShimmer2(isShow: isLoading), ), SizedBox(width: 6.w), diff --git a/lib/presentation/home/widgets/welcome_widget.dart b/lib/presentation/home/widgets/welcome_widget.dart index 4ccc126a..21f01c8b 100644 --- a/lib/presentation/home/widgets/welcome_widget.dart +++ b/lib/presentation/home/widgets/welcome_widget.dart @@ -39,7 +39,7 @@ class WelcomeWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ - Flexible(child: name.toText16(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1, height: 1)), + Flexible(child: name.toText16(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1, height: 1, isEnglishOnly: true)), Icon(Icons.keyboard_arrow_down, size: 20, color: AppColors.greyTextColor), ], ), diff --git a/lib/presentation/insurance/widgets/patient_insurance_card.dart b/lib/presentation/insurance/widgets/patient_insurance_card.dart index 531341b5..2d3ba9ea 100644 --- a/lib/presentation/insurance/widgets/patient_insurance_card.dart +++ b/lib/presentation/insurance/widgets/patient_insurance_card.dart @@ -52,7 +52,7 @@ class PatientInsuranceCard extends StatelessWidget { children: [ SizedBox( width: MediaQuery.of(context).size.width * 0.4, - child: "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true, textOverflow: TextOverflow.clip)), + child: "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true, textOverflow: TextOverflow.clip, isEnglishOnly: true)), LocaleKeys.policyNumber.tr(namedArgs: {'number': insuranceCardDetailsModel.insurancePolicyNo ?? ''}, context: context).toText12(isBold: true, color: AppColors.lightGrayColor), ], ), diff --git a/lib/presentation/lab/lab_orders_page.dart b/lib/presentation/lab/lab_orders_page.dart index 15461659..bb2c3034 100644 --- a/lib/presentation/lab/lab_orders_page.dart +++ b/lib/presentation/lab/lab_orders_page.dart @@ -1 +1 @@ -import 'dart:async'; import 'dart:convert'; 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/appbar/collapsing_list_view.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 CollapsingListView( title: LocaleKeys.labResults.tr(context: context), search: () async { if (labProvider.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: labProvider.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; labProvider.filterLabReports(value); } } }, child: Consumer( builder: (context, labViewModel, child) { return SingleChildScrollView( physics: NeverScrollableScrollPhysics(), 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: () { labViewModel.setIsSortByClinic(true); }, backgroundColor: labViewModel.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, borderColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12.f, 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: () { labViewModel.setIsSortByClinic(false); }, backgroundColor: labViewModel.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, borderColor: labViewModel.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, textColor: labViewModel.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 ? Column( children: [ AppCustomChipWidget( labelText: selectedFilterText!, backgroundColor: AppColors.alertColor, textColor: AppColors.whiteColor, deleteIcon: AppAssets.close_bottom_sheet_icon, deleteIconColor: AppColors.whiteColor, deleteIconHasColor: true, onDeleteTap: () { selectedFilterText = ""; labProvider.filterLabReports(""); }, ), SizedBox(height: 8.h), ], ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available labViewModel.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (labViewModel.patientLabOrdersViewList.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: labViewModel.patientLabOrdersViewList.length, itemBuilder: (context, index) { final group = labViewModel.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( labViewModel.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: ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemBuilder: (cxt, index) { PatientLabOrdersResponseModel order = group[index]; 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: labViewModel.isSortByClinic ? (order.projectName ?? "") : (order.clinicDescription ?? ""), ), ], ), // 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: () { labViewModel.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), ], ).paddingOnly(top: 16, bottom: 16); }, separatorBuilder: (cxt, index) => Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), itemCount: group.length)) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (labViewModel.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: labViewModel.indexedCharacterForUniqueTest, details: labViewModel.uniqueTestsList, labViewModel: labViewModel, 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 'dart:convert'; 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/appbar/collapsing_list_view.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'; import 'dart:ui' as ui; 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 CollapsingListView( title: LocaleKeys.labResults.tr(context: context), search: () async { if (labProvider.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: labProvider.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; labProvider.filterLabReports(value); } } }, child: Consumer( builder: (context, labViewModel, child) { return SingleChildScrollView( physics: NeverScrollableScrollPhysics(), 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: () { labViewModel.setIsSortByClinic(true); }, backgroundColor: labViewModel.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, borderColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12.f, 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: () { labViewModel.setIsSortByClinic(false); }, backgroundColor: labViewModel.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, borderColor: labViewModel.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, textColor: labViewModel.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 ? Column( children: [ AppCustomChipWidget( labelText: selectedFilterText!, backgroundColor: AppColors.alertColor, textColor: AppColors.whiteColor, deleteIcon: AppAssets.close_bottom_sheet_icon, deleteIconColor: AppColors.whiteColor, deleteIconHasColor: true, onDeleteTap: () { selectedFilterText = ""; labProvider.filterLabReports(""); }, ), SizedBox(height: 8.h), ], ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available labViewModel.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (labViewModel.patientLabOrdersViewList.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: labViewModel.patientLabOrdersViewList.length, itemBuilder: (context, index) { final group = labViewModel.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( labViewModel.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: ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemBuilder: (cxt, index) { PatientLabOrdersResponseModel order = group[index]; 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!}"), isEnglishOnly: true, ), Directionality( textDirection: ui.TextDirection.ltr, child: AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), isEnglishOnly: true, )), AppCustomChipWidget( labelText: labViewModel.isSortByClinic ? (order.projectName ?? "") : (order.clinicDescription ?? ""), ), ], ), // 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: () { labViewModel.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), ], ).paddingOnly(top: 16, bottom: 16); }, separatorBuilder: (cxt, index) => Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), itemCount: group.length)) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (labViewModel.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: labViewModel.indexedCharacterForUniqueTest, details: labViewModel.uniqueTestsList, labViewModel: labViewModel, 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/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index f288af66..89843ea7 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -85,6 +85,8 @@ import '../../features/active_prescriptions/active_prescriptions_view_model.dart import '../prescriptions/prescription_detail_page.dart'; import 'widgets/medical_file_appointment_card.dart'; +import 'dart:ui' as ui; + class MedicalFilePage extends StatefulWidget { bool showBackIcon; @@ -784,11 +786,15 @@ class _MedicalFilePageState extends State { runSpacing: 4.w, children: [ AppCustomChipWidget(labelText: prescriptionVM.patientPrescriptionOrders[index].clinicDescription!), - AppCustomChipWidget( - icon: AppAssets.doctor_calendar_icon, - labelText: DateUtil.formatDateToDate( - DateUtil.convertStringToDate(prescriptionVM.patientPrescriptionOrders[index].appointmentDate), - false, + Directionality( + textDirection: ui.TextDirection.ltr, + child: AppCustomChipWidget( + icon: AppAssets.doctor_calendar_icon, + labelText: DateUtil.formatDateToDate( + DateUtil.convertStringToDate(prescriptionVM.patientPrescriptionOrders[index].appointmentDate), + false, + ), + isEnglishOnly: true, ), ), ], diff --git a/lib/presentation/medical_file/widgets/medical_file_appointment_card.dart b/lib/presentation/medical_file/widgets/medical_file_appointment_card.dart index 73dd1652..4c1a72b7 100644 --- a/lib/presentation/medical_file/widgets/medical_file_appointment_card.dart +++ b/lib/presentation/medical_file/widgets/medical_file_appointment_card.dart @@ -74,7 +74,7 @@ class MedicalFileAppointmentCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - (patientAppointmentHistoryResponseModel.doctorNameObj ?? "").toText14(isBold: true, maxlines: 1).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading), + (patientAppointmentHistoryResponseModel.doctorNameObj ?? "").toText14(isBold: true, maxlines: 1, isEnglishOnly: !Utils.isArabicText(patientAppointmentHistoryResponseModel.doctorNameObj ?? "")).toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading), (patientAppointmentHistoryResponseModel.clinicName ?? "") .toText12(maxLine: 1, fontWeight: FontWeight.w500, color: AppColors.greyTextColor) .toShimmer2(isShow: myAppointmentsViewModel.isMyAppointmentsLoading), diff --git a/lib/presentation/prescriptions/prescription_detail_page.dart b/lib/presentation/prescriptions/prescription_detail_page.dart index b9b5b789..ec2cd1a0 100644 --- a/lib/presentation/prescriptions/prescription_detail_page.dart +++ b/lib/presentation/prescriptions/prescription_detail_page.dart @@ -23,6 +23,8 @@ import 'package:open_filex/open_filex.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'dart:ui' as ui; + class PrescriptionDetailPage extends StatefulWidget { PrescriptionDetailPage({super.key, required this.prescriptionsResponseModel, required this.isFromAppointments}); @@ -124,11 +126,15 @@ class _PrescriptionDetailPageState extends State { spacing: 4.h, runSpacing: 4.h, children: [ - AppCustomChipWidget( - icon: AppAssets.doctor_calendar_icon, - labelText: DateUtil.formatDateToDate( - DateUtil.convertStringToDate(widget.prescriptionsResponseModel.appointmentDate), false), - labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.h), + Directionality( + textDirection: ui.TextDirection.ltr, + child: AppCustomChipWidget( + icon: AppAssets.doctor_calendar_icon, + labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(widget.prescriptionsResponseModel.appointmentDate), false), + isEnglishOnly: true + , + labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.h), + ), ), AppCustomChipWidget( labelText: widget.prescriptionsResponseModel.clinicDescription!, @@ -225,9 +231,7 @@ class _PrescriptionDetailPageState extends State { hasShadow: true, ), child: CustomButton( - text: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! - ? LocaleKeys.resendOrder.tr(context: context) - : LocaleKeys.prescriptionDeliveryError.tr(context: context), + text: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? LocaleKeys.resendOrder.tr(context: context) : LocaleKeys.prescriptionDeliveryError.tr(context: context), onPressed: () async { if (widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported!) { LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingPrescriptionDetails.tr(context: context)); @@ -239,16 +243,14 @@ class _PrescriptionDetailPageState extends State { }, backgroundColor: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.greyF7Color, borderColor: AppColors.successColor.withOpacity(0.01), - textColor: - widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? Colors.white : AppColors.textColor.withOpacity(0.35), + textColor: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? Colors.white : AppColors.textColor.withOpacity(0.35), fontSize: 16, fontWeight: FontWeight.w500, borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 50.h, icon: AppAssets.prescription_refill_icon, - iconColor: - widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? Colors.white : AppColors.textColor.withOpacity(0.35), + iconColor: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? Colors.white : AppColors.textColor.withOpacity(0.35), iconSize: 20.h, ).paddingSymmetrical(24.h, 24.h), ), diff --git a/lib/presentation/prescriptions/prescription_item_view.dart b/lib/presentation/prescriptions/prescription_item_view.dart index 38b96d37..c5cd50c2 100644 --- a/lib/presentation/prescriptions/prescription_item_view.dart +++ b/lib/presentation/prescriptions/prescription_item_view.dart @@ -47,7 +47,7 @@ class PrescriptionItemView extends StatelessWidget { fit: BoxFit.fill, ).toShimmer2(isShow: isLoading).circle(100), Expanded( - child: (isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].itemDescription!).toText16(isBold: true, maxlines: 2).toShimmer2(isShow: isLoading), + child: (isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].itemDescription!).toText16(isBold: true, maxlines: 2, isEnglishOnly: true).toShimmer2(isShow: isLoading), ), ], ).paddingSymmetrical(16.h, 0.h), @@ -78,7 +78,9 @@ class PrescriptionItemView extends StatelessWidget { children: [ Utils.buildSvgWithAssets(icon: AppAssets.prescription_remarks_icon, width: 18.h, height: 18.h), SizedBox(width: 9.h), - Expanded(child: "${LocaleKeys.remarks.tr(context: context)}: ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].remarks!}".toText10(isBold: true)), + Expanded( + child: "${LocaleKeys.remarks.tr(context: context)} ${isLoading ? "" : prescriptionVM.prescriptionDetailsList[index].remarks!}".toText10(isBold: true, isEnglishOnly: true), + ), ], ).paddingSymmetrical(16.h, 0.h), SizedBox(height: 14.h), @@ -95,7 +97,7 @@ class PrescriptionItemView extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.setReminder.tr(context: context).toText13(isBold: true), - "Notify me before the consumption time".toText10(color: AppColors.textColorLight), + "Notify me before the consumption time".toText10(color: AppColors.textColorLight, isEnglishOnly: true), ], ).toShimmer2(isShow: isLoading).expanded, Switch( diff --git a/lib/presentation/prescriptions/prescriptions_list_page.dart b/lib/presentation/prescriptions/prescriptions_list_page.dart index cd507d41..4eb297d5 100644 --- a/lib/presentation/prescriptions/prescriptions_list_page.dart +++ b/lib/presentation/prescriptions/prescriptions_list_page.dart @@ -24,6 +24,8 @@ import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; +import 'dart:ui' as ui; + class PrescriptionsListPage extends StatefulWidget { const PrescriptionsListPage({super.key}); @@ -213,8 +215,11 @@ class _PrescriptionsListPageState extends State { spacing: 6.h, runSpacing: 6.h, children: [ - AppCustomChipWidget( - labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(prescription.appointmentDate), false), + Directionality( + textDirection: ui.TextDirection.ltr, + child: AppCustomChipWidget( + labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(prescription.appointmentDate), false), isEnglishOnly: true, + ), ), AppCustomChipWidget( labelText: model.isSortByClinic ? prescription.name ?? "" : prescription.clinicDescription!, diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart index 2bd41f06..27f74826 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -378,7 +378,7 @@ class FamilyCardWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - "${profile.patientName}".toText18(isBold: true, weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1), + "${profile.patientName}".toText18(isBold: true, weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1, isEnglishOnly: true), AppCustomChipWidget( icon: AppAssets.file_icon, labelText: "${LocaleKeys.fileNo.tr(context: context)}: ${profile.responseId}", diff --git a/lib/presentation/radiology/radiology_orders_page.dart b/lib/presentation/radiology/radiology_orders_page.dart index a07face1..81aef5c7 100644 --- a/lib/presentation/radiology/radiology_orders_page.dart +++ b/lib/presentation/radiology/radiology_orders_page.dart @@ -24,6 +24,8 @@ import 'package:provider/provider.dart'; import '../../features/radiology/radiology_view_model.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'dart:ui' as ui; + class RadiologyOrdersPage extends StatefulWidget { const RadiologyOrdersPage({super.key}); @@ -289,10 +291,13 @@ class _RadiologyOrdersPageState extends State { AppCustomChipWidget( labelText: (order.description ?? '').toString(), ), - AppCustomChipWidget( - labelText: DateUtil.formatDateToDate( - (order.orderDate ?? order.appointmentDate), - false, + Directionality( + textDirection: ui.TextDirection.ltr, + child: AppCustomChipWidget( + labelText: DateUtil.formatDateToDate( + (order.orderDate ?? order.appointmentDate), + false, + ), isEnglishOnly: true, ), ), AppCustomChipWidget( diff --git a/lib/presentation/radiology/radiology_result_page.dart b/lib/presentation/radiology/radiology_result_page.dart index 7b3f11d4..02f30be5 100644 --- a/lib/presentation/radiology/radiology_result_page.dart +++ b/lib/presentation/radiology/radiology_result_page.dart @@ -20,6 +20,7 @@ import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:open_filex/open_filex.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'dart:ui' as ui; class RadiologyResultPage extends StatefulWidget { RadiologyResultPage({super.key, required this.patientRadiologyResponseModel}); @@ -52,6 +53,14 @@ class _RadiologyResultPageState extends State { Expanded( child: CollapsingListView( title: LocaleKeys.radiologyResult.tr(context: context), + viewImage: () { + if (radiologyViewModel.radiologyImageURL.isNotEmpty) { + Uri uri = Uri.parse(radiologyViewModel.radiologyImageURL); + launchUrl(uri, mode: LaunchMode.platformDefault, webOnlyWindowName: ""); + } else { + Utils.showToast("Radiology image not available"); + } + }, child: SingleChildScrollView( child: Padding( padding: EdgeInsets.symmetric(horizontal: 24.h), @@ -71,31 +80,34 @@ class _RadiologyResultPageState extends State { SizedBox(height: 16.h), // widget.patientRadiologyResponseModel.description!.toText16(isBold: true), SizedBox(height: 8.h), - widget.patientRadiologyResponseModel.reportData!.trim().toText12(isBold: true, color: AppColors.textColorLight), - SizedBox(height: 16.h), - CustomButton( - text: LocaleKeys.viewRadiologyImage.tr(context: context), - onPressed: () async { - if (radiologyViewModel.radiologyImageURL.isNotEmpty) { - Uri uri = Uri.parse(radiologyViewModel.radiologyImageURL); - launchUrl(uri, mode: LaunchMode.platformDefault, webOnlyWindowName: ""); - } else { - Utils.showToast("Radiology image not available"); - } - }, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedColor, - textColor: Colors.white, - fontSize: 14, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - icon: AppAssets.download, - iconColor: Colors.white, - iconSize: 20.h, + Directionality( + textDirection: ui.TextDirection.ltr, + child: widget.patientRadiologyResponseModel.reportData!.trim().toText12(isBold: true, color: AppColors.textColorLight, isEnglishOnly: true), ), SizedBox(height: 16.h), + // CustomButton( + // text: LocaleKeys.viewRadiologyImage.tr(context: context), + // onPressed: () async { + // if (radiologyViewModel.radiologyImageURL.isNotEmpty) { + // Uri uri = Uri.parse(radiologyViewModel.radiologyImageURL); + // launchUrl(uri, mode: LaunchMode.platformDefault, webOnlyWindowName: ""); + // } else { + // Utils.showToast("Radiology image not available"); + // } + // }, + // backgroundColor: AppColors.primaryRedColor, + // borderColor: AppColors.primaryRedColor, + // textColor: Colors.white, + // fontSize: 14, + // fontWeight: FontWeight.w500, + // borderRadius: 12, + // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + // height: 40.h, + // icon: AppAssets.download, + // iconColor: Colors.white, + // iconSize: 20.h, + // ), + // SizedBox(height: 16.h), ], ).paddingSymmetrical(16.h, 0.h), ), @@ -116,16 +128,21 @@ class _RadiologyResultPageState extends State { text: LocaleKeys.downloadReport.tr(context: context), onPressed: () async { LoaderBottomSheet.showLoader(); - await radiologyViewModel.getRadiologyPDF(patientRadiologyResponseModel: widget.patientRadiologyResponseModel, authenticatedUser: _appState.getAuthenticatedUser()!, onError: (err) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - context, - child: Utils.getErrorWidget(loadingText: err), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }).then((val) async { + await radiologyViewModel + .getRadiologyPDF( + patientRadiologyResponseModel: widget.patientRadiologyResponseModel, + authenticatedUser: _appState.getAuthenticatedUser()!, + onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: err), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }) + .then((val) async { LoaderBottomSheet.hideLoader(); if (radiologyViewModel.patientRadiologyReportPDFBase64.isNotEmpty) { String path = await Utils.createFileFromString(radiologyViewModel.patientRadiologyReportPDFBase64, "pdf"); diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index 0c32d87d..4a315c6e 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -26,6 +26,7 @@ class CollapsingListView extends StatelessWidget { VoidCallback? sendEmail; VoidCallback? doctorResponse; VoidCallback? downloadReport; + VoidCallback? viewImage; Widget? bottomChild; Widget? trailing; bool isClose; @@ -49,6 +50,7 @@ class CollapsingListView extends StatelessWidget { this.sendEmail, this.doctorResponse, this.downloadReport, + this.viewImage, this.isLeading = true, this.trailing, this.leadingCallback, @@ -92,6 +94,7 @@ class CollapsingListView extends StatelessWidget { sendEmail: sendEmail, doctorResponse: doctorResponse, downloadReport: downloadReport, + viewImage: viewImage, bottomChild: bottomChild, trailing: trailing, aiOverview: aiOverview, @@ -204,6 +207,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget VoidCallback? sendEmail; VoidCallback? doctorResponse; VoidCallback? downloadReport; + VoidCallback? viewImage; Widget? bottomChild; Widget? trailing; @@ -222,6 +226,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget this.sendEmail, this.doctorResponse, this.downloadReport, + this.viewImage, this.bottomChild, this.trailing, }); @@ -301,6 +306,7 @@ class _ScrollAnimatedTitleState extends State { if (widget.search != null) Utils.buildSvgWithAssets(icon: AppAssets.search_icon).onPress(widget.search!), if (widget.aiOverview != null) actionButton(context, t, title: LocaleKeys.aiOverView.tr(context: context), icon: AppAssets.aiOverView, isAiButton: true).onPress(widget.aiOverview!), if (widget.downloadReport != null) actionButton(context, t, title: LocaleKeys.downloadReport.tr(context: context), icon: AppAssets.download).onPress(widget.downloadReport!), + if (widget.viewImage != null) actionButton(context, t, title: LocaleKeys.viewRadiologyImage.tr(context: context), icon: AppAssets.download).onPress(widget.viewImage!), if (widget.trailing != null) widget.trailing!, ] ], diff --git a/lib/widgets/chip/app_custom_chip_widget.dart b/lib/widgets/chip/app_custom_chip_widget.dart index 77345933..0a6d1169 100644 --- a/lib/widgets/chip/app_custom_chip_widget.dart +++ b/lib/widgets/chip/app_custom_chip_widget.dart @@ -27,6 +27,7 @@ class AppCustomChipWidget extends StatelessWidget { this.labelPadding, this.onDeleteTap, this.applyThemeColor = true, + this.isEnglishOnly = false }); final String? labelText; @@ -48,6 +49,7 @@ class AppCustomChipWidget extends StatelessWidget { final void Function()? onChipTap; final void Function()? onDeleteTap; final bool applyThemeColor; + final bool isEnglishOnly; @override Widget build(BuildContext context) { @@ -85,7 +87,7 @@ class AppCustomChipWidget extends StatelessWidget { applyThemeColor: applyThemeColor, ) : SizedBox.shrink(), - label: richText ?? (labelText?? "").toText10(weight: FontWeight.w500, letterSpacing: 0, color: resolvedTextColor), + label: richText ?? (labelText?? "").toText10(weight: FontWeight.w500, letterSpacing: 0, color: resolvedTextColor, isEnglishOnly: isEnglishOnly), padding: padding, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, labelPadding: labelPadding ?? EdgeInsetsDirectional.only(end: deleteIcon?.isNotEmpty == true ? 2.w : 8.w), @@ -112,7 +114,7 @@ class AppCustomChipWidget extends StatelessWidget { ) : Chip( materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - label: richText ?? (labelText?? "").toText10(weight: FontWeight.w500, letterSpacing: 0, color: resolvedTextColor, isCenter: true), + label: richText ?? (labelText?? "").toText10(weight: FontWeight.w500, letterSpacing: 0, color: resolvedTextColor, isCenter: true, isEnglishOnly: isEnglishOnly), padding: EdgeInsets.zero, backgroundColor: resolvedBackgroundColor, shape: shape ?? diff --git a/pubspec.yaml b/pubspec.yaml index 27a81c7e..bca92d54 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,8 +2,8 @@ name: hmg_patient_app_new description: "New HMG Patient App" publish_to: 'none' # Remove this line if you wish to publish to pub.dev -#version: 0.0.11+8 -version: 0.0.1+9 +#version: 0.0.13+10 +version: 0.0.1+13 environment: sdk: ">=3.6.0 <4.0.0" From 3d877ed28da872b0ef97abeb81b7dd817da91f76 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 25 Mar 2026 13:34:31 +0300 Subject: [PATCH 08/17] Updates --- assets/langs/ar-SA.json | 4 +- assets/langs/en-US.json | 3 +- .../book_appointments_view_model.dart | 22 ++++++++++ lib/generated/locale_keys.g.dart | 3 +- .../appointment_details_page.dart | 12 ++--- .../widgets/appointment_card.dart | 4 +- .../book_appointment_page.dart | 28 ++++++++---- .../home/data/landing_page_data.dart | 8 ++-- lib/presentation/home/landing_page.dart | 2 +- .../home/widgets/large_service_card.dart | 5 ++- .../home_health_care/hhc_procedures_page.dart | 21 ++++++--- .../insurance_update_details_card.dart | 26 +++++------ .../widgets/patient_insurance_card.dart | 44 +++++++++++-------- .../medical_file/medical_file_page.dart | 44 +++++++++++-------- .../profile_settings/profile_settings.dart | 44 +++++++++++-------- lib/widgets/chip/app_custom_chip_widget.dart | 17 ++++--- 16 files changed, 181 insertions(+), 106 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 04684df5..071374e6 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -435,7 +435,6 @@ "serviceInformation": "معلومات الخدمة", "homeHealthCare": "الرعاية الصحية المنزلية", "noAppointmentAvailable": "لا توجد مواعيد متاحة", - "homeHealthCareText": "تقدم هذه الخدمة مجموعة من خدمات الرعاية الصحية المنزلية، والمتابعة المستمرة والشاملة في أماكن إقامتهم لأولئك الذين لا يمكنهم الوصول إلى المرافق الصحية، مثل (تحليلات المختبر - الأشعة - التطعيمات - العلاج الطبيعي)، إلخ.", "loginRegister": "تسجيل الدخول / التسجيل", "orderLog": "سجل الطلب", "infoLab": "تتيح لك هذه الخدمة عرض نتائج جميع الفحوصات المخبرية التي أجريت في مجموعة الحبيب الطبية بالإضافة إلى إرسال التقرير عبر البريد الإلكتروني.", @@ -1585,5 +1584,6 @@ "hmgPolicies": "سياسات مجموعة الحبيب الطبية", "darkMode": "المظهر الداكن", "generateAiAnalysisResult": "قم بإجراء تحليل لهذا المختبر AI", - "ratings": "التقييمات" + "ratings": "التقييمات", + "hmgPharmacyText": "صيدلية الحبيب، المتجر الصيدلاني الإلكتروني المتكامل الذي تقدمه لكم مجموعة خدمات الدكتور سليمان الحبيب الطبية." } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index c43d730e..a76898ba 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1578,5 +1578,6 @@ "hmgPolicies": "HMG Policies", "darkMode": "Dark Mode", "generateAiAnalysisResult": "Generate AI analysis for this result", - "ratings": "Ratings" + "ratings": "Ratings", + "hmgPharmacyText": "Al Habib Pharmacy, the complete online Pharmaceutical store brought to you by Dr. Sulaiman Al Habib Medical Services Group." } diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart index 676a299a..0d2a8f82 100644 --- a/lib/features/book_appointments/book_appointments_view_model.dart +++ b/lib/features/book_appointments/book_appointments_view_model.dart @@ -49,6 +49,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { bool isDoctorSearchByNameStarted = false; bool isAppointmentNearestGateLoading = false; + bool isLiveCareSelectedFromHomePage = false; bool isLiveCareSchedule = false; bool isGetDocForHealthCal = false; bool showSortFilterButtons = false; @@ -318,6 +319,11 @@ class BookAppointmentsViewModel extends ChangeNotifier { notifyListeners(); } + setIsLiveCareSelectedFromHomePage(bool isLiveCareSelectedFromHomePage) { + this.isLiveCareSelectedFromHomePage = isLiveCareSelectedFromHomePage; + notifyListeners(); + } + setIsWaitingAppointmentSelected(bool isWaitingAppointmentSelected) { this.isWaitingAppointmentSelected = isWaitingAppointmentSelected; notifyListeners(); @@ -423,9 +429,25 @@ class BookAppointmentsViewModel extends ChangeNotifier { calculationID = null; isGetDocForHealthCal = false; selectedTabIndex = index; + checkLiveCareSymptomCheckerStatus(); notifyListeners(); } + bool checkLiveCareSymptomCheckerStatus() { + bool isAllowed = false; + + if (selectedTabIndex == 1) { + if (_appState.isAuthenticated) { + isAllowed = true; + } else { + isAllowed = false; + } + } else { + isAllowed = true; + } + return isAllowed; + } + /// this function will decide which clinic api to be called /// either api for region flow or the select clinic api Future getClinics() async { diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 73a18102..951dbf90 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -436,7 +436,6 @@ abstract class LocaleKeys { static const serviceInformation = 'serviceInformation'; static const homeHealthCare = 'homeHealthCare'; static const noAppointmentAvailable = 'noAppointmentAvailable'; - static const homeHealthCareText = 'homeHealthCareText'; static const loginRegister = 'loginRegister'; static const orderLog = 'orderLog'; static const infoLab = 'infoLab'; @@ -746,6 +745,7 @@ abstract class LocaleKeys { static const infoTodo = 'infoTodo'; static const familyInfo = 'familyInfo'; static const rrtdDetails = 'rrtdDetails'; + static const homeHealthCareText = 'homeHealthCareText'; static const onlineCheckInAgreement = 'onlineCheckInAgreement'; static const infoEreferral = 'infoEreferral'; static const erConsultation = 'erConsultation'; @@ -1579,5 +1579,6 @@ abstract class LocaleKeys { static const darkMode = 'darkMode'; static const generateAiAnalysisResult = 'generateAiAnalysisResult'; static const ratings = 'ratings'; + static const hmgPharmacyText = 'hmgPharmacyText'; } diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index cafb740e..71cf4e16 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -69,12 +69,12 @@ class _AppointmentDetailsPageState extends State { @override void initState() { scheduleMicrotask(() async { - CalenderUtilsNew calendarUtils = await CalenderUtilsNew.instance; - var doesExist = await calendarUtils.checkIfEventExist("${widget.patientAppointmentHistoryResponseModel.appointmentNo}"); - myAppointmentsViewModel.setAppointmentReminder(doesExist, widget.patientAppointmentHistoryResponseModel); - setState((){ - - }); + if (!AppointmentType.isArrived(widget.patientAppointmentHistoryResponseModel)) { + CalenderUtilsNew calendarUtils = await CalenderUtilsNew.instance; + var doesExist = await calendarUtils.checkIfEventExist("${widget.patientAppointmentHistoryResponseModel.appointmentNo}"); + myAppointmentsViewModel.setAppointmentReminder(doesExist, widget.patientAppointmentHistoryResponseModel); + setState(() {}); + } }); super.initState(); diff --git a/lib/presentation/appointments/widgets/appointment_card.dart b/lib/presentation/appointments/widgets/appointment_card.dart index 210de466..ac63432f 100644 --- a/lib/presentation/appointments/widgets/appointment_card.dart +++ b/lib/presentation/appointments/widgets/appointment_card.dart @@ -424,7 +424,9 @@ class AppointmentCard extends StatelessWidget { ), ); } else { - bookAppointmentsViewModel.getAppointmentNearestGate(projectID: patientAppointmentHistoryResponseModel.projectID, clinicID: patientAppointmentHistoryResponseModel.clinicID); + if (!AppointmentType.isArrived(patientAppointmentHistoryResponseModel)) { + bookAppointmentsViewModel.getAppointmentNearestGate(projectID: patientAppointmentHistoryResponseModel.projectID, clinicID: patientAppointmentHistoryResponseModel.clinicID); + } Navigator.of(context) .push( CustomPageRoute( diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart index ab548449..aea34ff0 100644 --- a/lib/presentation/book_appointment/book_appointment_page.dart +++ b/lib/presentation/book_appointment/book_appointment_page.dart @@ -61,7 +61,13 @@ class _BookAppointmentPageState extends State { immediateLiveCareViewModel.initImmediateLiveCare(); }); WidgetsBinding.instance.addPostFrameCallback((_) { - showUnKnownClinicBottomSheet(); + if (bookAppointmentsViewModel.selectedTabIndex == 1) { + if (appState.isAuthenticated) { + showUnKnownClinicBottomSheet(); + } + } else { + showUnKnownClinicBottomSheet(); + } }); super.initState(); } @@ -203,7 +209,9 @@ class _BookAppointmentPageState extends State { ), ), ), - _buildSymptomsBottomCard(), + Consumer(builder: (context, bookAppointmentsVM, child) { + return _buildSymptomsBottomCard(); + }), ], ), ); @@ -414,12 +422,13 @@ class _BookAppointmentPageState extends State { } Widget _buildSymptomsBottomCard() { - return Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), - child: Row( - children: [ - Expanded( - child: Column( + return bookAppointmentsViewModel.checkLiveCareSymptomCheckerStatus() + ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), + child: Row( + children: [ + Expanded( + child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -442,7 +451,8 @@ class _BookAppointmentPageState extends State { ) ], ).paddingAll(24.w), - ); + ) + : SizedBox.shrink(); } void openRegionListBottomSheet(BuildContext context, RegionBottomSheetType type) { diff --git a/lib/presentation/home/data/landing_page_data.dart b/lib/presentation/home/data/landing_page_data.dart index b74e57f3..4606c800 100644 --- a/lib/presentation/home/data/landing_page_data.dart +++ b/lib/presentation/home/data/landing_page_data.dart @@ -165,8 +165,8 @@ class LandingPageData { serviceName: "home_health_care", icon: AppAssets.homeBottom, title: LocaleKeys.homeHealthCare, - subtitle: LocaleKeys.liveCareServiceDesc, - largeCardIcon: AppAssets.homeHealthCareService, + subtitle: LocaleKeys.homeHealthCareText, + largeCardIcon: AppAssets.homeHealthCareService, backgroundColor: AppColors.primaryRedColor, iconColor: AppColors.whiteColor, isBold: false, @@ -175,8 +175,8 @@ class LandingPageData { serviceName: "pharmacy", icon: AppAssets.pharmacy_icon, //359846 title: LocaleKeys.hmgPharmacy, - subtitle: LocaleKeys.liveCareServiceDesc, - largeCardIcon: AppAssets.pharmacyService, + subtitle: LocaleKeys.hmgPharmacyText, + largeCardIcon: AppAssets.pharmacyService, backgroundColor: AppColors.pharmacyBGColor, iconColor: null, isBold: true, diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index a7ae78b9..5d068b6c 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -258,7 +258,7 @@ class _LandingPageState extends State { ); }), !appState.isAuthenticated - ? Utils.buildSvgWithAssets(icon: AppAssets.changeLanguageHomePageIcon, height: 24.h, width: 24.h).onPress(() { + ? Utils.buildSvgWithAssets(icon: appState.isArabic() ? AppAssets.enLangIcon : AppAssets.arLangIcon, height: 24.h, width: 24.h).onPress(() { context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA')); }) : SizedBox.shrink() diff --git a/lib/presentation/home/widgets/large_service_card.dart b/lib/presentation/home/widgets/large_service_card.dart index 7c86dd09..4405a197 100644 --- a/lib/presentation/home/widgets/large_service_card.dart +++ b/lib/presentation/home/widgets/large_service_card.dart @@ -229,10 +229,10 @@ class FadedLargeServiceCard extends StatelessWidget { ], ), SizedBox(height: 10.h), - serviceCardData.subtitle.tr(context: context).toText14(weight: FontWeight.w500, color: AppColors.blackBgColor, letterSpacing: 0), + serviceCardData.subtitle.tr(context: context).toText14(weight: FontWeight.w500, color: AppColors.blackBgColor, letterSpacing: 0, maxlines: 2), SizedBox(height: 12.h), CustomButton( - text: serviceCardData.isBold ? "Visit Pharmacy Online".needTranslation : LocaleKeys.bookNow.tr(context: context), + text: serviceCardData.isBold ? LocaleKeys.visitPharmacyOnline.tr(context: context) : LocaleKeys.bookNow.tr(context: context), onPressed: () { handleOnTap(); }, @@ -255,6 +255,7 @@ class FadedLargeServiceCard extends StatelessWidget { case "livecare": { getIt.get().onTabChanged(1); + getIt.get().setIsLiveCareSelectedFromHomePage(true); Navigator.of(getIt.get().navigatorKey.currentContext!).push( CustomPageRoute( page: BookAppointmentPage(), diff --git a/lib/presentation/home_health_care/hhc_procedures_page.dart b/lib/presentation/home_health_care/hhc_procedures_page.dart index c420742c..88766ea0 100644 --- a/lib/presentation/home_health_care/hhc_procedures_page.dart +++ b/lib/presentation/home_health_care/hhc_procedures_page.dart @@ -8,6 +8,7 @@ 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/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart'; @@ -33,11 +34,13 @@ class HhcProceduresPage extends StatefulWidget { } class _HhcProceduresPageState extends State { + + late AppState appState; + @override void initState() { super.initState(); final HmgServicesViewModel hmgServicesViewModel = context.read(); - final AppState appState = getIt.get(); scheduleMicrotask(() async { final user = appState.getAuthenticatedUser(); @@ -445,11 +448,12 @@ class _HhcProceduresPageState extends State { @override Widget build(BuildContext context) { + appState = getIt.get(); return Scaffold( backgroundColor: AppColors.bgScaffoldColor, body: CollapsingListView( title: LocaleKeys.homeHealthCare.tr(context: context), - history: () => Navigator.of(context).push(CustomPageRoute(page: HhcOrderDetailPage(), direction: AxisDirection.up)), + history: () => appState.isAuthenticated ? Navigator.of(context).push(CustomPageRoute(page: HhcOrderDetailPage(), direction: AxisDirection.up)) : null, bottomChild: Consumer( builder: (BuildContext context, HmgServicesViewModel hmgServicesViewModel, Widget? child) { if (hmgServicesViewModel.isHhcOrdersLoading || hmgServicesViewModel.isHhcServicesLoading) { @@ -467,8 +471,14 @@ class _HhcProceduresPageState extends State { padding: EdgeInsets.all(24.w), child: CustomButton( borderWidth: 0, - text: LocaleKeys.createNewRequest.tr(context: context), - onPressed: () => _buildServicesListBottomsSheet(hmgServicesViewModel.hhcServicesList), + text: appState.isAuthenticated ? LocaleKeys.createNewRequest.tr(context: context) : LocaleKeys.loginToUseService.tr(context: context), + onPressed: () { + if(appState.isAuthenticated) { + _buildServicesListBottomsSheet(hmgServicesViewModel.hhcServicesList); + } else { + getIt().onLoginPressed(); + } + }, textColor: AppColors.whiteColor, borderRadius: 12.r, borderColor: Colors.transparent, @@ -492,12 +502,13 @@ class _HhcProceduresPageState extends State { } else { return Column( children: [ + appState.isAuthenticated ? Center( child: Utils.getNoDataWidget( context, noDataText: LocaleKeys.youHaveNoPendingRequests.tr(context: context), ), - ), + ) : LocaleKeys.homeHealthCareText.tr(context: context).toText18(weight: FontWeight.w500).paddingSymmetrical(24.h, 24.h), ], ); } diff --git a/lib/presentation/insurance/widgets/insurance_update_details_card.dart b/lib/presentation/insurance/widgets/insurance_update_details_card.dart index 35be7f9e..bf86671e 100644 --- a/lib/presentation/insurance/widgets/insurance_update_details_card.dart +++ b/lib/presentation/insurance/widgets/insurance_update_details_card.dart @@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart'; import 'package:hmg_patient_app_new/core/app_assets.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/date_util.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'; @@ -75,21 +76,18 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget { ], ), SizedBox(height: 8.h), - Row( + Wrap( + direction: Axis.horizontal, + spacing: 4.h, + runSpacing: 4.h, children: [ - Wrap( - direction: Axis.horizontal, - spacing: 4.h, - runSpacing: 4.h, - children: [ - AppCustomChipWidget( - icon: AppAssets.doctor_calendar_icon, - labelText: "${LocaleKeys.expiryOn.tr(context: context)} ${insuranceViewModel.patientInsuranceUpdateResponseModel!.effectiveTo}", - ), - AppCustomChipWidget( - labelText: "Member ID: ${insuranceViewModel.patientInsuranceUpdateResponseModel!.memberID!}", - ), - ], + AppCustomChipWidget( + icon: AppAssets.doctor_calendar_icon, + labelText: + "${LocaleKeys.expiryOn.tr(context: context)} ${DateUtil.formatDateToDate(DateTime.parse(insuranceViewModel.patientInsuranceUpdateResponseModel!.effectiveTo!), false)}", + ), + AppCustomChipWidget( + labelText: "Member ID: ${insuranceViewModel.patientInsuranceUpdateResponseModel!.memberID!}", ), ], ), diff --git a/lib/presentation/insurance/widgets/patient_insurance_card.dart b/lib/presentation/insurance/widgets/patient_insurance_card.dart index 2d3ba9ea..d6bb204f 100644 --- a/lib/presentation/insurance/widgets/patient_insurance_card.dart +++ b/lib/presentation/insurance/widgets/patient_insurance_card.dart @@ -79,27 +79,35 @@ class PatientInsuranceCard extends StatelessWidget { : AppColors.warningColorYellow, iconSize: 12.w, deleteIcon: insuranceViewModel.isInsuranceActive ? null : AppAssets.forward_chevron_icon, - deleteIconColor: AppColors.warningColorYellow, + deleteIconColor: insuranceViewModel.isInsuranceExpired + ? AppColors.primaryRedColor + : insuranceViewModel.isInsuranceActive + ? AppColors.successColor + : AppColors.warningColorYellow, deleteIconHasColor: true, onChipTap: () { if (!insuranceViewModel.isInsuranceActive) { - showCommonBottomSheetWithoutHeight( - title: LocaleKeys.notice.tr(context: context), - context, - child: Utils.getWarningWidget( - loadingText: LocaleKeys.insuranceInActiveContactSupport.tr(context: context), - confirmText: LocaleKeys.contactUs.tr(context: context), - isShowActionButtons: true, - onCancelTap: () { - Navigator.pop(context); - }, - onConfirmTap: () async { - launchUrl(Uri.parse("tel://" + "+966 92 006 6666")); - }), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); + insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); + insuranceViewModel.getPatientInsuranceDetailsForUpdate( + appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); + showCommonBottomSheetWithoutHeight(context, child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); + // showCommonBottomSheetWithoutHeight( + // title: LocaleKeys.notice.tr(context: context), + // context, + // child: Utils.getWarningWidget( + // loadingText: LocaleKeys.insuranceInActiveContactSupport.tr(context: context), + // confirmText: LocaleKeys.contactUs.tr(context: context), + // isShowActionButtons: true, + // onCancelTap: () { + // Navigator.pop(context); + // }, + // onConfirmTap: () async { + // launchUrl(Uri.parse("tel://" + "+966 92 006 6666")); + // }), + // callBackFunc: () {}, + // isFullScreen: false, + // isCloseButtonVisible: true, + // ); } }, backgroundColor: insuranceViewModel.isInsuranceExpired diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 89843ea7..b804a751 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -312,27 +312,35 @@ class _MedicalFilePageState extends State { : AppColors.warningColorYellow, iconSize: 12.w, deleteIcon: insuranceVM.isInsuranceActive ? null : AppAssets.forward_chevron_icon, - deleteIconColor: AppColors.warningColorYellow, + deleteIconColor: insuranceVM.isInsuranceExpired + ? AppColors.primaryRedColor + : insuranceVM.isInsuranceActive + ? AppColors.successColor + : AppColors.warningColorYellow, deleteIconHasColor: true, onChipTap: () { if (!insuranceVM.isInsuranceActive) { - showCommonBottomSheetWithoutHeight( - title: LocaleKeys.notice.tr(context: navigationService.navigatorKey.currentContext!), - navigationService.navigatorKey.currentContext!, - child: Utils.getWarningWidget( - loadingText: LocaleKeys.insuranceInActiveContactSupport.tr(context: context), - confirmText: LocaleKeys.contactUs.tr(context: context), - isShowActionButtons: true, - onCancelTap: () { - navigationService.pop(); - }, - onConfirmTap: () async { - launchUrl(Uri.parse("tel://" + "+966 92 006 6666")); - }), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); + insuranceVM.setIsInsuranceUpdateDetailsLoading(true); + insuranceVM.getPatientInsuranceDetailsForUpdate( + appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); + showCommonBottomSheetWithoutHeight(context, child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); + // showCommonBottomSheetWithoutHeight( + // title: LocaleKeys.notice.tr(context: navigationService.navigatorKey.currentContext!), + // navigationService.navigatorKey.currentContext!, + // child: Utils.getWarningWidget( + // loadingText: LocaleKeys.insuranceInActiveContactSupport.tr(context: context), + // confirmText: LocaleKeys.contactUs.tr(context: context), + // isShowActionButtons: true, + // onCancelTap: () { + // navigationService.pop(); + // }, + // onConfirmTap: () async { + // launchUrl(Uri.parse("tel://" + "+966 92 006 6666")); + // }), + // callBackFunc: () {}, + // isFullScreen: false, + // isCloseButtonVisible: true, + // ); } }, backgroundColor: insuranceVM.isInsuranceExpired diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart index 27f74826..7d6af196 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -23,6 +23,7 @@ import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_v import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/habib_wallet/habib_wallet_page.dart'; import 'package:hmg_patient_app_new/presentation/habib_wallet/recharge_wallet_page.dart'; +import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_update_details_card.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/app_language_change.dart'; @@ -431,27 +432,34 @@ class FamilyCardWidget extends StatelessWidget { : AppColors.warningColorYellow, iconSize: 12.w, deleteIcon: insuranceVM.isInsuranceActive ? null : AppAssets.forward_chevron_icon, - deleteIconColor: AppColors.warningColorYellow, + deleteIconColor: insuranceVM.isInsuranceExpired + ? AppColors.primaryRedColor + : insuranceVM.isInsuranceActive + ? AppColors.successColor + : AppColors.warningColorYellow, deleteIconHasColor: true, onChipTap: () { if (!insuranceVM.isInsuranceActive) { - showCommonBottomSheetWithoutHeight( - title: LocaleKeys.notice.tr(context: context), - context, - child: Utils.getWarningWidget( - loadingText: LocaleKeys.insuranceInActiveContactSupport.tr(context: context), - confirmText: LocaleKeys.contactUs.tr(context: context), - isShowActionButtons: true, - onCancelTap: () { - Navigator.pop(context); - }, - onConfirmTap: () async { - launchUrl(Uri.parse("tel://" + "+966 92 006 6666")); - }), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); + insuranceVM.setIsInsuranceUpdateDetailsLoading(true); + insuranceVM.getPatientInsuranceDetailsForUpdate(appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); + showCommonBottomSheetWithoutHeight(context, child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); + // showCommonBottomSheetWithoutHeight( + // title: LocaleKeys.notice.tr(context: context), + // context, + // child: Utils.getWarningWidget( + // loadingText: LocaleKeys.insuranceInActiveContactSupport.tr(context: context), + // confirmText: LocaleKeys.contactUs.tr(context: context), + // isShowActionButtons: true, + // onCancelTap: () { + // Navigator.pop(context); + // }, + // onConfirmTap: () async { + // launchUrl(Uri.parse("tel://" + "+966 92 006 6666")); + // }), + // callBackFunc: () {}, + // isFullScreen: false, + // isCloseButtonVisible: true, + // ); } }, backgroundColor: insuranceVM.isInsuranceExpired diff --git a/lib/widgets/chip/app_custom_chip_widget.dart b/lib/widgets/chip/app_custom_chip_widget.dart index 0a6d1169..b2ae4288 100644 --- a/lib/widgets/chip/app_custom_chip_widget.dart +++ b/lib/widgets/chip/app_custom_chip_widget.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.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/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -101,12 +103,15 @@ class AppCustomChipWidget extends StatelessWidget { deleteIcon: deleteIcon?.isNotEmpty == true ? InkWell( onTap: onDeleteTap, - child: Utils.buildSvgWithAssets( - icon: deleteIcon!, - width: iconS, - height: iconS, - iconColor: deleteIconHasColor ? resolvedDeleteIconColor : null, - applyThemeColor: applyThemeColor, + child: Transform.flip( + flipX: getIt.get().isArabic(), + child: Utils.buildSvgWithAssets( + icon: deleteIcon!, + width: iconS, + height: iconS, + iconColor: deleteIconHasColor ? resolvedDeleteIconColor : null, + applyThemeColor: applyThemeColor, + ), ), ) : null, From d703c382e5e350fee56a59f1396468ca4d2ed8c3 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 25 Mar 2026 17:02:17 +0300 Subject: [PATCH 09/17] Updates --- assets/langs/ar-SA.json | 3 +- assets/langs/en-US.json | 3 +- lib/core/api/api_client.dart | 5 +- lib/extensions/widget_extensions.dart | 23 ++--- .../insurance/insurance_view_model.dart | 2 +- lib/generated/locale_keys.g.dart | 1 + lib/presentation/home/landing_page.dart | 57 ++++++------ .../insurance_update_details_card.dart | 72 ++++++++------- .../profile_settings/profile_settings.dart | 87 ++++++++++--------- 9 files changed, 141 insertions(+), 112 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 071374e6..958a4902 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1585,5 +1585,6 @@ "darkMode": "المظهر الداكن", "generateAiAnalysisResult": "قم بإجراء تحليل لهذا المختبر AI", "ratings": "التقييمات", - "hmgPharmacyText": "صيدلية الحبيب، المتجر الصيدلاني الإلكتروني المتكامل الذي تقدمه لكم مجموعة خدمات الدكتور سليمان الحبيب الطبية." + "hmgPharmacyText": "صيدلية الحبيب، المتجر الصيدلاني الإلكتروني المتكامل الذي تقدمه لكم مجموعة خدمات الدكتور سليمان الحبيب الطبية.", + "insuranceRequestSubmittedSuccessfully": "تم إرسال طلب تحديث بيانات التأمين بنجاح. سيتم إعلامك بمجرد الانتهاء." } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index a76898ba..cea0082a 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1579,5 +1579,6 @@ "darkMode": "Dark Mode", "generateAiAnalysisResult": "Generate AI analysis for this result", "ratings": "Ratings", - "hmgPharmacyText": "Al Habib Pharmacy, the complete online Pharmaceutical store brought to you by Dr. Sulaiman Al Habib Medical Services Group." + "hmgPharmacyText": "Al Habib Pharmacy, the complete online Pharmaceutical store brought to you by Dr. Sulaiman Al Habib Medical Services Group.", + "insuranceRequestSubmittedSuccessfully": "Your insurance update request has been successfully submitted. You will be notified once completed." } diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index f415d8ac..0131a938 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -200,7 +200,7 @@ class ApiClientImp implements ApiClient { } // body['TokenID'] = "@dm!n"; - // body['PatientID'] = 2007395; + // body['PatientID'] = 4774402; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; // body['SessionID'] = "45786230487560q"; @@ -359,7 +359,8 @@ class ApiClientImp implements ApiClient { onFailure( parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode, - failureType: ServerFailure("Error While Fetching data"), + // failureType: ServerFailure("Error While Fetching data"), + failureType: ServerFailure(parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage']), ); logApiEndpointError(endPoint, parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], statusCode); } diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index 64672f5f..5e4d4e1f 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -152,6 +152,7 @@ extension SmoothContainerExtension on ShapeBorder { BorderSide? side, BorderRadius? customBorder, bool hasShadow = false, + bool hasDenseShadow = false, }) { final bgColor = backgroundColor ?? color; return ShapeDecoration( @@ -161,17 +162,17 @@ extension SmoothContainerExtension on ShapeBorder { smoothness: 1, side: side ?? BorderSide.none, ), - shadows: - // hasShadow - // ? [ - // BoxShadow( - // color: const Color(0xff000000).withOpacity(.05), - // blurRadius: 32, - // offset: const Offset(0, 0), - // ) - // ] - // : - [], + shadows: hasShadow + ? [ + BoxShadow( + color: hasDenseShadow ? const Color(0xff000000).withOpacity(.30) : const Color(0xff000000).withOpacity(.1), + // color: AppColors.primaryRedColor.withOpacity(.5), + blurRadius: 10, + spreadRadius: 0, + offset: const Offset(0, 0), + ) + ] + : [], ); } } diff --git a/lib/features/insurance/insurance_view_model.dart b/lib/features/insurance/insurance_view_model.dart index 515743c6..d66a7a22 100644 --- a/lib/features/insurance/insurance_view_model.dart +++ b/lib/features/insurance/insurance_view_model.dart @@ -214,7 +214,7 @@ class InsuranceViewModel extends ChangeNotifier { (failure) async { notifyListeners(); if (onError != null) { - onError(failure.toString()); + onError(failure.message.toString()); } }, (apiResponse) { diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 951dbf90..2aeb87f1 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1580,5 +1580,6 @@ abstract class LocaleKeys { static const generateAiAnalysisResult = 'generateAiAnalysisResult'; static const ratings = 'ratings'; static const hmgPharmacyText = 'hmgPharmacyText'; + static const insuranceRequestSubmittedSuccessfully = 'insuranceRequestSubmittedSuccessfully'; } diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 5d068b6c..3012876f 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -331,7 +331,6 @@ class _LandingPageState extends State { ).paddingSymmetrical(24.h, 0.h).onPress(() { Navigator.of(context).push(CustomPageRoute(page: MyAppointmentsPage())); }), - SizedBox(height: 16.h), Consumer3( builder: (context, myAppointmentsVM, immediateLiveCareVM, todoSectionVM, child) { return myAppointmentsVM.isMyAppointmentsLoading @@ -348,7 +347,7 @@ class _LandingPageState extends State { isLoading: true, isFromHomePage: true, ), - ).paddingSymmetrical(24.h, 0.h) + ).paddingSymmetrical(24.h, 16.h) : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty ? myAppointmentsVM.patientAppointmentsHistoryList.length == 1 ? Container( @@ -399,27 +398,34 @@ class _LandingPageState extends State { ), ), ) - : Swiper( - itemCount: myAppointmentsVM.isMyAppointmentsLoading - ? 3 - : myAppointmentsVM.patientAppointmentsHistoryList.length < 3 - ? myAppointmentsVM.patientAppointmentsHistoryList.length - : 3, - 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), + : SizedBox( + height: 255.h + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space + child: Swiper( + itemCount: myAppointmentsVM.isMyAppointmentsLoading + ? 3 + : myAppointmentsVM.patientAppointmentsHistoryList.length < 3 + ? myAppointmentsVM.patientAppointmentsHistoryList.length + : 3, + layout: SwiperLayout.STACK, + loop: true, + itemWidth: MediaQuery.of(context).size.width - 48.h, + indicatorLayout: PageIndicatorLayout.COLOR, + axisDirection: AxisDirection.right, + controller: _controller, + itemHeight: 255.h + 20, + // extra space for shadow + pagination: SwiperPagination( + alignment: Alignment.bottomCenter, + margin: EdgeInsets.only(top: 220.h + 20 + 8 + 24), + builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor), + ), + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: getIndexSwiperCard(index), + ); + }, ), - itemBuilder: (BuildContext context, int index) { - return getIndexSwiperCard(index); - }, ) : Container( width: double.infinity, @@ -451,7 +457,7 @@ class _LandingPageState extends State { ], ), ), - ).paddingSymmetrical(24.h, 0.h); + ).paddingSymmetrical(24.h, 16.h); }, ), @@ -466,7 +472,7 @@ class _LandingPageState extends State { decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, borderRadius: 20.r, - hasShadow: true, + hasShadow: false, side: BorderSide(color: AppColors.primaryRedColor, width: 3.h), ), width: double.infinity, @@ -775,7 +781,7 @@ class _LandingPageState extends State { decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, borderRadius: 20.h, - hasShadow: false, + hasShadow: true, side: BorderSide( color: Utils.getCardBorderColor(currentStatus), width: 2.w, @@ -1006,6 +1012,7 @@ class _LandingPageState extends State { color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true, + hasDenseShadow: true ), child: AppointmentCard( patientAppointmentHistoryResponseModel: appointment, diff --git a/lib/presentation/insurance/widgets/insurance_update_details_card.dart b/lib/presentation/insurance/widgets/insurance_update_details_card.dart index bf86671e..59a4dd97 100644 --- a/lib/presentation/insurance/widgets/insurance_update_details_card.dart +++ b/lib/presentation/insurance/widgets/insurance_update_details_card.dart @@ -9,6 +9,7 @@ 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/insurance/insurance_view_model.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_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/theme/colors.dart'; @@ -105,38 +106,47 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget { text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", onPressed: () { LoaderBottomSheet.showLoader(); - insuranceViewModel.updatePatientInsuranceCard( - patientID: appState.getAuthenticatedUser()!.patientId!, - patientType: appState.getAuthenticatedUser()!.patientType!, - patientIdentificationID: appState.getAuthenticatedUser()!.patientIdentificationNo!, - mobileNo: appState.getAuthenticatedUser()!.mobileNumber!, - insuranceCardImage: "", - onSuccess: (val) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - title: LocaleKeys.success.tr(context: context), - context, - child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr(context: context)), - callBackFunc: () { + getIt().sendPatientUpdateRequest(onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + insuranceViewModel.setIsInsuranceDataToBeLoaded(true); + insuranceViewModel.initInsuranceProvider(); + }, onError: (err) { + insuranceViewModel.updatePatientInsuranceCard( + patientID: appState.getAuthenticatedUser()!.patientId!, + patientType: appState.getAuthenticatedUser()!.patientType!, + patientIdentificationID: appState.getAuthenticatedUser()!.patientIdentificationNo!, + mobileNo: appState.getAuthenticatedUser()!.mobileNumber!, + insuranceCardImage: "", + onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.success.tr(context: context), + context, + child: Utils.getSuccessWidget(loadingText: LocaleKeys.insuranceRequestSubmittedSuccessfully.tr(context: context)), + callBackFunc: () { + Navigator.pop(context); + }, + isFullScreen: false, + isCloseButtonVisible: false, + ); + Future.delayed(Duration(milliseconds: 2000)).then((value) async { Navigator.pop(context); - }, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }, - onError: (err) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - title: LocaleKeys.notice.tr(context: context), - context, - child: Utils.getErrorWidget(loadingText: err.toString()), - callBackFunc: () { - Navigator.pop(context); - }, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }); + }); + }, + onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.notice.tr(context: context), + context, + child: Utils.getErrorWidget(loadingText: err.toString()), + callBackFunc: () { + Navigator.pop(context); + }, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + }); }, backgroundColor: insuranceViewModel.patientInsuranceUpdateResponseModel != null ? AppColors.successColor : AppColors.lightGrayBGColor, borderColor: AppColors.successColor.withOpacity(0.01), diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart index 7d6af196..e975d6f4 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -98,46 +98,53 @@ class ProfileSettingsState extends State { }, isClose: true, child: SingleChildScrollView( - padding: EdgeInsets.only(top: 24.h, bottom: 24.h), + padding: EdgeInsets.only(top: 0.h, bottom: 24.h), physics: NeverScrollableScrollPhysics(), child: Consumer2( builder: (context, profileVm, medicalVm, child) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Swiper( - itemCount: medicalVm.patientFamilyFiles.length, - layout: SwiperLayout.STACK, - loop: true, - itemHeight: dynamicItemHeight(context), - itemWidth: SizeUtils.width - 30.w, - indicatorLayout: PageIndicatorLayout.COLOR, - axisDirection: AxisDirection.right, - controller: _controller, - pagination: SwiperPagination( - alignment: Alignment.bottomCenter, - margin: EdgeInsets.only(top: (210.h + 8.h + 24.h)), - builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor), + SizedBox( + height: dynamicItemHeight(context) + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space + child: Swiper( + itemCount: medicalVm.patientFamilyFiles.length, + layout: SwiperLayout.STACK, + loop: true, + itemHeight: dynamicItemHeight(context) + 20, + // extra space for shadow + itemWidth: SizeUtils.width - 30.w, + indicatorLayout: PageIndicatorLayout.COLOR, + axisDirection: AxisDirection.right, + controller: _controller, + pagination: SwiperPagination( + alignment: Alignment.bottomCenter, + margin: EdgeInsets.only(top: (180.h + 20 + 8.h + 24.h)), + builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor), + ), + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: FamilyCardWidget( + profile: medicalVm.patientFamilyFiles[index], + onAddFamilyMemberPress: () { + DialogService dialogService = getIt.get(); + dialogService.showAddFamilyFileSheet( + label: LocaleKeys.addFamilyMember.tr(context: context), + message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(context: context), + onVerificationPress: () { + medicalVm.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); + }); + }, + onFamilySwitchPress: (FamilyFileResponseModelLists profile) { + medicalVm.switchFamilyFiles(responseID: profile.responseId, patientID: profile.patientId, phoneNumber: profile.mobileNumber); + }, + ).paddingOnly(right: 16.w, left: 8.w), + ); + }, ), - itemBuilder: (BuildContext context, int index) { - return FamilyCardWidget( - profile: medicalVm.patientFamilyFiles[index], - onAddFamilyMemberPress: () { - DialogService dialogService = getIt.get(); - dialogService.showAddFamilyFileSheet( - label: LocaleKeys.addFamilyMember.tr(context: context), - message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(context: context), - onVerificationPress: () { - medicalVm.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); - }); - }, - onFamilySwitchPress: (FamilyFileResponseModelLists profile) { - medicalVm.switchFamilyFiles(responseID: profile.responseId, patientID: profile.patientId, phoneNumber: profile.mobileNumber); - }, - ).paddingOnly(right: 16.w, left: 8.w); - }, ), - SizedBox(height: 5.h), + SizedBox(height: 16.h), GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: isTablet ? 3 : 2), physics: const NeverScrollableScrollPhysics(), @@ -362,9 +369,7 @@ class FamilyCardWidget extends StatelessWidget { return Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - ), + borderRadius: 24.r, hasShadow: true, hasDenseShadow: true), child: Column( children: [ Column( @@ -409,10 +414,11 @@ class FamilyCardWidget extends StatelessWidget { iconColor: AppColors.primaryRedColor) : SizedBox(), Consumer(builder: (context, insuranceVM, child) { - return AppCustomChipWidget( - icon: insuranceVM.isInsuranceExpired - ? AppAssets.cancel_circle_icon - : insuranceVM.isInsuranceActive + return isActive + ? AppCustomChipWidget( + icon: insuranceVM.isInsuranceExpired + ? AppAssets.cancel_circle_icon + : insuranceVM.isInsuranceActive ? AppAssets.insurance_active_icon : AppAssets.alertSquare, labelText: insuranceVM.isInsuranceExpired @@ -468,7 +474,8 @@ class FamilyCardWidget extends StatelessWidget { ? AppColors.successColor.withOpacity(0.1) : AppColors.warningColorYellow.withOpacity(0.1), labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: insuranceVM.isInsuranceActive ? 6.w : 0.w), - ).toShimmer2(isShow: insuranceVM.isInsuranceLoading); + ).toShimmer2(isShow: insuranceVM.isInsuranceLoading) + : SizedBox.shrink(); }), ], ), From d053f58b7deb730dd263efbab232862046d2a32d Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 26 Mar 2026 22:34:25 +0300 Subject: [PATCH 10/17] Updates --- assets/langs/ar-SA.json | 7 +- assets/langs/en-US.json | 7 +- ios/Runner.xcodeproj/project.pbxproj | 14 +- ios/Runner/Info.plist | 1 - lib/core/api_consts.dart | 6 +- lib/core/dependencies.dart | 8 +- lib/core/utils/validation_utils.dart | 8 + lib/extensions/string_extensions.dart | 4 +- .../authentication_view_model.dart | 7 +- .../widgets/otp_verification_screen.dart | 42 +++-- .../hmg_services/hmg_services_view_model.dart | 5 + .../insurance/insurance_view_model.dart | 2 +- .../my_appointments_view_model.dart | 1 + .../profile_settings_repo.dart | 100 ++++++++++ .../profile_settings_view_model.dart | 99 +++++++++- lib/generated/locale_keys.g.dart | 1 + .../appointments/my_doctors_page.dart | 4 +- .../widgets/doctor_rating_details.dart | 23 ++- lib/presentation/home/landing_page.dart | 4 +- .../home/widgets/large_service_card.dart | 22 ++- .../insurance_update_details_card.dart | 7 +- lib/presentation/lab/lab_order_by_test.dart | 2 +- .../medical_file/medical_file_page.dart | 173 +++++++++++------- .../widgets/patient_sick_leave_card.dart | 23 ++- .../my_family/widget/family_cards.dart | 8 +- .../profile_settings/profile_settings.dart | 84 ++++++--- .../widgets/update_email_widget.dart | 106 +++++++++++ .../symptoms_checker/user_info_selection.dart | 2 +- .../widgets/condition_card.dart | 4 +- lib/widgets/appbar/collapsing_list_view.dart | 2 +- pubspec.yaml | 4 +- 31 files changed, 598 insertions(+), 182 deletions(-) create mode 100644 lib/features/profile_settings/profile_settings_repo.dart create mode 100644 lib/presentation/profile_settings/widgets/update_email_widget.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 958a4902..268bf0a3 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -811,7 +811,7 @@ "awaitingApproval": "انتظر القبول", "news": "أخبار", "ready": "جاهز", - "enterValidNationalId": "الرجاء إدخال رقم الهوية الوطنية أو رقم الملف الصحيح", + "enterValidNationalId": "رقم الهوية أو رقم الملف غير صحيح", "enterValidPhoneNumber": "الرجاء إدخال رقم هاتف صالح", "cannotEnterSaudiOrUAENumber": "لا يمكنك إدخال أرقام هواتف السعودية (00966) أو الإمارات (00971) عند اختيار دولة 'أخرى'", "medicalCentersWithCount": "{count} مراكز طبية", @@ -1274,7 +1274,7 @@ "noVitalSignsRecordedYet": "لا توجد علامات حيوية مسجلة بعد", "appointmentsAndVisits": "المواعيد والزيارات", "labAndRadiology": "المختبر والأشعة", - "activeMedicationsAndPrescriptions": "الأدوية النشطة والوصفات الطبية", + "activeMedicationsAndPrescriptions": "الوصفات الطبية", "allPrescriptions": "جميع الوصفات", "allMedications": "جميع الأدوية", "youDontHaveAnyPrescriptionsYet": "ليس لديك أي وصفات طبية بعد.", @@ -1586,5 +1586,6 @@ "generateAiAnalysisResult": "قم بإجراء تحليل لهذا المختبر AI", "ratings": "التقييمات", "hmgPharmacyText": "صيدلية الحبيب، المتجر الصيدلاني الإلكتروني المتكامل الذي تقدمه لكم مجموعة خدمات الدكتور سليمان الحبيب الطبية.", - "insuranceRequestSubmittedSuccessfully": "تم إرسال طلب تحديث بيانات التأمين بنجاح. سيتم إعلامك بمجرد الانتهاء." + "insuranceRequestSubmittedSuccessfully": "تم إرسال طلب تحديث بيانات التأمين بنجاح. سيتم إعلامك بمجرد الانتهاء.", + "updatingEmailAddress": "جارٍ تحديث عنوان البريد الإلكتروني، يرجى الانتظار..." } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index cea0082a..d1a48222 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -802,7 +802,7 @@ "notNow": "Not Now", "pendingActivation": "Pending Activation", "awaitingApproval": "Awaiting Approval", - "enterValidNationalId": "Please enter a valid national ID or file number", + "enterValidNationalId": "Invalid Identification or file number", "enterValidPhoneNumber": "Please enter a valid phone number", "cannotEnterSaudiOrUAENumber": "You cannot enter Saudi Arabia (00966) or UAE (00971) phone numbers when 'Others' country is selected", "ready": "Ready", @@ -1266,7 +1266,7 @@ "noVitalSignsRecordedYet": "No vital signs recorded yet", "appointmentsAndVisits": "Appointments & visits", "labAndRadiology": "Lab & Radiology", - "activeMedicationsAndPrescriptions": "Active Medications & Prescriptions", + "activeMedicationsAndPrescriptions": "Recent Prescriptions", "allPrescriptions": "All Prescriptions", "allMedications": "All Medications", "youDontHaveAnyPrescriptionsYet": "You don't have any prescriptions yet.", @@ -1580,5 +1580,6 @@ "generateAiAnalysisResult": "Generate AI analysis for this result", "ratings": "Ratings", "hmgPharmacyText": "Al Habib Pharmacy, the complete online Pharmaceutical store brought to you by Dr. Sulaiman Al Habib Medical Services Group.", - "insuranceRequestSubmittedSuccessfully": "Your insurance update request has been successfully submitted. You will be notified once completed." + "insuranceRequestSubmittedSuccessfully": "Your insurance update request has been successfully submitted. You will be notified once completed.", + "updatingEmailAddress": "Updating email address, Please wait..." } diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 8ed9d257..6a81b151 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -343,10 +343,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; @@ -360,10 +364,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; @@ -523,7 +531,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 14; DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -709,7 +717,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 14; DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -738,7 +746,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 14; DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 9c805ac5..f412b006 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -101,7 +101,6 @@ audio fetch - location remote-notification voip diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index 6ad7b7ce..5fae22b1 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -233,7 +233,7 @@ class ApiConsts { static String getAiOverViewLabOrder = "Services/Patients.svc/REST/HMGAI_Lab_Analyzer_API"; // ************ static values for Api **************** - static final double appVersionID = 20.3; + static final double appVersionID = 20.5; // static final double appVersionID = 50.7; static final int appChannelId = 3; @@ -920,6 +920,10 @@ const DASHBOARD = 'Services/Patients.svc/REST/PatientDashboard'; const SEND_PATIENT_IMMEDIATE_UPDATE_INSURANCE_REQUEST = 'Services/OUTPs.svc/REST/PatientCompanyUpdate'; +const PROFILE_SETTING = 'Services/Patients.svc/REST/GetPateintInfoForUpdate'; + +const SAVE_SETTING = 'Services/Patients.svc/REST/UpdatePateintInfo'; + class ApiKeyConstants { static final String googleMapsApiKey = 'AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng'; } diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart index 4266aa3b..657d03ea 100644 --- a/lib/core/dependencies.dart +++ b/lib/core/dependencies.dart @@ -50,6 +50,7 @@ import 'package:hmg_patient_app_new/features/payfort/payfort_repo.dart'; import 'package:hmg_patient_app_new/features/payfort/payfort_view_model.dart'; import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_repo.dart'; import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_model.dart'; +import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_repo.dart'; import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_view_model.dart'; import 'package:hmg_patient_app_new/features/qr_parking/qr_parking_repo.dart'; import 'package:hmg_patient_app_new/features/radiology/radiology_repo.dart'; @@ -172,6 +173,7 @@ class AppDependencies { getIt.registerLazySingleton(() => NotificationsRepoImp(loggerService: getIt(), apiClient: getIt())); getIt.registerLazySingleton(() => AskDoctorRepoImp(loggerService: getIt(), apiClient: getIt())); getIt.registerLazySingleton(() => ServicesPriceListRepoImp(loggerService: getIt(), apiClient: getIt())); + getIt.registerLazySingleton(() => ProfileSettingsRepoImp(loggerService: getIt(), apiClient: getIt())); // ViewModels // Global/shared VMs → LazySingleton @@ -224,7 +226,11 @@ class AppDependencies { authenticationRepo: getIt(), cacheService: getIt(), navigationService: getIt(), dialogService: getIt(), appState: getIt(), errorHandlerService: getIt(), localAuthService: getIt()), ); - getIt.registerLazySingleton(() => ProfileSettingsViewModel(cacheService: getIt())); + getIt.registerLazySingleton(() => ProfileSettingsViewModel( + cacheService: getIt(), + profileSettingsRepo: getIt(), + errorHandlerService: getIt(), + )); getIt.registerLazySingleton(() => DateRangeSelectorRangeViewModel()); diff --git a/lib/core/utils/validation_utils.dart b/lib/core/utils/validation_utils.dart index a8bc03d3..b5651648 100644 --- a/lib/core/utils/validation_utils.dart +++ b/lib/core/utils/validation_utils.dart @@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:hmg_patient_app_new/core/common_models/nationality_country_model.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/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; @@ -32,6 +33,13 @@ class ValidationUtils { isCorrectID = false; } + if(nationalId!.length == 10) { + if (Utils.isSAUDIIDValid(nationalId!) == false) { + _dialogService.showExceptionBottomSheet(message: LocaleKeys.enterValidNationalId.tr(), onOkPressed: onOkPress); + isCorrectID = false; + } + } + if (nationalId != null && nationalId.isNotEmpty && selectedCountry != null) { if (selectedCountry == CountryEnum.saudiArabia) { if (!validateIqama(nationalId)) { diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 93901497..6e28ffda 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -320,9 +320,9 @@ extension EmailValidator on String { height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 32.f, letterSpacing: -1, fontFamily: isEnglishOnly ? "Poppins" : getIt.get().getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins', fontWeight: isBold ? FontWeight.bold : weight ?? FontWeight.normal), ); - Widget toText44({Color? color, bool isBold = false}) => Text( + Widget toText44({Color? color, bool isBold = false, bool isEnglishOnly = false,}) => Text( this, - style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 44.f, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal), + style: TextStyle(height: 32 / 32, color: color ?? AppColors.blackColor, fontSize: 44.f, letterSpacing: -1, fontWeight: isBold ? FontWeight.bold : FontWeight.normal, fontFamily: (isEnglishOnly ? "Poppins" : getIt.get().getLanguageCode() == "ar" ? 'GESSTwo' : 'Poppins'),), ); Widget toSectionHeading({String upperHeading = "", String lowerHeading = ""}) { diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index ce54c69f..336b35ae 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -28,6 +28,7 @@ import 'package:hmg_patient_app_new/features/authentication/models/resp_models/a import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_activation_code_resp_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_user_staus_nhic_response_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart'; +import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; @@ -619,11 +620,12 @@ class AuthenticationViewModel extends ChangeNotifier { } else { activation.list!.first.isParentUser = true; } - activation.list!.first.bloodGroup = activation.patientBlodType; + activation.list!.first.bloodGroup = activation.patientBloodType; activation.list!.first.zipCode = selectedCountrySignup == CountryEnum.others ? '0' : selectedCountrySignup.countryCode; _appState.setAuthenticatedUser(activation.list!.first); _appState.setPrivilegeModelList(activation.list!.first.listPrivilege!); - _appState.setUserBloodGroup = activation.patientBlodType ?? "N/A"; + // _appState.setUserBloodGroup = activation.patientBlodType ?? "N/A"; + _appState.setUserBloodGroup = activation.patientBloodType ?? "N/A"; } // _appState.setUserBloodGroup = (activation.patientBlodType ?? ""); _appState.setAppAuthToken = activation.authenticationTokenId; @@ -646,6 +648,7 @@ class AuthenticationViewModel extends ChangeNotifier { await clearDefaultInputValues(); myAppointmentsVM.setIsAppointmentDataToBeLoaded(true); getIt.get().setIsInsuranceDataToBeLoaded(true); + getIt.get().setHasVitalSignDataLoaded(false); if (isUserAgreedBefore) { LoaderBottomSheet.hideLoader(); navigateToHomeScreen(); diff --git a/lib/features/authentication/widgets/otp_verification_screen.dart b/lib/features/authentication/widgets/otp_verification_screen.dart index 7ddccda8..9e80dbb9 100644 --- a/lib/features/authentication/widgets/otp_verification_screen.dart +++ b/lib/features/authentication/widgets/otp_verification_screen.dart @@ -20,6 +20,8 @@ import 'package:hmg_patient_app_new/widgets/appbar/app_bar_widget.dart'; import 'package:provider/provider.dart'; import 'package:sms_otp_auto_verify/sms_otp_auto_verify.dart'; +import 'dart:ui' as ui; + typedef OnDone = void Function(String text); class ProvidedPinBoxTextAnimation { @@ -564,23 +566,27 @@ class _OTPVerificationScreenState extends State { SizedBox(height: 16.h), Center( - child: OTPWidget( - maxLength: _otpLength, - controller: _otpController, - pinBoxWidth: 70.h, - pinBoxHeight: 100.h, - pinBoxRadius: 16, - pinBoxBorderWidth: 0, - pinBoxOuterPadding: EdgeInsets.symmetric(horizontal: 4.h), - defaultBorderColor: Colors.transparent, - textBorderColor: Colors.transparent, - pinBoxColor: AppColors.whiteColor, - autoFocus: true, - onTextChanged: _onOtpChanged, - pinTextStyle: TextStyle( - fontSize: 40.f, - fontWeight: FontWeight.bold, - color: AppColors.whiteColor, + child: Directionality( + textDirection: ui.TextDirection.ltr, + child: OTPWidget( + maxLength: _otpLength, + controller: _otpController, + pinBoxWidth: 70.h, + pinBoxHeight: 100.h, + pinBoxRadius: 16, + pinBoxBorderWidth: 0, + pinBoxOuterPadding: EdgeInsets.symmetric(horizontal: 4.h), + defaultBorderColor: Colors.transparent, + textBorderColor: Colors.transparent, + pinBoxColor: AppColors.whiteColor, + autoFocus: true, + onTextChanged: _onOtpChanged, + pinTextStyle: TextStyle( + fontSize: 40.f, + fontWeight: FontWeight.bold, + color: AppColors.whiteColor, + fontFamily: "Poppins" + ), ), ), ), @@ -601,7 +607,7 @@ class _OTPVerificationScreenState extends State { children: [ LocaleKeys.resendIn.tr(context: context).toText16(color: AppColors.inputLabelTextColor), SizedBox(width: 2.h), - ' ($minutes:$seconds). '.toText16(color: AppColors.inputLabelTextColor) + ' ($minutes:$seconds). '.toText16(color: AppColors.inputLabelTextColor, isEnglishOnly: true) ], ); }, diff --git a/lib/features/hmg_services/hmg_services_view_model.dart b/lib/features/hmg_services/hmg_services_view_model.dart index 5bf450ba..7b32cc6e 100644 --- a/lib/features/hmg_services/hmg_services_view_model.dart +++ b/lib/features/hmg_services/hmg_services_view_model.dart @@ -85,6 +85,11 @@ class HmgServicesViewModel extends ChangeNotifier { List covidTestProcedureList = []; Covid19GetPaymentInfo? covidPaymentInfo; + void setHasVitalSignDataLoaded(bool hasVitalSignDataLoaded) { + this.hasVitalSignDataLoaded = hasVitalSignDataLoaded; + notifyListeners(); + } + Future getOrdersList() async {} // HHC multiple services selection diff --git a/lib/features/insurance/insurance_view_model.dart b/lib/features/insurance/insurance_view_model.dart index d66a7a22..d1423113 100644 --- a/lib/features/insurance/insurance_view_model.dart +++ b/lib/features/insurance/insurance_view_model.dart @@ -88,7 +88,7 @@ class InsuranceViewModel extends ChangeNotifier { (failure) async { debugPrint("InsuranceViewModel: API call failed - ${failure.toString()}"); isInsuranceLoading = false; - isInsuranceDataToBeLoaded = false; + isInsuranceDataToBeLoaded = true; isInsuranceExpired = false; isInsuranceActive = false; notifyListeners(); diff --git a/lib/features/my_appointments/my_appointments_view_model.dart b/lib/features/my_appointments/my_appointments_view_model.dart index d2296a66..1584f891 100644 --- a/lib/features/my_appointments/my_appointments_view_model.dart +++ b/lib/features/my_appointments/my_appointments_view_model.dart @@ -634,6 +634,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { Future getPatientMyDoctors({Function(dynamic)? onSuccess, Function(String)? onError}) async { // if (!isAppointmentDataToBeLoaded) return; isPatientMyDoctorsLoading = true; + patientMyDoctorsList.clear(); notifyListeners(); final result = await myAppointmentsRepo.getPatientDoctorsList(); diff --git a/lib/features/profile_settings/profile_settings_repo.dart b/lib/features/profile_settings/profile_settings_repo.dart new file mode 100644 index 00000000..253bf505 --- /dev/null +++ b/lib/features/profile_settings/profile_settings_repo.dart @@ -0,0 +1,100 @@ +import 'package:dartz/dartz.dart'; +import 'package:hmg_patient_app_new/core/api/api_client.dart'; +import 'package:hmg_patient_app_new/core/api_consts.dart'; +import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; +import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; +import 'package:hmg_patient_app_new/services/logger_service.dart'; + +abstract class ProfileSettingsRepo { + /// Updates general patient info (name, phone, etc.). + Future>> updatePatientInfo({ + required Map patientInfo, + }); + + /// Deactivates (deletes) the patient's account. + Future>> deactivateAccount(); +} + +class ProfileSettingsRepoImp implements ProfileSettingsRepo { + final ApiClient apiClient; + final LoggerService loggerService; + + ProfileSettingsRepoImp({ + required this.loggerService, + required this.apiClient, + }); + + @override + Future>> updatePatientInfo({ + required Map patientInfo, + }) async { + try { + GenericApiModel? apiResponse; + Failure? failure; + + await apiClient.post( + SAVE_SETTING, + body: patientInfo, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: errorMessage, + data: response, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } + + @override + Future>> deactivateAccount() async { + final Map body = {}; + + try { + GenericApiModel? apiResponse; + Failure? failure; + + await apiClient.post( + // TODO: Replace with actual deactivate-account endpoint once available + 'Services/Patients.svc/REST/Patient_DeactivateAccount', + body: body, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: errorMessage, + data: response, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } +} + diff --git a/lib/features/profile_settings/profile_settings_view_model.dart b/lib/features/profile_settings/profile_settings_view_model.dart index e001d1bd..92f11528 100644 --- a/lib/features/profile_settings/profile_settings_view_model.dart +++ b/lib/features/profile_settings/profile_settings_view_model.dart @@ -1,18 +1,42 @@ import 'package:flutter/foundation.dart'; +import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_repo.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; +import 'package:hmg_patient_app_new/services/error_handler_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; class ProfileSettingsViewModel extends ChangeNotifier { static const String _darkModeKey = 'is_dark_mode'; final CacheService _cacheService; + final ProfileSettingsRepo profileSettingsRepo; + final ErrorHandlerService errorHandlerService; + // ── Dark-mode state ────────────────────────────────────────────────── bool _isDarkMode = false; - bool get isDarkMode => _isDarkMode; - ProfileSettingsViewModel({required CacheService cacheService}) - : _cacheService = cacheService; + // ── Update email state ─────────────────────────────────────────────── + bool isUpdateEmailLoading = false; + bool isUpdateEmailSuccess = false; + String? updateEmailError; + + // ── Update patient info state ──────────────────────────────────────── + bool isUpdatePatientInfoLoading = false; + bool isUpdatePatientInfoSuccess = false; + String? updatePatientInfoError; + + // ── Deactivate account state ───────────────────────────────────────── + bool isDeactivateAccountLoading = false; + bool isDeactivateAccountSuccess = false; + String? deactivateAccountError; + + ProfileSettingsViewModel({ + required CacheService cacheService, + required this.profileSettingsRepo, + required this.errorHandlerService, + }) : _cacheService = cacheService; + + // ── Dark mode ──────────────────────────────────────────────────────── /// Call once at app startup (before the first frame) to restore the /// persisted dark-mode preference. @@ -30,6 +54,75 @@ class ProfileSettingsViewModel extends ChangeNotifier { notifyListeners(); } + // ── Update patient info ────────────────────────────────────────────── + + Future updatePatientInfo({ + required Map patientInfo, + Function(dynamic)? onSuccess, + Function(String)? onError, + }) async { + isUpdatePatientInfoLoading = true; + isUpdatePatientInfoSuccess = false; + updatePatientInfoError = null; + notifyListeners(); + + final result = await profileSettingsRepo.updatePatientInfo(patientInfo: patientInfo); + + result.fold( + (failure) { + isUpdatePatientInfoLoading = false; + updatePatientInfoError = failure.message; + notifyListeners(); + if (onError != null) { + onError(failure.message); + } else { + errorHandlerService.handleError(failure: failure); + } + }, + (response) { + isUpdatePatientInfoLoading = false; + isUpdatePatientInfoSuccess = true; + notifyListeners(); + onSuccess?.call(response.data); + }, + ); + } + + // ── Deactivate account ─────────────────────────────────────────────── + + Future deactivateAccount({ + Function(dynamic)? onSuccess, + Function(String)? onError, + }) async { + isDeactivateAccountLoading = true; + isDeactivateAccountSuccess = false; + deactivateAccountError = null; + notifyListeners(); + + final result = await profileSettingsRepo.deactivateAccount(); + + result.fold( + (failure) { + isDeactivateAccountLoading = false; + deactivateAccountError = failure.message; + notifyListeners(); + if (onError != null) { + onError(failure.message); + } else { + errorHandlerService.handleError(failure: failure); + } + }, + (response) { + isDeactivateAccountLoading = false; + isDeactivateAccountSuccess = true; + notifyListeners(); + onSuccess?.call(response.data); + }, + ); + } + + // ── Helpers ────────────────────────────────────────────────────────── + void notify() { notifyListeners(); } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 2aeb87f1..031e1be9 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1581,5 +1581,6 @@ abstract class LocaleKeys { static const ratings = 'ratings'; static const hmgPharmacyText = 'hmgPharmacyText'; static const insuranceRequestSubmittedSuccessfully = 'insuranceRequestSubmittedSuccessfully'; + static const updatingEmailAddress = 'updatingEmailAddress'; } diff --git a/lib/presentation/appointments/my_doctors_page.dart b/lib/presentation/appointments/my_doctors_page.dart index d1ea0e98..002f537c 100644 --- a/lib/presentation/appointments/my_doctors_page.dart +++ b/lib/presentation/appointments/my_doctors_page.dart @@ -93,8 +93,6 @@ class _MyDoctorsPageState extends State { borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, - - ), SizedBox(width: 8.h), CustomButton( @@ -280,7 +278,7 @@ class _MyDoctorsPageState extends State { runSpacing: 4.h, children: [ AppCustomChipWidget( - labelText: isSortByClinic ? (doctor?.clinicName ?? "") : (doctor?.projectName ?? ""), + labelText: isSortByClinic ? (doctor?.projectName ?? "") : (doctor?.clinicName ?? ""), ), ], ), diff --git a/lib/presentation/book_appointment/widgets/doctor_rating_details.dart b/lib/presentation/book_appointment/widgets/doctor_rating_details.dart index 6d9e1cb2..1a5eedfe 100644 --- a/lib/presentation/book_appointment/widgets/doctor_rating_details.dart +++ b/lib/presentation/book_appointment/widgets/doctor_rating_details.dart @@ -20,13 +20,20 @@ class DoctorRatingDetails extends StatelessWidget { : Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - bookAppointmentsVM.doctorsProfileResponseModel.actualDoctorRate!.ceilToDouble().toString().toText44(isBold: true), + bookAppointmentsVM.doctorsProfileResponseModel.actualDoctorRate!.ceilToDouble().toString().toText44(isBold: true, isEnglishOnly: true), SizedBox(height: 4.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "${bookAppointmentsVM.doctorsProfileResponseModel.noOfPatientsRate} ${LocaleKeys.reviews.tr(context: context)}" - .toText16(weight: FontWeight.w500, color: AppColors.greyInfoTextColor), + Row( + children: [ + "${bookAppointmentsVM.doctorsProfileResponseModel.noOfPatientsRate} " + .toText16(weight: FontWeight.w500, color: AppColors.greyInfoTextColor, isEnglishOnly: true), + LocaleKeys.reviews.tr(context: context) + .toText16(weight: FontWeight.w500, color: AppColors.greyInfoTextColor,), + ], + ), + RatingBar( initialRating: bookAppointmentsVM.doctorsProfileResponseModel.actualDoctorRate!.toDouble(), direction: Axis.horizontal, @@ -75,7 +82,7 @@ class DoctorRatingDetails extends StatelessWidget { ), Container( margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0), - child: Text("${getRatingWidth(bookAppointmentsVM.doctorDetailsList[0].ratio).round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600)), + child: Text("${getRatingWidth(bookAppointmentsVM.doctorDetailsList[0].ratio).round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600, fontFamily: "Poppins")), ), ], ), @@ -95,7 +102,7 @@ class DoctorRatingDetails extends StatelessWidget { ), Container( margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0), - child: Text("${bookAppointmentsVM.doctorDetailsList[1].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600)), + child: Text("${bookAppointmentsVM.doctorDetailsList[1].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600, fontFamily: "Poppins")), ), ], ), @@ -115,7 +122,7 @@ class DoctorRatingDetails extends StatelessWidget { ), Container( margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0), - child: Text("${bookAppointmentsVM.doctorDetailsList[2].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600)), + child: Text("${bookAppointmentsVM.doctorDetailsList[2].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600, fontFamily: "Poppins")), ), ], ), @@ -135,7 +142,7 @@ class DoctorRatingDetails extends StatelessWidget { ), Container( margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0), - child: Text("${bookAppointmentsVM.doctorDetailsList[3].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600)), + child: Text("${bookAppointmentsVM.doctorDetailsList[3].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600, fontFamily: "Poppins")), ), ], ), @@ -156,7 +163,7 @@ class DoctorRatingDetails extends StatelessWidget { ), Container( margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0), - child: Text("${bookAppointmentsVM.doctorDetailsList[4].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600)), + child: Text("${bookAppointmentsVM.doctorDetailsList[4].ratio.round()}%", style: TextStyle(fontSize: 14.0, color: AppColors.textColor, fontWeight: FontWeight.w600, fontFamily: "Poppins")), ), ], ), diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 3012876f..0c17434e 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -407,10 +407,10 @@ class _LandingPageState extends State { ? myAppointmentsVM.patientAppointmentsHistoryList.length : 3, layout: SwiperLayout.STACK, - loop: true, + loop: false, itemWidth: MediaQuery.of(context).size.width - 48.h, indicatorLayout: PageIndicatorLayout.COLOR, - axisDirection: AxisDirection.right, + axisDirection: getIt.get().isArabic() ? AxisDirection.left : AxisDirection.right, controller: _controller, itemHeight: 255.h + 20, // extra space for shadow diff --git a/lib/presentation/home/widgets/large_service_card.dart b/lib/presentation/home/widgets/large_service_card.dart index 4405a197..b89e58c5 100644 --- a/lib/presentation/home/widgets/large_service_card.dart +++ b/lib/presentation/home/widgets/large_service_card.dart @@ -1,6 +1,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/api_consts.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/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -92,12 +93,12 @@ class LargeServiceCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ serviceCardData.title.tr(context: context).toText14(isBold: true, color: AppColors.textColor), - serviceCardData.subtitle.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), + serviceCardData.subtitle.tr(context: context).toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight, maxLine: 2), ], ), ), ], - ).paddingSymmetrical(16.w, 0.h).expanded, + ).paddingSymmetrical(8.w, 0.h).expanded, CustomButton( text: serviceCardData.isBold ? LocaleKeys.visitPharmacyOnline.tr(context: context) : LocaleKeys.bookNow.tr(context: context), onPressed: () { @@ -177,7 +178,9 @@ class FadedLargeServiceCard extends StatelessWidget { children: [ ClipRRect( borderRadius: BorderRadius.circular(24.r), - child: Image.asset(serviceCardData.largeCardIcon, fit: BoxFit.cover, width: 520.w, height: 250.h), + child: Transform.flip( + flipX: getIt.get().isArabic(), + child: Image.asset(serviceCardData.largeCardIcon, fit: BoxFit.cover, width: 520.w, height: 250.h)), ), Positioned( top: 0, @@ -216,11 +219,14 @@ class FadedLargeServiceCard extends StatelessWidget { ), child: Padding( padding: EdgeInsets.all(8.h), - child: Utils.buildSvgWithAssets( - icon: serviceCardData.icon, - iconColor: serviceCardData.iconColor, - fit: BoxFit.contain, - applyThemeColor: false + child: Transform.flip( + flipX: getIt.get().isArabic(), + child: Utils.buildSvgWithAssets( + icon: serviceCardData.icon, + iconColor: serviceCardData.iconColor, + fit: BoxFit.contain, + applyThemeColor: false + ), ), ), ), diff --git a/lib/presentation/insurance/widgets/insurance_update_details_card.dart b/lib/presentation/insurance/widgets/insurance_update_details_card.dart index 59a4dd97..2136f0cb 100644 --- a/lib/presentation/insurance/widgets/insurance_update_details_card.dart +++ b/lib/presentation/insurance/widgets/insurance_update_details_card.dart @@ -110,6 +110,7 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget { LoaderBottomSheet.hideLoader(); insuranceViewModel.setIsInsuranceDataToBeLoaded(true); insuranceViewModel.initInsuranceProvider(); + Navigator.pop(context); }, onError: (err) { insuranceViewModel.updatePatientInsuranceCard( patientID: appState.getAuthenticatedUser()!.patientId!, @@ -129,9 +130,9 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget { isFullScreen: false, isCloseButtonVisible: false, ); - Future.delayed(Duration(milliseconds: 2000)).then((value) async { - Navigator.pop(context); - }); + // Future.delayed(Duration(milliseconds: 2000)).then((value) async { + // Navigator.pop(context); + // }); }, onError: (err) { LoaderBottomSheet.hideLoader(); diff --git a/lib/presentation/lab/lab_order_by_test.dart b/lib/presentation/lab/lab_order_by_test.dart index 1b5db920..ac6f0f3b 100644 --- a/lib/presentation/lab/lab_order_by_test.dart +++ b/lib/presentation/lab/lab_order_by_test.dart @@ -59,7 +59,7 @@ class LabOrderByTest extends StatelessWidget { icon: AppAssets.view_report_icon, iconColor: AppColors.primaryRedColor, iconSize: 16.h, - text: LocaleKeys.viewReport.tr(context: context), + text: LocaleKeys.viewResults.tr(context: context), onPressed: () { onTap(); }, diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index b804a751..1c839c10 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -283,9 +283,9 @@ class _MedicalFilePageState extends State { ), AppCustomChipWidget( icon: AppAssets.blood_icon, - labelText: LocaleKeys.bloodGroup.tr(namedArgs: {'bloodType': appState.getUserBloodGroup.isEmpty ? "N/A" : appState.getUserBloodGroup}, context: context), + labelText: appState.getUserBloodGroup.isEmpty ? "N/A" : appState.getUserBloodGroup, iconColor: AppColors.primaryRedColor, - labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), + labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w), padding: EdgeInsets.zero, ), Consumer(builder: (context, insuranceVM, child) { @@ -749,7 +749,26 @@ class _MedicalFilePageState extends State { ], ).paddingSymmetrical(0.w, 0.h), SizedBox(height: 24.h), - LocaleKeys.activeMedicationsAndPrescriptions.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.activeMedicationsAndPrescriptions.tr(context: context).toText16(weight: FontWeight.w500, letterSpacing: -0.2), + Row( + children: [ + 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), + ], + ).onPress(() { + // myAppointmentsViewModel.getPatientMyDoctors(); + Navigator.of(context).push( + CustomPageRoute( + page: PrescriptionsListPage(), + ), + ); + }), + ], + ), SizedBox(height: 16.h), Consumer(builder: (context, prescriptionVM, child) { return prescriptionVM.isPrescriptionsOrdersLoading @@ -830,55 +849,55 @@ class _MedicalFilePageState extends State { separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), ), SizedBox(height: 16.h), - Divider(color: AppColors.dividerColor), - SizedBox(height: 16.h), - Row( - children: [ - Expanded( - child: CustomButton( - text: LocaleKeys.allPrescriptions.tr(context: context), - onPressed: () { - Navigator.of(context).push( - CustomPageRoute( - page: PrescriptionsListPage(), - ), - ); - }, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 12.f, - fontWeight: FontWeight.w500, - borderRadius: 12.r, - height: 40.h, - icon: AppAssets.requests, - iconColor: AppColors.primaryRedColor, - iconSize: 16.w, - ), - ), - SizedBox(width: 6.w), - Expanded( - child: CustomButton( - text: LocaleKeys.allMedications.tr(context: context), - onPressed: () { Navigator.of(context).push( - CustomPageRoute( - page: ActiveMedicationPage(), - ), - );}, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 12.f, - fontWeight: FontWeight.w500, - borderRadius: 12.h, - height: 40.h, - icon: AppAssets.all_medications_icon, - iconColor: AppColors.primaryRedColor, - iconSize: 16.h, - ), - ), - ], - ), + // Divider(color: AppColors.dividerColor), + // SizedBox(height: 16.h), + // Row( + // children: [ + // Expanded( + // child: CustomButton( + // text: LocaleKeys.allPrescriptions.tr(context: context), + // onPressed: () { + // Navigator.of(context).push( + // CustomPageRoute( + // page: PrescriptionsListPage(), + // ), + // ); + // }, + // backgroundColor: AppColors.secondaryLightRedColor, + // borderColor: AppColors.secondaryLightRedColor, + // textColor: AppColors.primaryRedColor, + // fontSize: 12.f, + // fontWeight: FontWeight.w500, + // borderRadius: 12.r, + // height: 40.h, + // icon: AppAssets.requests, + // iconColor: AppColors.primaryRedColor, + // iconSize: 16.w, + // ), + // ), + // SizedBox(width: 6.w), + // Expanded( + // child: CustomButton( + // text: LocaleKeys.allMedications.tr(context: context), + // onPressed: () { Navigator.of(context).push( + // CustomPageRoute( + // page: ActiveMedicationPage(), + // ), + // );}, + // backgroundColor: AppColors.secondaryLightRedColor, + // borderColor: AppColors.secondaryLightRedColor, + // textColor: AppColors.primaryRedColor, + // fontSize: 12.f, + // fontWeight: FontWeight.w500, + // borderRadius: 12.h, + // height: 40.h, + // icon: AppAssets.all_medications_icon, + // iconColor: AppColors.primaryRedColor, + // iconSize: 16.h, + // ), + // ), + // ], + // ), ], ), ), @@ -911,7 +930,7 @@ class _MedicalFilePageState extends State { Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), ], ).onPress(() { - myAppointmentsViewModel.getPatientMyDoctors(); + // myAppointmentsViewModel.getPatientMyDoctors(); Navigator.of(context).push( CustomPageRoute( page: MyDoctorsPage(), @@ -1210,6 +1229,26 @@ class _MedicalFilePageState extends State { // Requests Tab Data return Column( children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "${LocaleKeys.sick.tr(context: context)} ${LocaleKeys.sickSubtitle.tr(context: context)}".toText16(isBold: true), + Row( + children: [ + LocaleKeys.viewAll.tr(context: context).toText12(color: AppColors.primaryRedColor), + SizedBox(width: 2.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 10.h), + ], + ), + ], + ).onPress(() { + Navigator.of(context).push( + CustomPageRoute( + page: PatientSickleavesListPage(), + ), + ); + }), + SizedBox(height: 16.h), Consumer(builder: (context, medicalFileVM, child) { return medicalFileVM.isPatientSickLeaveListLoading ? PatientSickLeaveCard( @@ -1279,20 +1318,20 @@ class _MedicalFilePageState extends State { ), ); }), - MedicalFileCard( - label: LocaleKeys.sickLeaveReport.tr(context: context), - textColor: AppColors.blackColor, - backgroundColor: AppColors.whiteColor, - svgIcon: AppAssets.sick_leave_report_icon, - isLargeText: true, - iconSize: 36.h, - ).onPress(() { - Navigator.of(context).push( - CustomPageRoute( - page: PatientSickleavesListPage(), - ), - ); - }), + // MedicalFileCard( + // label: LocaleKeys.sickLeaveReport.tr(context: context), + // textColor: AppColors.blackColor, + // backgroundColor: AppColors.whiteColor, + // svgIcon: AppAssets.sick_leave_report_icon, + // isLargeText: true, + // iconSize: 36.h, + // ).onPress(() { + // Navigator.of(context).push( + // CustomPageRoute( + // page: PatientSickleavesListPage(), + // ), + // ); + // }), ], ).paddingSymmetrical(0.w, 0.0), SizedBox(height: 24.h), diff --git a/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart b/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart index a0c54e68..18bd2e69 100644 --- a/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart +++ b/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart @@ -40,18 +40,17 @@ class PatientSickLeaveCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - "${LocaleKeys.sick.tr(context: context)} ${LocaleKeys.sickSubtitle.tr(context: context)}".toText16(isBold: true).toShimmer2(isShow: isLoading), - AppCustomChipWidget( - labelText: isLoading ? "" : getStatusText(context), - backgroundColor: getStatusColor().withOpacity(0.15), - textColor: getStatusColor(), - ).toShimmer2(isShow: isLoading, width: 100.h), - ], - ), - SizedBox(height: 16.h), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // AppCustomChipWidget( + // labelText: isLoading ? "" : getStatusText(context), + // backgroundColor: getStatusColor().withOpacity(0.15), + // textColor: getStatusColor(), + // ).toShimmer2(isShow: isLoading, width: 100.h), + // ], + // ), + // SizedBox(height: 16.h), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/presentation/my_family/widget/family_cards.dart b/lib/presentation/my_family/widget/family_cards.dart index 826b1741..f304fcc3 100644 --- a/lib/presentation/my_family/widget/family_cards.dart +++ b/lib/presentation/my_family/widget/family_cards.dart @@ -102,7 +102,7 @@ class _FamilyCardsState extends State { : profile.status == FamilyFileEnum.active.toInt ? AppColors.lightGreenColor : AppColors.lightGrayBGColor, - chipText: profile.statusDescription ?? "N/A", + chipText: profile.statusDescription ?? " N/A", iconAsset: null, isShowBorder: false, borderRadius: 8.h, @@ -154,7 +154,7 @@ class _FamilyCardsState extends State { crossAxisCount: 2, crossAxisSpacing: 10.w, mainAxisSpacing: 10.h, - childAspectRatio: widget.isShowDetails ? 0.56.h : 0.64.h, + childAspectRatio: widget.isShowDetails ? 0.56.h : 0.74.h, ), padding: EdgeInsets.only(bottom: 20.h), itemBuilder: (context, index) { @@ -164,7 +164,7 @@ class _FamilyCardsState extends State { final canSwitch = isParentUser || (!isParentUser && profile.responseId == appState.getSuperUserID); return Container( padding: EdgeInsets.symmetric(vertical: 15.h, horizontal: 15.h), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), child: Opacity( opacity: isActive || profile.status == FamilyFileEnum.pending.toInt || !canSwitch ? 0.4 : 1.0, // Fade all content if active child: Stack( @@ -187,7 +187,7 @@ class _FamilyCardsState extends State { CustomChipWidget( chipType: ChipTypeEnum.alert, backgroundColor: AppColors.lightGrayBGColor, - chipText: "Relation:${profile.relationship ?? " N/A"}", + chipText: "Relation: ${profile.relationship ?? " N/A"}", iconAsset: AppAssets.heart, isShowBorder: false, borderRadius: 8.h, diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart index e975d6f4..98002ca9 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -24,6 +24,7 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/habib_wallet/habib_wallet_page.dart'; import 'package:hmg_patient_app_new/presentation/habib_wallet/recharge_wallet_page.dart'; import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_update_details_card.dart'; +import 'package:hmg_patient_app_new/presentation/profile_settings/widgets/update_email_widget.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/app_language_change.dart'; @@ -115,7 +116,7 @@ class ProfileSettingsState extends State { // extra space for shadow itemWidth: SizeUtils.width - 30.w, indicatorLayout: PageIndicatorLayout.COLOR, - axisDirection: AxisDirection.right, + axisDirection: getIt.get().isArabic() ? AxisDirection.left : AxisDirection.right, controller: _controller, pagination: SwiperPagination( alignment: Alignment.bottomCenter, @@ -234,24 +235,24 @@ class ProfileSettingsState extends State { ], ), ), - 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.language_change, LocaleKeys.language.tr(context: context), () { - showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.language.tr(context: context), child: AppLanguageChange(), callBackFunc: () {}, isFullScreen: false); - }, trailingLabel: Utils.appState.isArabic() ? "العربية" : "English"), - 1.divider, - actionItem(AppAssets.bell, LocaleKeys.notificationsSettings.tr(context: context), () { - openAppSettings(); - }), - // 1.divider, - // actionItem(AppAssets.touch_face_id, LocaleKeys.touchIDFaceIDServices.tr(context: context), () {}, switchValue: true), - ], - ), - ), + // 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.language_change, LocaleKeys.language.tr(context: context), () { + // showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.language.tr(context: context), child: AppLanguageChange(), callBackFunc: () {}, isFullScreen: false); + // }, trailingLabel: Utils.appState.isArabic() ? "العربية" : "English"), + // 1.divider, + // actionItem(AppAssets.bell, LocaleKeys.notificationsSettings.tr(context: context), () { + // openAppSettings(); + // }), + // // 1.divider, + // // actionItem(AppAssets.touch_face_id, LocaleKeys.touchIDFaceIDServices.tr(context: context), () {}, switchValue: true), + // ], + // ), + // ), 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), @@ -259,7 +260,15 @@ class ProfileSettingsState extends State { decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), child: Column( children: [ - actionItem(AppAssets.email_transparent, LocaleKeys.updateEmailAddress.tr(context: context), () {}), + actionItem(AppAssets.email_transparent, LocaleKeys.updateEmailAddress.tr(context: context), () { + showCommonBottomSheetWithoutHeight( + context, + title: LocaleKeys.updateEmailAddress.tr(context: context), + child: UpdateEmailDialog(), + callBackFunc: () {}, + isFullScreen: false, + ); + }), // 1.divider, // actionItem(AppAssets.smart_phone_fill, "Phone Number".needTranslation, () {}), // 1.divider, @@ -385,10 +394,24 @@ class FamilyCardWidget extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ "${profile.patientName}".toText18(isBold: true, weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 1, isEnglishOnly: true), - AppCustomChipWidget( - icon: AppAssets.file_icon, - labelText: "${LocaleKeys.fileNo.tr(context: context)}: ${profile.responseId}", - iconSize: 12.w, + Wrap( + direction: Axis.horizontal, + spacing: 4.w, + runSpacing: 6.w, + children: [ + AppCustomChipWidget( + labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w), + icon: AppAssets.file_icon, + labelText: "${LocaleKeys.fileno.tr(context: context)}: ${profile.responseId}", + iconSize: 12.w, + ), + isActive ? AppCustomChipWidget( + icon: AppAssets.checkmark_icon, + labelText: LocaleKeys.verified.tr(context: context), + iconColor: AppColors.successColor, + labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w), + ) : SizedBox.shrink(), + ], ), ], ).expanded, @@ -406,13 +429,14 @@ class FamilyCardWidget extends StatelessWidget { AppCustomChipWidget( labelText: LocaleKeys.ageYearsOld.tr(namedArgs: {'age': profile.age.toString(), 'yearsOld': LocaleKeys.yearsOld.tr(context: context)}), ), - isActive && appState.getAuthenticatedUser()!.bloodGroup != null - ? AppCustomChipWidget( - icon: AppAssets.blood_icon, + // isActive && appState.getAuthenticatedUser()!.bloodGroup != null + // ? + isActive ? AppCustomChipWidget( + icon: AppAssets.blood_icon, labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 8.w), - labelText: "Blood: ${appState.getAuthenticatedUser()!.bloodGroup ?? ""}", - iconColor: AppColors.primaryRedColor) - : SizedBox(), + labelText: appState.getAuthenticatedUser()!.bloodGroup ?? "N/A", + iconColor: AppColors.primaryRedColor) + : SizedBox(), Consumer(builder: (context, insuranceVM, child) { return isActive ? AppCustomChipWidget( diff --git a/lib/presentation/profile_settings/widgets/update_email_widget.dart b/lib/presentation/profile_settings/widgets/update_email_widget.dart new file mode 100644 index 00000000..ad9b9d5a --- /dev/null +++ b/lib/presentation/profile_settings/widgets/update_email_widget.dart @@ -0,0 +1,106 @@ +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_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.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/features/profile_settings/profile_settings_view_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/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import 'package:hmg_patient_app_new/widgets/input_widget.dart'; +import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; +import 'package:provider/provider.dart'; + +class UpdateEmailDialog extends StatefulWidget { + UpdateEmailDialog({super.key}); + + @override + State createState() => _UpdateEmailDialogState(); +} + +class _UpdateEmailDialogState extends State { + late FocusNode _textFieldFocusNode; + late TextEditingController? textController; + ProfileSettingsViewModel? profileSettingsViewModel; + + @override + void initState() { + _textFieldFocusNode = FocusNode(); + textController = TextEditingController(); + textController!.text = getIt.get().getAuthenticatedUser()!.emailAddress ?? ""; + super.initState(); + } + + @override + void dispose() { + _textFieldFocusNode.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + profileSettingsViewModel = Provider.of(context); + return GestureDetector( + onTap: () { + _textFieldFocusNode.unfocus(); + FocusScope.of(context).unfocus(); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Enter the new email address to be updated in your HMG File: ".toText16(textAlign: TextAlign.start, weight: FontWeight.w500), + SizedBox(height: 12.h), + TextInputWidget( + labelText: LocaleKeys.email.tr(), + hintText: "demo@gmail.com", + controller: textController, + focusNode: _textFieldFocusNode, + autoFocus: true, + padding: EdgeInsets.all(8.h), + keyboardType: TextInputType.emailAddress, + isEnable: true, + isReadOnly: false, + prefix: null, + isBorderAllowed: false, + isAllowLeadingIcon: true, + fontSize: 14.f, + isCountryDropDown: false, + leadingIcon: AppAssets.email, + fontFamily: "Poppins", + ), + SizedBox(height: 12.h), + CustomButton( + text: LocaleKeys.submit.tr(context: context), + onPressed: () { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.updatingEmailAddress.tr(context: context)); + profileSettingsViewModel!.updatePatientInfo( + patientInfo: {"EmailAddress": textController!.text}, + onSuccess: (response) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.success.tr(context: context), child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr()), + callBackFunc: () async { + Navigator.of(context).pop(); + }, isFullScreen: false); + }, + onError: (error) { + LoaderBottomSheet.hideLoader(); + // Show error message + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(error)), + ); + }, + ); + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: const Color(0xFFffffff), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/symptoms_checker/user_info_selection.dart b/lib/presentation/symptoms_checker/user_info_selection.dart index f1e8413d..b245c014 100644 --- a/lib/presentation/symptoms_checker/user_info_selection.dart +++ b/lib/presentation/symptoms_checker/user_info_selection.dart @@ -100,7 +100,7 @@ class _UserInfoSelectionPageState extends State { children: [ title.toText14(weight: FontWeight.w500), subTitle - .toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500) + .toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500, isEnglishOnly: true) .toShimmer2(isShow: (leadingIcon == AppAssets.rulerIcon || leadingIcon == AppAssets.weightScale) && hmgServicesVM.isVitalSignLoading), ], ), diff --git a/lib/presentation/symptoms_checker/widgets/condition_card.dart b/lib/presentation/symptoms_checker/widgets/condition_card.dart index e48f41ea..d753b780 100644 --- a/lib/presentation/symptoms_checker/widgets/condition_card.dart +++ b/lib/presentation/symptoms_checker/widgets/condition_card.dart @@ -168,7 +168,7 @@ class ConditionCard extends StatelessWidget { crossAxisAlignment: WrapCrossAlignment.center, children: [ for (int i = 0; i < symptoms.length; i++) ...[ - "● ${symptoms[i]}".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + "● ${symptoms[i]}".toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor, isEnglishOnly: true), if (i != symptoms.length - 1) Padding( padding: EdgeInsets.symmetric(horizontal: 2.w), @@ -228,7 +228,7 @@ class ConditionCard extends StatelessWidget { backgroundColor: AppColors.scaffoldBgColor, titleWidget: Row( children: [ - "$percentage%".toText12(fontWeight: FontWeight.bold, color: getChipColorBySeverityEnum(severityEnum)), + "$percentage%".toText12(fontWeight: FontWeight.bold, color: getChipColorBySeverityEnum(severityEnum), isEnglishOnly: true), ], ).paddingSymmetrical(0, 4.h), ), diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index 4a315c6e..b933e530 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -259,7 +259,7 @@ class _ScrollAnimatedTitleState extends State { super.dispose(); } - double t = 0; + double t = 1.0; void _onScroll() { final double offset = widget.controller.offset; diff --git a/pubspec.yaml b/pubspec.yaml index bca92d54..4484fa77 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,8 +2,8 @@ name: hmg_patient_app_new description: "New HMG Patient App" publish_to: 'none' # Remove this line if you wish to publish to pub.dev -#version: 0.0.13+10 -version: 0.0.1+13 +version: 0.0.15+12 +#version: 0.0.1+14 environment: sdk: ">=3.6.0 <4.0.0" From 0ed6103b1527134f3194de2deb5cc452494fd6b5 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 29 Mar 2026 13:58:36 +0300 Subject: [PATCH 11/17] updates --- lib/extensions/widget_extensions.dart | 8 +- lib/presentation/contact_us/contact_us.dart | 41 +- lib/presentation/home/landing_page.dart | 989 ++++++++++-------- .../home/widgets/welcome_widget.dart | 58 +- .../medical_file/medical_file_page.dart | 25 +- .../my_family/widget/family_cards.dart | 371 +++++-- .../profile_settings/profile_settings.dart | 260 ++--- lib/services/dialog_service.dart | 3 +- lib/theme/colors.dart | 2 +- 9 files changed, 1027 insertions(+), 730 deletions(-) diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index 5e4d4e1f..f0897950 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -165,11 +165,11 @@ extension SmoothContainerExtension on ShapeBorder { shadows: hasShadow ? [ BoxShadow( - color: hasDenseShadow ? const Color(0xff000000).withOpacity(.30) : const Color(0xff000000).withOpacity(.1), - // color: AppColors.primaryRedColor.withOpacity(.5), - blurRadius: 10, + // color: hasDenseShadow ? const Color(0xff000000).withOpacity(.06) : const Color(0xff000000).withOpacity(.1), + color: const Color(0xffE1E1E1).withOpacity(1.0), + blurRadius: 0, spreadRadius: 0, - offset: const Offset(0, 0), + offset: const Offset(1, 0), ) ] : [], diff --git a/lib/presentation/contact_us/contact_us.dart b/lib/presentation/contact_us/contact_us.dart index fd0a439b..16a154a1 100644 --- a/lib/presentation/contact_us/contact_us.dart +++ b/lib/presentation/contact_us/contact_us.dart @@ -17,6 +17,7 @@ import 'package:hmg_patient_app_new/presentation/contact_us/live_chat_page.dart' import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher.dart'; class ContactUs extends StatelessWidget { ContactUs({super.key}); @@ -33,6 +34,15 @@ class ContactUs extends StatelessWidget { contactUsViewModel = Provider.of(context); return Column( children: [ + checkInOptionCard( + AppAssets.call_fill, + LocaleKeys.callNow.tr(), + // LocaleKeys.viewNearestHMGLocationsviewNearestHMGLocations.tr(), + "Call for immediate assistance", + ).onPress(() { + launchUrl(Uri.parse("tel://" + "+966 92 006 6666")); + }), + SizedBox(height: 16.h), checkInOptionCard( AppAssets.location, LocaleKeys.findUs.tr(), @@ -46,26 +56,23 @@ class ContactUs extends StatelessWidget { page: FindUsPage(), ), ); + }, onFailure: () { + Navigator.pop(context); + Navigator.of(context).push( + CustomPageRoute( + page: FindUsPage(), + ), + ); + }, onLocationDeniedForever: () { + Navigator.pop(context); + Navigator.of(context).push( + CustomPageRoute( + page: FindUsPage(), + ), + ); }); }), SizedBox(height: 16.h), - checkInOptionCard( - AppAssets.feedbackFill, - LocaleKeys.feedback.tr(), - LocaleKeys.provideFeedbackOnServices.tr(), - ).onPress(() { - contactUsViewModel.setSelectedFeedbackType( - FeedbackType(id: 5, nameEN: "Not classified", nameAR: 'غير محدد'), - ); - contactUsViewModel.setIsSendFeedbackTabSelected(true); - Navigator.pop(context); - Navigator.of(context).push( - CustomPageRoute( - page: FeedbackPage(), - ), - ); - }), - SizedBox(height: 16.h), checkInOptionCard( AppAssets.ask_doctor_icon, LocaleKeys.liveChat.tr(), diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 0c17434e..768a31d1 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -25,6 +25,8 @@ import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_mode import 'package:hmg_patient_app_new/features/hospital/hospital_selection_view_model.dart'; import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart'; import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart'; +import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; +import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/appointment_rating_view_model.dart'; 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'; @@ -45,7 +47,9 @@ import 'package:hmg_patient_app_new/presentation/home/widgets/habib_wallet_card. import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/welcome_widget.dart'; +import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; +import 'package:hmg_patient_app_new/presentation/my_family/my_family.dart'; import 'package:hmg_patient_app_new/presentation/notifications/notifications_list_page.dart'; import 'package:hmg_patient_app_new/presentation/profile_settings/profile_settings.dart'; import 'package:hmg_patient_app_new/presentation/rate_appointment/rate_appointment_doctor.dart'; @@ -53,6 +57,7 @@ import 'package:hmg_patient_app_new/presentation/todo_section/ancillary_procedur import 'package:hmg_patient_app_new/presentation/todo_section/widgets/ancillary_orders_list.dart'; import 'package:hmg_patient_app_new/routes/app_routes.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; +import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/services/zoom_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; @@ -62,6 +67,7 @@ import 'package:hmg_patient_app_new/widgets/countdown_timer.dart'; 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 'package:smooth_corner/smooth_corner.dart'; import '../emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart'; @@ -122,6 +128,7 @@ class _LandingPageState extends State { emergencyServicesViewModel.checkPatientERAdvanceBalance(); // myAppointmentsViewModel.getPatientAppointmentQueueDetails(); notificationsViewModel.initNotificationsViewModel(); + insuranceViewModel.initInsuranceProvider(); // Commented as per new requirement to remove rating popup from the app @@ -160,29 +167,46 @@ class _LandingPageState extends State { canPop: false, child: Scaffold( backgroundColor: AppColors.bgScaffoldColor, - body: SingleChildScrollView( - padding: EdgeInsets.only(top: kToolbarHeight + 0.h, bottom: 24), - child: Column( - spacing: 16.h, + body: Consumer(builder: (context, insuranceVM, child) { + return Stack( children: [ - Row( - spacing: 8.h, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - appState.isAuthenticated - ? WelcomeWidget( - onTap: () { - Navigator.of(context).push(springPageRoute(ProfileSettings())); - }, - name: ('${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}'), - imageUrl: appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.maleImg : AppAssets.femaleImg, - ).expanded - : CustomButton( - text: LocaleKeys.loginOrRegister.tr(context: context), - onPressed: () async { - await authVM.onLoginPressed(); + SingleChildScrollView( + padding: EdgeInsets.only(top: (!insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired) ? (MediaQuery.paddingOf(context).top + 70.h) : kToolbarHeight + 0.h, bottom: 24), + child: Column( + spacing: 16.h, + children: [ + Row( + spacing: 8.h, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + appState.isAuthenticated + ? WelcomeWidget( + onTap: () { + // DialogService dialogService = getIt.get(); + // dialogService.showFamilyBottomSheetWithoutH( + // label: LocaleKeys.familyTitle.tr(context: context), + // message: "", + // isShowManageButton: true, + // onSwitchPress: (FamilyFileResponseModelLists profile) { + // getIt.get().switchFamilyFiles(responseID: profile.responseId, patientID: profile.patientId, phoneNumber: profile.mobileNumber); + // }, + // profiles: getIt.get().patientFamilyFiles); + + Navigator.of(context).push( + CustomPageRoute( + page: FamilyMedicalScreen(), + ), + ); + }, + name: ('${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}'), + imageUrl: appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.maleImg : AppAssets.femaleImg, + ).expanded + : CustomButton( + text: LocaleKeys.loginOrRegister.tr(context: context), + onPressed: () async { + await authVM.onLoginPressed(); - // Navigator.pushReplacementNamed( + // Navigator.pushReplacementNamed( // // context, // context, // AppRoutes.zoomCallPage, @@ -223,476 +247,539 @@ class _LandingPageState extends State { }), (appState.isAuthenticated && (int.parse(todoSectionVM.notificationsCount ?? "0") > 0)) ? Positioned( - right: 0, - top: 0, - child: Container( - width: 8.w, - height: 8.h, - padding: EdgeInsets.all(4), - decoration: BoxDecoration( - color: AppColors.primaryRedColor, - borderRadius: BorderRadius.circular(20.r), - ), - child: Text( - "", - style: TextStyle( - color: Colors.white, - fontSize: 8.f, - ), - textAlign: TextAlign.center, - ), - ), - ) - : SizedBox.shrink(), - ]), - Utils.buildSvgWithAssets(icon: AppAssets.indoor_nav_icon, height: 24.h, width: 24.w).onPress(() { - openIndoorNavigationBottomSheet(context); - }), - Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 24.h, width: 24.h).onPress(() { - showCommonBottomSheetWithoutHeight( - context, + right: 0, + top: 0, + child: Container( + width: 8.w, + height: 8.h, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: AppColors.primaryRedColor, + borderRadius: BorderRadius.circular(20.r), + ), + child: Text( + "", + style: TextStyle( + color: Colors.white, + fontSize: 8.f, + ), + textAlign: TextAlign.center, + ), + ), + ) + : SizedBox.shrink(), + ]), + Utils.buildSvgWithAssets(icon: AppAssets.location, height: 24.h, width: 24.w).onPress(() { + // openIndoorNavigationBottomSheet(context); + showCommonBottomSheetWithoutHeight( + context, title: LocaleKeys.contactUs.tr(), child: ContactUs(), callBackFunc: () {}, isFullScreen: false, ); }), - !appState.isAuthenticated - ? Utils.buildSvgWithAssets(icon: appState.isArabic() ? AppAssets.enLangIcon : AppAssets.arLangIcon, height: 24.h, width: 24.h).onPress(() { - context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA')); - }) - : SizedBox.shrink() - ], + // Utils.buildSvgWithAssets(icon: AppAssets.contact_icon, height: 24.h, width: 24.h).onPress(() { + // showCommonBottomSheetWithoutHeight( + // context, + // title: LocaleKeys.contactUs.tr(), + // child: ContactUs(), + // callBackFunc: () {}, + // isFullScreen: false, + // ); + // }), + !appState.isAuthenticated + ? Utils.buildSvgWithAssets(icon: appState.isArabic() ? AppAssets.enLangIcon : AppAssets.arLangIcon, height: 24.h, width: 24.h).onPress(() { + context.setLocale(appState.isArabic() ? Locale('en', 'US') : Locale('ar', 'SA')); + }) + : SizedBox.shrink() + ], ); }), ], ).paddingSymmetrical(24.h, 0.h), !appState.isAuthenticated ? Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: false, - ), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Row( - children: [ - Utils.buildSvgWithAssets( - width: 50.w, - height: 60.h, - icon: AppAssets.symptomCheckerIcon, - fit: BoxFit.contain, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: false, ), - SizedBox(width: 12.w), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.howAreYouFeelingToday.tr(context: context).toText14(weight: FontWeight.w600), - LocaleKeys.checkYourSymptomsWithScale.tr(context: context).toText12(fontWeight: FontWeight.w500), - SizedBox(height: 14.h), - CustomButton( - text: LocaleKeys.checkYourSymptoms.tr(context: context), - onPressed: () async { - context.navigateWithName(AppRoutes.userInfoSelection); - }, - padding: EdgeInsetsGeometry.zero, - backgroundColor: AppColors.primaryRedColor, - borderColor: AppColors.primaryRedColor, - textColor: Colors.white, - fontSize: 14.f, - fontWeight: FontWeight.w600, - borderRadius: 12.r, - height: 40.h, - ), - ], - ).expanded - ], - ), - ), - ).paddingSymmetrical(24.w, 0.h) - : SizedBox.shrink(), - appState.isAuthenticated - ? Column( - children: [ - SizedBox(height: 12.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(weight: FontWeight.w600), - Row( - children: [ - LocaleKeys.viewAll.tr(context: context).toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500), - SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), - ], + child: Padding( + padding: EdgeInsets.all(16.h), + child: Row( + children: [ + Utils.buildSvgWithAssets( + width: 50.w, + height: 60.h, + icon: AppAssets.symptomCheckerIcon, + fit: BoxFit.contain, + ), + SizedBox(width: 12.w), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.howAreYouFeelingToday.tr(context: context).toText14(weight: FontWeight.w600), + LocaleKeys.checkYourSymptomsWithScale.tr(context: context).toText12(fontWeight: FontWeight.w500), + SizedBox(height: 14.h), + CustomButton( + text: LocaleKeys.checkYourSymptoms.tr(context: context), + onPressed: () async { + context.navigateWithName(AppRoutes.userInfoSelection); + }, + padding: EdgeInsetsGeometry.zero, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: Colors.white, + fontSize: 14.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + height: 40.h, + ), + ], + ).expanded + ], + ), ), - ], - ).paddingSymmetrical(24.h, 0.h).onPress(() { - Navigator.of(context).push(CustomPageRoute(page: MyAppointmentsPage())); - }), - Consumer3( - builder: (context, myAppointmentsVM, immediateLiveCareVM, todoSectionVM, child) { - return myAppointmentsVM.isMyAppointmentsLoading - ? Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - ), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(), - myAppointmentsViewModel: myAppointmentsViewModel, - bookAppointmentsViewModel: bookAppointmentsViewModel, - isLoading: true, - isFromHomePage: true, - ), - ).paddingSymmetrical(24.h, 16.h) - : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty - ? myAppointmentsVM.patientAppointmentsHistoryList.length == 1 - ? Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 24.r, - hasShadow: true, - ), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList.first, - myAppointmentsViewModel: myAppointmentsViewModel, - bookAppointmentsViewModel: bookAppointmentsViewModel, - isLoading: false, - isFromHomePage: true, - ), - ).paddingSymmetrical(24.h, 0.h) - : isTablet - ? SizedBox( - height: isFoldable ? 290.h : 255.h, - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: 3, - shrinkWrap: true, - padding: EdgeInsets.only(left: 16.h, right: 16.h), - itemBuilder: (context, index) { - return SizedBox( - height: 255.h, - width: 250.w, - child: getIndexSwiperCard(index), - ); - // return AnimationConfiguration.staggeredList( - // position: index, - // duration: const Duration(milliseconds: 1000), - // child: SlideAnimation( - // horizontalOffset: 100.0, - // child: FadeInAnimation( - // child: SizedBox( - // height: 255.h, - // width: 250.w, - // child: getIndexSwiperCard(index), - // ), - // ), - // ), - // ); - }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox( - width: 10.w, + ).paddingSymmetrical(24.w, 0.h) + : SizedBox.shrink(), + appState.isAuthenticated + ? Column( + children: [ + SizedBox(height: 12.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.appointmentsAndVisits.tr(context: context).toText16(weight: FontWeight.w600), + Row( + children: [ + LocaleKeys.viewAll.tr(context: context).toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500), + SizedBox(width: 2.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), + ], + ), + ], + ).paddingSymmetrical(24.h, 0.h).onPress(() { + Navigator.of(context).push(CustomPageRoute(page: MyAppointmentsPage())); + }), + Consumer3( + builder: (context, myAppointmentsVM, immediateLiveCareVM, todoSectionVM, child) { + return myAppointmentsVM.isMyAppointmentsLoading + ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: true, + ), + child: AppointmentCard( + patientAppointmentHistoryResponseModel: PatientAppointmentHistoryResponseModel(), + myAppointmentsViewModel: myAppointmentsViewModel, + bookAppointmentsViewModel: bookAppointmentsViewModel, + isLoading: true, + isFromHomePage: true, + ), + ).paddingSymmetrical(24.h, 16.h) + : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty + ? myAppointmentsVM.patientAppointmentsHistoryList.length == 1 + ? Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: true, ), - ), - ) - : SizedBox( - height: 255.h + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space - child: Swiper( - itemCount: myAppointmentsVM.isMyAppointmentsLoading - ? 3 - : myAppointmentsVM.patientAppointmentsHistoryList.length < 3 - ? myAppointmentsVM.patientAppointmentsHistoryList.length - : 3, - layout: SwiperLayout.STACK, - loop: false, - itemWidth: MediaQuery.of(context).size.width - 48.h, - indicatorLayout: PageIndicatorLayout.COLOR, - axisDirection: getIt.get().isArabic() ? AxisDirection.left : AxisDirection.right, - controller: _controller, - itemHeight: 255.h + 20, - // extra space for shadow - pagination: SwiperPagination( - alignment: Alignment.bottomCenter, - margin: EdgeInsets.only(top: 220.h + 20 + 8 + 24), - builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor), + child: AppointmentCard( + patientAppointmentHistoryResponseModel: myAppointmentsVM.patientAppointmentsHistoryList.first, + myAppointmentsViewModel: myAppointmentsViewModel, + bookAppointmentsViewModel: bookAppointmentsViewModel, + isLoading: false, + isFromHomePage: true, ), - itemBuilder: (BuildContext context, int index) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 10), - child: getIndexSwiperCard(index), - ); - }, + ).paddingSymmetrical(24.h, 0.h) + : isTablet + ? SizedBox( + height: isFoldable ? 290.h : 255.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: 3, + shrinkWrap: true, + padding: EdgeInsets.only(left: 16.h, right: 16.h), + itemBuilder: (context, index) { + return SizedBox( + height: 255.h, + width: 250.w, + child: getIndexSwiperCard(index), + ); + // return AnimationConfiguration.staggeredList( + // position: index, + // duration: const Duration(milliseconds: 1000), + // child: SlideAnimation( + // horizontalOffset: 100.0, + // child: FadeInAnimation( + // child: SizedBox( + // height: 255.h, + // width: 250.w, + // child: getIndexSwiperCard(index), + // ), + // ), + // ), + // ); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox( + width: 10.w, + ), + ), + ) + : SizedBox( + height: 255.h + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space + child: Swiper( + itemCount: myAppointmentsVM.isMyAppointmentsLoading + ? 3 + : myAppointmentsVM.patientAppointmentsHistoryList.length < 3 + ? myAppointmentsVM.patientAppointmentsHistoryList.length + : 3, + layout: SwiperLayout.STACK, + loop: false, + itemWidth: MediaQuery.of(context).size.width - 48.h, + indicatorLayout: PageIndicatorLayout.COLOR, + axisDirection: getIt.get().isArabic() ? AxisDirection.left : AxisDirection.right, + controller: _controller, + itemHeight: 255.h + 20, + // extra space for shadow + pagination: SwiperPagination( + alignment: Alignment.bottomCenter, + margin: EdgeInsets.only(top: 220.h + 20 + 8 + 24), + builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor), + ), + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: getIndexSwiperCard(index), + ); + }, + ), + ) + : Container( + width: double.infinity, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), + SizedBox(height: 12.h), + LocaleKeys.noUpcomingAppointmentPleaseBook.tr(context: context).toText12(isCenter: true), + SizedBox(height: 12.h), + CustomButton( + text: LocaleKeys.bookAppo.tr(context: context), + onPressed: () { + getIt.get().onTabChanged(0); + Navigator.of(context).push(CustomPageRoute(page: BookAppointmentPage())); + }, + backgroundColor: Color(0xffFEE9EA), + borderColor: Color(0xffFEE9EA), + textColor: Color(0xffED1C2B), + fontSize: 14.f, + fontWeight: FontWeight.w500, + padding: EdgeInsets.fromLTRB(10.h, 0, 10.h, 0), + icon: AppAssets.add_icon, + iconColor: AppColors.primaryRedColor, + height: 40.h, + ), + ], ), - ) - : Container( - width: double.infinity, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r, hasShadow: true), - child: Padding( - padding: EdgeInsets.all(16.h), - child: Column( - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.home_calendar_icon, width: 32.h, height: 32.h), - SizedBox(height: 12.h), - LocaleKeys.noUpcomingAppointmentPleaseBook.tr(context: context).toText12(isCenter: true), - SizedBox(height: 12.h), - CustomButton( - text: LocaleKeys.bookAppo.tr(context: context), - onPressed: () { - getIt.get().onTabChanged(0); - Navigator.of(context).push(CustomPageRoute(page: BookAppointmentPage())); - }, - backgroundColor: Color(0xffFEE9EA), - borderColor: Color(0xffFEE9EA), - textColor: Color(0xffED1C2B), - fontSize: 14.f, - fontWeight: FontWeight.w500, - padding: EdgeInsets.fromLTRB(10.h, 0, 10.h, 0), - icon: AppAssets.add_icon, - iconColor: AppColors.primaryRedColor, - height: 40.h, ), - ], - ), - ), - ).paddingSymmetrical(24.h, 16.h); - }, - ), + ).paddingSymmetrical(24.h, 16.h); + }, + ), - // Consumer for ER Online Check-In pending request - Consumer( - builder: (context, emergencyServicesVM, child) { - return emergencyServicesVM.patientHasAdvanceERBalance - ? Column( + // Consumer for ER Online Check-In pending request + Consumer( + builder: (context, emergencyServicesVM, child) { + return emergencyServicesVM.patientHasAdvanceERBalance + ? Column( + children: [ + SizedBox(height: 16.h), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.r, + hasShadow: false, + side: BorderSide(color: AppColors.primaryRedColor, width: 3.h), + ), + width: double.infinity, + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // AppCustomChipWidget( + // labelText: LocaleKeys.erOnlineCheckInRequest.tr(context: context), + // 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), + // ], + // ), + SizedBox(height: 8.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - SizedBox(height: 16.h), - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.r, - hasShadow: false, - side: BorderSide(color: AppColors.primaryRedColor, width: 3.h), - ), - width: double.infinity, - child: Padding( - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - AppCustomChipWidget( - labelText: LocaleKeys.erOnlineCheckInRequest.tr(context: context), - 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), - ], - ), - SizedBox(height: 8.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.youHaveEROnlineCheckInRequest.tr(context: context).toText12(isBold: true), - Transform.flip( - flipX: getIt.get().isArabic(), - child: Utils.buildSvgWithAssets( - icon: AppAssets.forward_arrow_icon_small, - iconColor: AppColors.blackColor, - width: 20.h, - height: 15.h, - fit: BoxFit.contain, - ), - ), - ], - ), - ], - ), + LocaleKeys.youHaveEROnlineCheckInRequest.tr(context: context).toText12(isBold: true), + Transform.flip( + flipX: getIt.get().isArabic(), + child: Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon_small, + iconColor: AppColors.blackColor, + width: 20.h, + height: 15.h, + fit: BoxFit.contain, ), - ).paddingSymmetrical(24.h, 0.h).onPress(() { - Navigator.of(context).push(CustomPageRoute(page: ErOnlineCheckinHome())); - // context.read().navigateToEROnlineCheckIn(); - }), - SizedBox(height: 12.h), + ), ], - ) - : SizedBox(height: 0.h); - }, + ), + ], + ), + ), + ).paddingSymmetrical(24.h, 0.h).onPress(() { + Navigator.of(context).push(CustomPageRoute(page: ErOnlineCheckinHome())); + // context.read().navigateToEROnlineCheckIn(); + }), + SizedBox(height: 12.h), + ], + ) + : SizedBox(height: 0.h); + }, + ), + SizedBox(height: 16.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.quickLinks.tr(context: context).toText16(weight: FontWeight.w600), + Row( + children: [ + LocaleKeys.viewMedicalFile.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), + SizedBox(width: 2.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), + ], + ), + ], + ).paddingSymmetrical(24.h, 0.h).onPress(() { + Navigator.of(context).push(CustomPageRoute(page: MedicalFilePage())); + }), + SizedBox(height: 16.h), + Container( + // height: 121.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), + child: Column( + children: [ + SizedBox( + height: 92.h + 32.h - 4.h, + child: RawScrollbar( + controller: _horizontalScrollController, + thumbVisibility: true, + radius: Radius.circular(10.0), + thumbColor: AppColors.primaryRedColor, + trackVisibility: true, + trackColor: Color(0xffD9D9D9), + trackBorderColor: Colors.transparent, + trackRadius: Radius.circular(10.0), + padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery + .sizeOf(context) + .width / 2 - 35, right: MediaQuery + .sizeOf(context) + .width / 2 - 35), + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: LandingPageData.getLoggedInServiceCardsList.length, + shrinkWrap: true, + controller: _horizontalScrollController, + padding: EdgeInsets.only(left: 16.h, right: 16.h, top: 16.h, bottom: 12.h), + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: SmallServiceCard( + icon: LandingPageData.getLoggedInServiceCardsList[index].icon, + title: LandingPageData.getLoggedInServiceCardsList[index].title, + subtitle: LandingPageData.getLoggedInServiceCardsList[index].subtitle, + iconColor: LandingPageData.getLoggedInServiceCardsList[index].iconColor!, + textColor: LandingPageData.getLoggedInServiceCardsList[index].textColor, + backgroundColor: LandingPageData.getLoggedInServiceCardsList[index].backgroundColor, + isBold: LandingPageData.getLoggedInServiceCardsList[index].isBold, + serviceName: LandingPageData.getLoggedInServiceCardsList[index].serviceName, + ), + ), + ), + ); + }, + separatorBuilder: (BuildContext cxt, int index) => 10.width, + ), + ), ), SizedBox(height: 16.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.quickLinks.tr(context: context).toText16(weight: FontWeight.w600), - Row( + ], + ), + ).paddingSymmetrical(24.h, 0.h), + ], + ) + : Container( + // height: 141.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), + child: Column( children: [ - LocaleKeys.viewMedicalFile.tr(context: context).toText12(color: AppColors.primaryRedColor, fontWeight: FontWeight.w500), - SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), + SizedBox( + height: 92.h + 32.h - 4.h, + child: RawScrollbar( + controller: _horizontalScrollController, + thumbVisibility: true, + radius: Radius.circular(10.0), + thumbColor: AppColors.primaryRedColor, + trackVisibility: true, + trackColor: Color(0xffD9D9D9), + trackBorderColor: Colors.transparent, + trackRadius: Radius.circular(10.0), + padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery.sizeOf(context).width / 2 - 35, right: MediaQuery.sizeOf(context).width / 2 - 35), + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: LandingPageData.getNotLoggedInServiceCardsList.length, + shrinkWrap: true, + controller: _horizontalScrollController, + padding: EdgeInsets.only(left: 16.h, right: 16.h, top: 16.h, bottom: 12.h), + // padding: EdgeInsets.zero, + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: SmallServiceCard( + serviceName: LandingPageData.getNotLoggedInServiceCardsList[index].serviceName, + icon: LandingPageData.getNotLoggedInServiceCardsList[index].icon, + title: LandingPageData.getNotLoggedInServiceCardsList[index].title, + subtitle: LandingPageData.getNotLoggedInServiceCardsList[index].subtitle, + iconColor: LandingPageData.getNotLoggedInServiceCardsList[index].iconColor!, + textColor: LandingPageData.getNotLoggedInServiceCardsList[index].textColor, + backgroundColor: LandingPageData.getNotLoggedInServiceCardsList[index].backgroundColor, + isBold: LandingPageData.getNotLoggedInServiceCardsList[index].isBold, + ), + ), + ), + ); + }, + separatorBuilder: (BuildContext cxt, int index) => 0.width, + ), + ), + ), + SizedBox(height: 16.h), ], ), + ).paddingSymmetrical(24.h, 0.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.services2.tr(context: context).toText18(weight: FontWeight.w600), + Row( + children: [ + LocaleKeys.viewAllServices.tr(context: context).toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500), + SizedBox(width: 2.h), + Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), ], - ).paddingSymmetrical(24.h, 0.h).onPress(() { - Navigator.of(context).push(CustomPageRoute(page: MedicalFilePage())); + ).onPress(() { + Navigator.of(context).push(CustomPageRoute(page: ServicesPage())); }), - SizedBox(height: 16.h), - Container( - // height: 121.h, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), - child: Column( + ], + ).paddingSymmetrical(24.w, 0.h), + SizedBox( + height: 431.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: LandingPageData.getServiceCardsList.length, + shrinkWrap: true, + padding: EdgeInsets.only(left: 24.w, right: 24.w), + itemBuilder: (context, index) { + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 1000), + child: SlideAnimation( + horizontalOffset: 100.0, + child: FadeInAnimation( + child: FadedLargeServiceCard( + serviceCardData: LandingPageData.getServiceCardsList[index], + image: LandingPageData.getServiceCardsList[index].icon, + title: LandingPageData.getServiceCardsList[index].title, + subtitle: LandingPageData.getServiceCardsList[index].subtitle, + icon: LandingPageData.getServiceCardsList[index].largeCardIcon, + ), + ), + ), + ); + }, + separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 16.w), + ), + ), + appState.isAuthenticated ? HabibWalletCard() : SizedBox(), + ], + ), + ), + (!insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired) + ? Container( + height: MediaQuery.paddingOf(context).top + 50.h, + decoration: ShapeDecoration( + color: AppColors.secondaryLightRedBorderColor, + shape: SmoothRectangleBorder( + side: BorderSide(width: 1, color: AppColors.primaryRedColor.withAlpha(20)), + // borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)), + smoothness: 1, + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - SizedBox( - height: 92.h + 32.h - 4.h, - child: RawScrollbar( - controller: _horizontalScrollController, - thumbVisibility: true, - radius: Radius.circular(10.0), - thumbColor: AppColors.primaryRedColor, - trackVisibility: true, - trackColor: Color(0xffD9D9D9), - trackBorderColor: Colors.transparent, - trackRadius: Radius.circular(10.0), - padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery.sizeOf(context).width / 2 - 35, right: MediaQuery.sizeOf(context).width / 2 - 35), - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: LandingPageData.getLoggedInServiceCardsList.length, - shrinkWrap: true, - controller: _horizontalScrollController, - padding: EdgeInsets.only(left: 16.h, right: 16.h, top: 16.h, bottom: 12.h), - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: SmallServiceCard( - icon: LandingPageData.getLoggedInServiceCardsList[index].icon, - title: LandingPageData.getLoggedInServiceCardsList[index].title, - subtitle: LandingPageData.getLoggedInServiceCardsList[index].subtitle, - iconColor: LandingPageData.getLoggedInServiceCardsList[index].iconColor!, - textColor: LandingPageData.getLoggedInServiceCardsList[index].textColor, - backgroundColor: LandingPageData.getLoggedInServiceCardsList[index].backgroundColor, - isBold: LandingPageData.getLoggedInServiceCardsList[index].isBold, - serviceName: LandingPageData.getLoggedInServiceCardsList[index].serviceName, - ), - ), + LocaleKeys.insuranceExpiredOrInactive.tr(context: context).toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500).paddingSymmetrical(24.h, 0.h), + Row( + children: [ + CustomButton( + text: LocaleKeys.updateInsurance.tr(context: context), + onPressed: () { + Navigator.of(context).push( + CustomPageRoute( + page: InsuranceHomePage(), ), ); }, - separatorBuilder: (BuildContext cxt, int index) => 10.width, - ), - ), + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.secondaryLightRedBorderColor, + textColor: AppColors.whiteColor, + fontSize: 10.f, + fontWeight: FontWeight.bold, + borderRadius: 8.r, + padding: EdgeInsets.fromLTRB(15, 0, 15, 0), + height: 36.h, + ).paddingSymmetrical(24.h, 0.h), + ], ), - SizedBox(height: 16.h), ], ), - ).paddingSymmetrical(24.h, 0.h), - ], - ) - : Container( - // height: 141.h, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), - child: Column( - children: [ SizedBox( - height: 92.h + 32.h - 4.h, - child: RawScrollbar( - controller: _horizontalScrollController, - thumbVisibility: true, - radius: Radius.circular(10.0), - thumbColor: AppColors.primaryRedColor, - trackVisibility: true, - trackColor: Color(0xffD9D9D9), - trackBorderColor: Colors.transparent, - trackRadius: Radius.circular(10.0), - padding: EdgeInsets.only(top: 92.h + 32.h, left: MediaQuery.sizeOf(context).width / 2 - 35, right: MediaQuery.sizeOf(context).width / 2 - 35), - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: LandingPageData.getNotLoggedInServiceCardsList.length, - shrinkWrap: true, - controller: _horizontalScrollController, - padding: EdgeInsets.only(left: 16.h, right: 16.h, top: 16.h, bottom: 12.h), - // padding: EdgeInsets.zero, - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: SmallServiceCard( - serviceName: LandingPageData.getNotLoggedInServiceCardsList[index].serviceName, - icon: LandingPageData.getNotLoggedInServiceCardsList[index].icon, - title: LandingPageData.getNotLoggedInServiceCardsList[index].title, - subtitle: LandingPageData.getNotLoggedInServiceCardsList[index].subtitle, - iconColor: LandingPageData.getNotLoggedInServiceCardsList[index].iconColor!, - textColor: LandingPageData.getNotLoggedInServiceCardsList[index].textColor, - backgroundColor: LandingPageData.getNotLoggedInServiceCardsList[index].backgroundColor, - isBold: LandingPageData.getNotLoggedInServiceCardsList[index].isBold, - ), - ), - ), - ); - }, - separatorBuilder: (BuildContext cxt, int index) => 0.width, - ), - ), - ), - SizedBox(height: 16.h), + height: 10.h, + ) ], ), - ).paddingSymmetrical(24.h, 0.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.services2.tr(context: context).toText18(weight: FontWeight.w600), - Row( - children: [ - LocaleKeys.viewAllServices.tr(context: context).toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500), - SizedBox(width: 2.h), - Icon(Icons.arrow_forward_ios, color: AppColors.primaryRedColor, size: 14.h), - ], - ).onPress(() { - Navigator.of(context).push(CustomPageRoute(page: ServicesPage())); - }), - ], - ).paddingSymmetrical(24.w, 0.h), - SizedBox( - height: 431.h, - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: LandingPageData.getServiceCardsList.length, - shrinkWrap: true, - padding: EdgeInsets.only(left: 24.w, right: 24.w), - itemBuilder: (context, index) { - return AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - horizontalOffset: 100.0, - child: FadeInAnimation( - child: FadedLargeServiceCard( - serviceCardData: LandingPageData.getServiceCardsList[index], - image: LandingPageData.getServiceCardsList[index].icon, - title: LandingPageData.getServiceCardsList[index].title, - subtitle: LandingPageData.getServiceCardsList[index].subtitle, - icon: LandingPageData.getServiceCardsList[index].largeCardIcon, - ), - ), - ), - ); - }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(width: 16.w), - ), - ), - appState.isAuthenticated ? HabibWalletCard() : SizedBox(), + ) + : SizedBox.shrink() ], - ), - ), + ); + }), ), ); } diff --git a/lib/presentation/home/widgets/welcome_widget.dart b/lib/presentation/home/widgets/welcome_widget.dart index 21f01c8b..9b613e64 100644 --- a/lib/presentation/home/widgets/welcome_widget.dart +++ b/lib/presentation/home/widgets/welcome_widget.dart @@ -1,10 +1,20 @@ 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/dependencies.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/insurance/insurance_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart'; +import 'package:hmg_patient_app_new/presentation/profile_settings/profile_settings.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +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:smooth_corner/smooth_corner.dart'; class WelcomeWidget extends StatelessWidget { final String name; @@ -20,33 +30,41 @@ class WelcomeWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return InkWell( - onTap: onTap, - borderRadius: BorderRadius.circular(30), - child: Row( - mainAxisSize: MainAxisSize.min, - spacing: 8.h, - children: [ - Image.asset(imageUrl, width: 40, height: 40), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 4.h, + return Column( + children: [ + InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(30), + child: Row( mainAxisSize: MainAxisSize.min, + spacing: 8.h, children: [ - LocaleKeys.welcome.tr(context: context).toText14(color: AppColors.greyTextColor, height: 1, weight: FontWeight.w500), - Row( + Icon(Icons.menu, color: AppColors.textColor).onPress(() { + Navigator.of(context).push(springPageRoute(ProfileSettings())); + }), + Image.asset(imageUrl, width: 40, height: 40), + Column( + crossAxisAlignment: CrossAxisAlignment.start, spacing: 4.h, - crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ - Flexible(child: name.toText16(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1, height: 1, isEnglishOnly: true)), - Icon(Icons.keyboard_arrow_down, size: 20, color: AppColors.greyTextColor), + LocaleKeys.welcome.tr(context: context).toText14(color: AppColors.greyTextColor, height: 1, weight: FontWeight.w500), + Row( + spacing: 4.h, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Flexible(child: name.toText16(weight: FontWeight.w500, textOverflow: TextOverflow.ellipsis, maxlines: 1, height: 1, isEnglishOnly: true)), + // Icon(Icons.keyboard_arrow_down, size: 20, color: AppColors.greyTextColor), + Utils.buildSvgWithAssets(icon: AppAssets.arrowRight, height: 22.h, width: 22.w) + ], + ), ], - ), + ).expanded, ], - ).expanded, - ], - ), + ), + ), + ], ); } } diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 1c839c10..5301d2e0 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -199,18 +199,23 @@ class _MedicalFilePageState extends State { ], ), SizedBox(width: 4.h), - Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, height: 22.h, width: 22.w) + Utils.buildSvgWithAssets(icon: AppAssets.arrowRight, height: 22.h, width: 22.w) ], ).onPress(() { - DialogService dialogService = getIt.get(); - dialogService.showFamilyBottomSheetWithoutH( - label: LocaleKeys.familyTitle.tr(context: context), - message: "", - isShowManageButton: true, - onSwitchPress: (FamilyFileResponseModelLists profile) { - medicalFileViewModel.switchFamilyFiles(responseID: profile.responseId, patientID: profile.patientId, phoneNumber: profile.mobileNumber); - }, - profiles: medicalFileViewModel.patientFamilyFiles); + Navigator.of(context).push( + CustomPageRoute( + page: FamilyMedicalScreen(), + ), + ); + // DialogService dialogService = getIt.get(); + // dialogService.showFamilyBottomSheetWithoutH( + // label: LocaleKeys.familyTitle.tr(context: context), + // message: "", + // isShowManageButton: true, + // onSwitchPress: (FamilyFileResponseModelLists profile) { + // medicalFileViewModel.switchFamilyFiles(responseID: profile.responseId, patientID: profile.patientId, phoneNumber: profile.mobileNumber); + // }, + // profiles: medicalFileViewModel.patientFamilyFiles); }), isLeading: widget.showBackIcon, // leadingCallback: () { diff --git a/lib/presentation/my_family/widget/family_cards.dart b/lib/presentation/my_family/widget/family_cards.dart index f304fcc3..a621168f 100644 --- a/lib/presentation/my_family/widget/family_cards.dart +++ b/lib/presentation/my_family/widget/family_cards.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -9,16 +11,22 @@ 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/habib_wallet/habib_wallet_view_model.dart'; +import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_update_details_card.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/buttons/custom_button.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/common_bottom_sheet.dart'; +import 'package:provider/provider.dart'; class FamilyCards extends StatefulWidget { final List profiles; + late List? profileViewList; final Function(FamilyFileResponseModelLists) onSelect; final Function(FamilyFileResponseModelLists) onRemove; final bool isShowDetails; @@ -28,11 +36,12 @@ class FamilyCards extends StatefulWidget { final bool isShowRemoveButton; final bool isForWalletRecharge; - const FamilyCards( + FamilyCards( {super.key, required this.profiles, required this.onSelect, required this.onRemove, + this.profileViewList, this.isShowDetails = false, this.isBottomSheet = false, this.isRequestDesign = false, @@ -46,9 +55,22 @@ class FamilyCards extends StatefulWidget { class _FamilyCardsState extends State { AppState appState = getIt(); + late InsuranceViewModel insuranceViewModel; + + @override + void initState() { + scheduleMicrotask(() { + insuranceViewModel.initInsuranceProvider(); + }); + super.initState(); + } @override Widget build(BuildContext context) { + widget.profileViewList = []; + widget.profileViewList!.addAll(widget.profiles); + widget.profileViewList!.removeWhere((element) => element.responseId == appState.getAuthenticatedUser()?.patientId); + insuranceViewModel = Provider.of(context, listen: false); DialogService dialogService = getIt.get(); if (widget.isRequestDesign) { return Column( @@ -71,15 +93,15 @@ class _FamilyCardsState extends State { ], ), SizedBox(height: 24.h), - widget.profiles.where((profile) => profile.isRequestFromMySide ?? false).isEmpty + widget.profileViewList!.where((profile) => profile.isRequestFromMySide ?? false).isEmpty ? Utils.getNoDataWidget(context) : ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, - itemCount: widget.profiles.where((profile) => profile.isRequestFromMySide ?? false).length, + itemCount: widget.profileViewList!.where((profile) => profile.isRequestFromMySide ?? false).length, itemBuilder: (context, index) { - final mySideProfiles = widget.profiles.where((profile) => profile.isRequestFromMySide ?? false).toList(); + final mySideProfiles = widget.profileViewList!.where((profile) => profile.isRequestFromMySide ?? false).toList(); FamilyFileResponseModelLists profile = mySideProfiles[index]; return Container( margin: EdgeInsets.only(bottom: 12.h), @@ -146,113 +168,252 @@ class _FamilyCardsState extends State { ], ); } else { - return GridView.builder( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemCount: widget.profiles.length, - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - crossAxisSpacing: 10.w, - mainAxisSpacing: 10.h, - childAspectRatio: widget.isShowDetails ? 0.56.h : 0.74.h, - ), - padding: EdgeInsets.only(bottom: 20.h), - itemBuilder: (context, index) { - final profile = widget.profiles[index]; - final isActive = (profile.responseId == appState.getAuthenticatedUser()?.patientId); - final isParentUser = appState.getAuthenticatedUser()?.isParentUser ?? false; - final canSwitch = isParentUser || (!isParentUser && profile.responseId == appState.getSuperUserID); - return Container( - padding: EdgeInsets.symmetric(vertical: 15.h, horizontal: 15.h), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), - child: Opacity( - opacity: isActive || profile.status == FamilyFileEnum.pending.toInt || !canSwitch ? 0.4 : 1.0, // Fade all content if active - child: Stack( + return Column( + children: [ + Container( + width: double.infinity, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 12.r), + child: Padding( + padding: EdgeInsets.all(16.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Column( - mainAxisSize: MainAxisSize.min, + Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Utils.buildImgWithAssets( - icon: profile.gender == null - ? AppAssets.dummyUser - : profile.gender == 1 - ? ((profile.age ?? 0) < 7 ? AppAssets.babyBoyImg : AppAssets.maleImg) - : (profile.age! < 7 ? AppAssets.babyGirlImg : AppAssets.femaleImg), - width: 72.h, - height: 70.h, + Image.asset(appState.getAuthenticatedUser()?.gender == 1 ? AppAssets.maleImg : AppAssets.femaleImg, width: 56.w, height: 56.h), + SizedBox(width: 8.w), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: MediaQuery.of(context).size.width * 0.6, + child: "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}" + .toText18(isBold: true, weight: FontWeight.w600, textOverflow: TextOverflow.ellipsis, maxlines: 2), + ), + SizedBox(height: 4.h), + Wrap( + direction: Axis.horizontal, + spacing: 4.w, + runSpacing: 6.w, + children: [ + AppCustomChipWidget( + icon: AppAssets.file_icon, + richText: "${LocaleKeys.fileno.tr(context: context)}: ${appState.getAuthenticatedUser()!.patientId}".toText10(isEnglishOnly: true), + labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), + ), + AppCustomChipWidget( + icon: AppAssets.checkmark_icon, + labelText: LocaleKeys.verified.tr(context: context), + iconColor: AppColors.successColor, + labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: 6.w), + ), + ], + ), + ], + ) + ], + ), + SizedBox(height: 16.h), + Divider(color: AppColors.dividerColor, height: 1.h), + SizedBox(height: 16.h), + Wrap( + direction: Axis.horizontal, + spacing: 4.h, + runSpacing: 4.h, + children: [ + AppCustomChipWidget( + 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), ), - SizedBox(height: 8.h), - (profile.patientName ?? "Unknown").toText14(isBold: false, isCenter: true, maxlines: 1, weight: FontWeight.w600), - SizedBox(height: 8.h), - CustomChipWidget( - chipType: ChipTypeEnum.alert, - backgroundColor: AppColors.lightGrayBGColor, - chipText: "Relation: ${profile.relationship ?? " N/A"}", - iconAsset: AppAssets.heart, - isShowBorder: false, - borderRadius: 8.h, - textColor: AppColors.textColor), - widget.isShowDetails ? SizedBox(height: 4.h) : SizedBox(), - widget.isShowDetails - ? CustomChipWidget( + AppCustomChipWidget( + icon: AppAssets.blood_icon, + labelText: appState.getUserBloodGroup.isEmpty ? "N/A" : appState.getUserBloodGroup, + iconColor: AppColors.primaryRedColor, + labelPadding: EdgeInsetsDirectional.only(start: -6.w, end: 6.w), + padding: EdgeInsets.zero, + ), + Consumer(builder: (context, insuranceVM, child) { + return AppCustomChipWidget( + icon: insuranceVM.isInsuranceExpired + ? AppAssets.cancel_circle_icon + : insuranceVM.isInsuranceActive + ? AppAssets.insurance_active_icon + : AppAssets.alertSquare, + labelText: insuranceVM.isInsuranceExpired + ? LocaleKeys.insuranceExpired.tr(context: context) + : insuranceVM.isInsuranceActive + ? LocaleKeys.insuranceActive.tr(context: context) + : LocaleKeys.insuranceInActive.tr(context: context), + iconColor: insuranceVM.isInsuranceExpired + ? AppColors.primaryRedColor + : insuranceVM.isInsuranceActive + ? AppColors.successColor + : AppColors.warningColorYellow, + textColor: insuranceVM.isInsuranceExpired + ? AppColors.primaryRedColor + : insuranceVM.isInsuranceActive + ? AppColors.successColor + : AppColors.warningColorYellow, + iconSize: 12.w, + deleteIcon: insuranceVM.isInsuranceActive ? null : AppAssets.forward_chevron_icon, + deleteIconColor: insuranceVM.isInsuranceExpired + ? AppColors.primaryRedColor + : insuranceVM.isInsuranceActive + ? AppColors.successColor + : AppColors.warningColorYellow, + deleteIconHasColor: true, + onChipTap: () { + if (!insuranceVM.isInsuranceActive) { + insuranceVM.setIsInsuranceUpdateDetailsLoading(true); + insuranceVM.getPatientInsuranceDetailsForUpdate( + appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); + showCommonBottomSheetWithoutHeight(context, child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); + // showCommonBottomSheetWithoutHeight( + // title: LocaleKeys.notice.tr(context: navigationService.navigatorKey.currentContext!), + // navigationService.navigatorKey.currentContext!, + // child: Utils.getWarningWidget( + // loadingText: LocaleKeys.insuranceInActiveContactSupport.tr(context: context), + // confirmText: LocaleKeys.contactUs.tr(context: context), + // isShowActionButtons: true, + // onCancelTap: () { + // navigationService.pop(); + // }, + // onConfirmTap: () async { + // launchUrl(Uri.parse("tel://" + "+966 92 006 6666")); + // }), + // callBackFunc: () {}, + // isFullScreen: false, + // isCloseButtonVisible: true, + // ); + } + }, + backgroundColor: insuranceVM.isInsuranceExpired + ? AppColors.primaryRedColor.withOpacity(0.1) + : insuranceVM.isInsuranceActive + ? AppColors.successColor.withOpacity(0.1) + : AppColors.warningColorYellow.withOpacity(0.1), + labelPadding: EdgeInsetsDirectional.only(start: -4.w, end: insuranceVM.isInsuranceActive ? 6.w : 0.w), + ).toShimmer2(isShow: insuranceVM.isInsuranceLoading); + }), + ], + ), + ], + ), + ), + ).paddingSymmetrical(0.w, 0.0), + SizedBox(height: 16.h), + GridView.builder( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: widget.profileViewList!.length, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 10.w, + mainAxisSpacing: 10.h, + childAspectRatio: widget.isShowDetails ? 0.56.h : 0.74.h, + ), + padding: EdgeInsets.only(bottom: 20.h), + itemBuilder: (context, index) { + final profile = widget.profileViewList![index]; + final isActive = (profile.responseId == appState.getAuthenticatedUser()?.patientId); + final isParentUser = appState.getAuthenticatedUser()?.isParentUser ?? false; + final canSwitch = isParentUser || (!isParentUser && profile.responseId == appState.getSuperUserID); + return Container( + padding: EdgeInsets.symmetric(vertical: 15.h, horizontal: 15.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r), + child: Opacity( + opacity: isActive || profile.status == FamilyFileEnum.pending.toInt || !canSwitch ? 0.4 : 1.0, // Fade all content if active + child: Stack( + children: [ + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Utils.buildImgWithAssets( + icon: profile.gender == null + ? AppAssets.dummyUser + : profile.gender == 1 + ? ((profile.age ?? 0) < 7 ? AppAssets.babyBoyImg : AppAssets.maleImg) + : (profile.age! < 7 ? AppAssets.babyGirlImg : AppAssets.femaleImg), + width: 72.h, + height: 70.h, + ), + SizedBox(height: 8.h), + (profile.patientName ?? "Unknown").toText14(isBold: false, isCenter: true, maxlines: 1, weight: FontWeight.w600), + SizedBox(height: 8.h), + CustomChipWidget( chipType: ChipTypeEnum.alert, backgroundColor: AppColors.lightGrayBGColor, - chipText: "Age:${profile.age ?? "N/A"} Years", + chipText: "Relation: ${profile.relationship ?? " N/A"}", + iconAsset: AppAssets.heart, isShowBorder: false, borderRadius: 8.h, - textColor: AppColors.textColor, - ) - : SizedBox(), - widget.isShowDetails - ? SizedBox(height: 8.h) - : SizedBox( - height: 4.h, - ), - Spacer(), - widget.isForWalletRecharge ? CustomButton( - height: 40.h, - onPressed: () { - widget.onSelect(profile); - // if (canSwitch) widget.onSelect(profile); - }, - text: LocaleKeys.select.tr(context: context), - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 13.h, - icon: AppAssets.activeCheck, - iconColor: isActive || !canSwitch ? (isActive ? null : AppColors.greyTextColor) : AppColors.primaryRedColor, - padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0), - ).paddingOnly(top: 0, bottom: 0) : CustomButton( - height: 40.h, - onPressed: () { - if (canSwitch) widget.onSelect(profile); - }, - text: isActive ? LocaleKeys.active.tr(context: context) : LocaleKeys.switchLogin.tr(context: context), - backgroundColor: isActive || !canSwitch ? Colors.grey.shade200 : AppColors.secondaryLightRedColor, - borderColor: isActive || !canSwitch ? Colors.grey.shade200 : AppColors.secondaryLightRedColor, - textColor: isActive || !canSwitch ? AppColors.greyTextColor : AppColors.primaryRedColor, - fontSize: 13.h, - icon: isActive ? AppAssets.activeCheck : AppAssets.switch_user, - iconColor: isActive || !canSwitch ? (isActive ? null : AppColors.greyTextColor) : AppColors.primaryRedColor, - padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0), - ).paddingOnly(top: 0, bottom: 0), + textColor: AppColors.textColor), + widget.isShowDetails ? SizedBox(height: 4.h) : SizedBox(), + widget.isShowDetails + ? CustomChipWidget( + chipType: ChipTypeEnum.alert, + backgroundColor: AppColors.lightGrayBGColor, + chipText: "Age: ${profile.age ?? "N/A"} Years", + isShowBorder: false, + borderRadius: 8.h, + textColor: AppColors.textColor, + ) + : SizedBox(), + widget.isShowDetails + ? SizedBox(height: 8.h) + : SizedBox( + height: 4.h, + ), + Spacer(), + widget.isForWalletRecharge + ? CustomButton( + height: 40.h, + onPressed: () { + widget.onSelect(profile); + // if (canSwitch) widget.onSelect(profile); + }, + text: LocaleKeys.select.tr(context: context), + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 13.h, + icon: AppAssets.activeCheck, + iconColor: isActive || !canSwitch ? (isActive ? null : AppColors.greyTextColor) : AppColors.primaryRedColor, + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0), + ).paddingOnly(top: 0, bottom: 0) + : CustomButton( + height: 40.h, + onPressed: () { + if (canSwitch) widget.onSelect(profile); + }, + text: isActive ? LocaleKeys.active.tr(context: context) : LocaleKeys.switchLogin.tr(context: context), + backgroundColor: isActive || !canSwitch ? Colors.grey.shade200 : AppColors.secondaryLightRedColor, + borderColor: isActive || !canSwitch ? Colors.grey.shade200 : AppColors.secondaryLightRedColor, + textColor: isActive || !canSwitch ? AppColors.greyTextColor : AppColors.primaryRedColor, + fontSize: 13.h, + icon: isActive ? AppAssets.activeCheck : AppAssets.switch_user, + iconColor: isActive || !canSwitch ? (isActive ? null : AppColors.greyTextColor) : AppColors.primaryRedColor, + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0), + ).paddingOnly(top: 0, bottom: 0), + ], + ), + if (widget.isShowRemoveButton) ...[ + Positioned( + top: 0, + right: 0, + child: Utils.buildSvgWithAssets(icon: AppAssets.deleteIcon).onPress(() { + if (!isActive) widget.onRemove(profile); + }), + ), + ], ], ), - if (widget.isShowRemoveButton) ...[ - Positioned( - top: 0, - right: 0, - child: Utils.buildSvgWithAssets(icon: AppAssets.deleteIcon).onPress(() { - if (!isActive) widget.onRemove(profile); - }), - ), - ], - ], - ), - ), - ); - }, + ), + ); + }, + ), + ], ); } } @@ -260,15 +421,15 @@ class _FamilyCardsState extends State { Widget manageFamily() { NavigationService navigationService = getIt(); - return widget.profiles.where((profile) => !(profile.isRequestFromMySide ?? false)).isEmpty + return widget.profileViewList!.where((profile) => !(profile.isRequestFromMySide ?? false)).isEmpty ? Utils.getNoDataWidget(context) : ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsetsGeometry.zero, - itemCount: widget.profiles.where((profile) => !(profile.isRequestFromMySide ?? false)).length, + itemCount: widget.profileViewList!.where((profile) => !(profile.isRequestFromMySide ?? false)).length, itemBuilder: (context, index) { - final otherProfiles = widget.profiles.where((profile) => !(profile.isRequestFromMySide ?? false)).toList(); + final otherProfiles = widget.profileViewList!.where((profile) => !(profile.isRequestFromMySide ?? false)).toList(); FamilyFileResponseModelLists profile = otherProfiles[index]; return Container( margin: EdgeInsets.only(bottom: 12.h), diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart index 98002ca9..50b8eb07 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -15,12 +15,15 @@ import 'package:hmg_patient_app_new/extensions/int_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/authentication/authentication_view_model.dart'; +import 'package:hmg_patient_app_new/features/contact_us/contact_us_view_model.dart'; +import 'package:hmg_patient_app_new/features/contact_us/models/feedback_type.dart'; import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart'; import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/contact_us/feedback_page.dart'; import 'package:hmg_patient_app_new/presentation/habib_wallet/habib_wallet_page.dart'; import 'package:hmg_patient_app_new/presentation/habib_wallet/recharge_wallet_page.dart'; import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_update_details_card.dart'; @@ -88,10 +91,12 @@ class ProfileSettingsState extends State { int length = 3; final SwiperController _controller = SwiperController(); late InsuranceViewModel insuranceViewModel; + late ContactUsViewModel contactUsViewModel; @override Widget build(BuildContext context) { insuranceViewModel = Provider.of(context, listen: false); + contactUsViewModel = Provider.of(context, listen: false); return CollapsingListView( title: LocaleKeys.profileAndSettings.tr(context: context), logout: () { @@ -106,102 +111,102 @@ class ProfileSettingsState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox( - height: dynamicItemHeight(context) + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space - child: Swiper( - itemCount: medicalVm.patientFamilyFiles.length, - layout: SwiperLayout.STACK, - loop: true, - itemHeight: dynamicItemHeight(context) + 20, - // extra space for shadow - itemWidth: SizeUtils.width - 30.w, - indicatorLayout: PageIndicatorLayout.COLOR, - axisDirection: getIt.get().isArabic() ? AxisDirection.left : AxisDirection.right, - controller: _controller, - pagination: SwiperPagination( - alignment: Alignment.bottomCenter, - margin: EdgeInsets.only(top: (180.h + 20 + 8.h + 24.h)), - builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor), - ), - itemBuilder: (BuildContext context, int index) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 10), - child: FamilyCardWidget( - profile: medicalVm.patientFamilyFiles[index], - onAddFamilyMemberPress: () { - DialogService dialogService = getIt.get(); - dialogService.showAddFamilyFileSheet( - label: LocaleKeys.addFamilyMember.tr(context: context), - message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(context: context), - onVerificationPress: () { - medicalVm.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); - }); - }, - onFamilySwitchPress: (FamilyFileResponseModelLists profile) { - medicalVm.switchFamilyFiles(responseID: profile.responseId, patientID: profile.patientId, phoneNumber: profile.mobileNumber); - }, - ).paddingOnly(right: 16.w, left: 8.w), - ); - }, - ), - ), - SizedBox(height: 16.h), - GridView( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: isTablet ? 3 : 2), - physics: const NeverScrollableScrollPhysics(), - padding: EdgeInsets.only(left: 24.w, right: 24.w, bottom: 24.h), - shrinkWrap: true, - children: [ - Container( - padding: EdgeInsets.all(16.w), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.r, - hasShadow: true, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - // spacing: 4.h, - children: [ - Row( - spacing: 8.w, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.wallet, width: 40.w, height: 40.h, applyThemeColor: false), - LocaleKeys.habibWallet.tr(context: context).toText16(weight: FontWeight.w600, maxlines: 2).expanded, - Utils.buildSvgWithAssets(icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward), - ], - ), - Spacer(), - Consumer(builder: (context, habibWalletVM, child) { - return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, isExpanded: false) - .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.r, width: 80.w, height: 24.h); - }), - Spacer(), - CustomButton( - height: 40.h, - icon: AppAssets.recharge_icon, - iconSize: 22.w, - iconColor: AppColors.infoColor, - textColor: AppColors.infoColor, - text: LocaleKeys.recharge.tr(context: context), - borderWidth: 0.w, - fontWeight: FontWeight.w500, - borderColor: Colors.transparent, - backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), - padding: EdgeInsets.all(8.w), - fontSize: 14.f, - onPressed: () { - Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); - }, - ), - ], - ).onPress(() { - Navigator.of(context).push(CustomPageRoute(page: HabibWalletPage())); - }), - ), - ], - ), + // SizedBox( + // height: dynamicItemHeight(context) + 20 + 30, // itemHeight + shadow padding (10 top + 10 bottom) + pagination dots space + // child: Swiper( + // itemCount: medicalVm.patientFamilyFiles.length, + // layout: SwiperLayout.STACK, + // loop: true, + // itemHeight: dynamicItemHeight(context) + 20, + // // extra space for shadow + // itemWidth: SizeUtils.width - 30.w, + // indicatorLayout: PageIndicatorLayout.COLOR, + // axisDirection: getIt.get().isArabic() ? AxisDirection.left : AxisDirection.right, + // controller: _controller, + // pagination: SwiperPagination( + // alignment: Alignment.bottomCenter, + // margin: EdgeInsets.only(top: (180.h + 20 + 8.h + 24.h)), + // builder: DotSwiperPaginationBuilder(color: Color(0xffD9D9D9), activeColor: AppColors.blackBgColor), + // ), + // itemBuilder: (BuildContext context, int index) { + // return Padding( + // padding: const EdgeInsets.symmetric(vertical: 10), + // child: FamilyCardWidget( + // profile: medicalVm.patientFamilyFiles[index], + // onAddFamilyMemberPress: () { + // DialogService dialogService = getIt.get(); + // dialogService.showAddFamilyFileSheet( + // label: LocaleKeys.addFamilyMember.tr(context: context), + // message: LocaleKeys.pleaseFillBelowFieldToAddNewFamilyMember.tr(context: context), + // onVerificationPress: () { + // medicalVm.addFamilyFile(otpTypeEnum: OTPTypeEnum.sms); + // }); + // }, + // onFamilySwitchPress: (FamilyFileResponseModelLists profile) { + // medicalVm.switchFamilyFiles(responseID: profile.responseId, patientID: profile.patientId, phoneNumber: profile.mobileNumber); + // }, + // ).paddingOnly(right: 16.w, left: 8.w), + // ); + // }, + // ), + // ), + // SizedBox(height: 16.h), + // GridView( + // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: isTablet ? 3 : 2), + // physics: const NeverScrollableScrollPhysics(), + // padding: EdgeInsets.only(left: 24.w, right: 24.w, bottom: 24.h), + // shrinkWrap: true, + // children: [ + // Container( + // padding: EdgeInsets.all(16.w), + // decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + // color: AppColors.whiteColor, + // borderRadius: 20.r, + // hasShadow: true, + // ), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // // spacing: 4.h, + // children: [ + // Row( + // spacing: 8.w, + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // Utils.buildSvgWithAssets(icon: AppAssets.wallet, width: 40.w, height: 40.h, applyThemeColor: false), + // LocaleKeys.habibWallet.tr(context: context).toText16(weight: FontWeight.w600, maxlines: 2).expanded, + // Utils.buildSvgWithAssets(icon: getIt.get().isArabic() ? AppAssets.arrow_back : AppAssets.arrow_forward), + // ], + // ), + // Spacer(), + // Consumer(builder: (context, habibWalletVM, child) { + // return Utils.getPaymentAmountWithSymbol2(habibWalletVM.habibWalletAmount, isExpanded: false) + // .toShimmer2(isShow: habibWalletVM.isWalletAmountLoading, radius: 12.r, width: 80.w, height: 24.h); + // }), + // Spacer(), + // CustomButton( + // height: 40.h, + // icon: AppAssets.recharge_icon, + // iconSize: 22.w, + // iconColor: AppColors.infoColor, + // textColor: AppColors.infoColor, + // text: LocaleKeys.recharge.tr(context: context), + // borderWidth: 0.w, + // fontWeight: FontWeight.w500, + // borderColor: Colors.transparent, + // backgroundColor: Color(0xff45A2F8).withValues(alpha: 0.08), + // padding: EdgeInsets.all(8.w), + // fontSize: 14.f, + // onPressed: () { + // Navigator.of(context).push(CustomPageRoute(page: RechargeWalletPage())); + // }, + // ), + // ], + // ).onPress(() { + // Navigator.of(context).push(CustomPageRoute(page: HabibWalletPage())); + // }), + // ), + // ], + // ), LocaleKeys.quickActions.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), @@ -253,31 +258,31 @@ class ProfileSettingsState extends State { // ], // ), // ), - 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(context: context), () { - showCommonBottomSheetWithoutHeight( - context, - title: LocaleKeys.updateEmailAddress.tr(context: context), - child: UpdateEmailDialog(), - callBackFunc: () {}, - isFullScreen: false, - ); - }), - // 1.divider, - // actionItem(AppAssets.smart_phone_fill, "Phone Number".needTranslation, () {}), - // 1.divider, - // actionItem(AppAssets.my_address, "My Addresses".needTranslation, () {}), - // 1.divider, - // actionItem(AppAssets.emergency, "Emergency Contact".needTranslation, () {}), - ], - ), - ), + // 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(context: context), () { + // showCommonBottomSheetWithoutHeight( + // context, + // title: LocaleKeys.updateEmailAddress.tr(context: context), + // child: UpdateEmailDialog(), + // callBackFunc: () {}, + // isFullScreen: false, + // ); + // }), + // // 1.divider, + // // actionItem(AppAssets.smart_phone_fill, "Phone Number".needTranslation, () {}), + // // 1.divider, + // // actionItem(AppAssets.my_address, "My Addresses".needTranslation, () {}), + // // 1.divider, + // // actionItem(AppAssets.emergency, "Emergency Contact".needTranslation, () {}), + // ], + // ), + // ), 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), @@ -289,6 +294,19 @@ class ProfileSettingsState extends State { launchUrl(Uri.parse("tel://" + "+966 92 006 6666")); }, trailingLabel: "92 006 6666"), 1.divider, + actionItem(AppAssets.feedbackFill, LocaleKeys.feedback.tr(context: context), () { + contactUsViewModel.setSelectedFeedbackType( + FeedbackType(id: 5, nameEN: "Not classified", nameAR: 'غير محدد'), + ); + contactUsViewModel.setIsSendFeedbackTabSelected(true); + Navigator.pop(context); + Navigator.of(context).push( + CustomPageRoute( + page: FeedbackPage(), + ), + ); + }, trailingLabel: ""), + 1.divider, // actionItem(AppAssets.permission, LocaleKeys.permissions.tr(context: context), () {}, trailingLabel: "Location, Camera"), // 1.divider, actionItem(AppAssets.rate, LocaleKeys.rateApp.tr(context: context), () { diff --git a/lib/services/dialog_service.dart b/lib/services/dialog_service.dart index c4dfb7c4..d2ba2723 100644 --- a/lib/services/dialog_service.dart +++ b/lib/services/dialog_service.dart @@ -166,7 +166,7 @@ class DialogServiceImp implements DialogService { mainAxisAlignment: MainAxisAlignment.start, children: [ if (message != null) (message).toText16(isBold: false, color: AppColors.textColor), - SizedBox(height: 24.h), + // SizedBox(height: 24.h), FamilyCards( profiles: profiles, onSelect: (FamilyFileResponseModelLists profile) { @@ -190,6 +190,7 @@ class DialogServiceImp implements DialogService { }) ], ), + useSafeArea: true, callBackFunc: () {}); } diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart index 514acfb4..467edd92 100644 --- a/lib/theme/colors.dart +++ b/lib/theme/colors.dart @@ -8,7 +8,7 @@ class AppColors { static const transparent = Colors.transparent; // ── Scaffold / Background ───────────────────────────────────────────────── - static Color get scaffoldBgColor => isDarkMode ? dark.scaffoldBgColor : const Color(0xFFF8F8F8); + static Color get scaffoldBgColor => isDarkMode ? dark.scaffoldBgColor : const Color(0xFFF0F0F0); static Color get bottomSheetBgColor => isDarkMode ? dark.bottomSheetBgColor : const Color(0xFFF8F8FA); static Color get lightGreyEFColor => isDarkMode ? dark.lightGreyEFColor : const Color(0xffeaeaff); static Color get greyF7Color => isDarkMode ? dark.greyF7Color : const Color(0xffF7F7F7); From 4a3d66f01a1b9a00e925c6a17c46cd0c9be9f69c Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Sun, 29 Mar 2026 18:02:12 +0300 Subject: [PATCH 12/17] Updates --- assets/langs/ar-SA.json | 4 +- assets/langs/en-US.json | 4 +- lib/core/api/api_client.dart | 2 +- lib/extensions/widget_extensions.dart | 4 +- lib/features/ask_doctor/ask_doctor_repo.dart | 2 +- .../models/ask_doctor_appointments_list.dart | 2 +- .../insurance/insurance_view_model.dart | 12 +++ lib/features/lab/lab_view_model.dart | 29 +++--- lib/generated/locale_keys.g.dart | 2 + .../appointment_details_page.dart | 23 ++++- .../widgets/appointment_card.dart | 16 +++- .../widgets/appointment_doctor_card.dart | 40 +++++---- .../emergency_services_page.dart | 2 +- lib/presentation/home/landing_page.dart | 32 ++++--- .../insurance/insurance_home_page.dart | 33 ++++--- .../insurance_update_details_card.dart | 88 ++++++++++--------- .../widgets/patient_insurance_card.dart | 51 ++++++++--- lib/presentation/lab/lab_orders_page.dart | 2 +- .../lab_order_result_item.dart | 8 +- .../medical_file/medical_file_page.dart | 55 ++++++------ 20 files changed, 257 insertions(+), 154 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 268bf0a3..6df6d8c7 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1587,5 +1587,7 @@ "ratings": "التقييمات", "hmgPharmacyText": "صيدلية الحبيب، المتجر الصيدلاني الإلكتروني المتكامل الذي تقدمه لكم مجموعة خدمات الدكتور سليمان الحبيب الطبية.", "insuranceRequestSubmittedSuccessfully": "تم إرسال طلب تحديث بيانات التأمين بنجاح. سيتم إعلامك بمجرد الانتهاء.", - "updatingEmailAddress": "جارٍ تحديث عنوان البريد الإلكتروني، يرجى الانتظار..." + "updatingEmailAddress": "جارٍ تحديث عنوان البريد الإلكتروني، يرجى الانتظار...", + "verifyInsurance": "التحقق من التأمين", + "tests": "تحليل" } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index d1a48222..bedf03fd 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1581,5 +1581,7 @@ "ratings": "Ratings", "hmgPharmacyText": "Al Habib Pharmacy, the complete online Pharmaceutical store brought to you by Dr. Sulaiman Al Habib Medical Services Group.", "insuranceRequestSubmittedSuccessfully": "Your insurance update request has been successfully submitted. You will be notified once completed.", - "updatingEmailAddress": "Updating email address, Please wait..." + "updatingEmailAddress": "Updating email address, Please wait...", + "verifyInsurance": "Verify Insurance", + "tests": "tests" } diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 0131a938..2de4ce5c 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -200,7 +200,7 @@ class ApiClientImp implements ApiClient { } // body['TokenID'] = "@dm!n"; - // body['PatientID'] = 4774402; + // body['PatientID'] = 1231755; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; // body['SessionID'] = "45786230487560q"; diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index f0897950..866c26a4 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.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/int_extensions.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_view_model.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:shimmer/shimmer.dart'; import 'package:sizer/sizer.dart'; @@ -166,7 +168,7 @@ extension SmoothContainerExtension on ShapeBorder { ? [ BoxShadow( // color: hasDenseShadow ? const Color(0xff000000).withOpacity(.06) : const Color(0xff000000).withOpacity(.1), - color: const Color(0xffE1E1E1).withOpacity(1.0), + color: getIt.get().isDarkMode ? Color(0xff3a3a3a).withOpacity(1.0) : Color(0xffE1E1E1).withOpacity(1.0), blurRadius: 0, spreadRadius: 0, offset: const Offset(1, 0), diff --git a/lib/features/ask_doctor/ask_doctor_repo.dart b/lib/features/ask_doctor/ask_doctor_repo.dart index 4e4a4006..bd6af5b8 100644 --- a/lib/features/ask_doctor/ask_doctor_repo.dart +++ b/lib/features/ask_doctor/ask_doctor_repo.dart @@ -47,7 +47,7 @@ class AskDoctorRepoImp implements AskDoctorRepo { try { final list = response['PatientDoctorAppointmentResultList']; - final clinicsList = list.map((item) => AskDoctorAppointmentHistoryList.fromJson(item as Map)).toList().cast(); + final clinicsList = list != null ? list.map((item) => AskDoctorAppointmentHistoryList.fromJson(item as Map)).toList().cast() : []; apiResponse = GenericApiModel>( messageStatus: messageStatus, diff --git a/lib/features/ask_doctor/models/ask_doctor_appointments_list.dart b/lib/features/ask_doctor/models/ask_doctor_appointments_list.dart index 7f40d71c..6b337662 100644 --- a/lib/features/ask_doctor/models/ask_doctor_appointments_list.dart +++ b/lib/features/ask_doctor/models/ask_doctor_appointments_list.dart @@ -143,7 +143,7 @@ class AskDoctorAppointmentHistoryList { noOfPatientsRate = json['NoOfPatientsRate']; projectName = json['ProjectName']; qR = json['QR']; - speciality = json['Speciality'].cast(); + // speciality = json['Speciality'].cast(); } Map toJson() { diff --git a/lib/features/insurance/insurance_view_model.dart b/lib/features/insurance/insurance_view_model.dart index d1423113..28210d39 100644 --- a/lib/features/insurance/insurance_view_model.dart +++ b/lib/features/insurance/insurance_view_model.dart @@ -13,6 +13,7 @@ class InsuranceViewModel extends ChangeNotifier { bool isInsuranceHistoryLoading = false; bool isInsuranceDetailsLoading = false; bool isInsuranceUpdateDetailsLoading = false; + bool isInsuranceExpiryBannerShown = false; bool isInsuranceDataToBeLoaded = true; bool isInsuranceApprovalsLoading = false; @@ -49,6 +50,11 @@ class InsuranceViewModel extends ChangeNotifier { notifyListeners(); } + setIsInsuranceExpiryBannerShown(bool isInsuranceExpiryBannerShown) { + this.isInsuranceExpiryBannerShown = isInsuranceExpiryBannerShown; + notifyListeners(); + } + setIsInsuranceHistoryLoading(bool val) { isInsuranceHistoryLoading = val; notifyListeners(); @@ -91,6 +97,7 @@ class InsuranceViewModel extends ChangeNotifier { isInsuranceDataToBeLoaded = true; isInsuranceExpired = false; isInsuranceActive = false; + isInsuranceExpiryBannerShown = false; notifyListeners(); }, (apiResponse) { @@ -111,6 +118,8 @@ class InsuranceViewModel extends ChangeNotifier { debugPrint("InsuranceViewModel: Insurance card expired: $isInsuranceExpired"); } + isInsuranceExpiryBannerShown = isInsuranceExpired; + isInsuranceActive = patientInsuranceList.first.isActive ?? false; // isInsuranceActive = true; @@ -148,6 +157,9 @@ class InsuranceViewModel extends ChangeNotifier { } Future getPatientInsuranceDetailsForUpdate(String patientID, String identificationNo, {Function(dynamic)? onSuccess, Function(String)? onError}) async { + patientInsuranceUpdateResponseModel = null; + notifyListeners(); + final result = await insuranceRepo.getPatientInsuranceDetailsForUpdate(patientId: patientID, identificationNo: identificationNo); result.fold( diff --git a/lib/features/lab/lab_view_model.dart b/lib/features/lab/lab_view_model.dart index 4c689ab7..1af2654e 100644 --- a/lib/features/lab/lab_view_model.dart +++ b/lib/features/lab/lab_view_model.dart @@ -149,21 +149,26 @@ class LabViewModel extends ChangeNotifier { isLabOrdersLoading = false; isLabResultsLoading = false; - // --- Build groups by clinic and by hospital (projectName) --- - final clinicMap = >{}; - final hospitalMap = >{}; - for (var order in patientLabOrders) { - final clinicKey = (order.clinicDescription ?? 'Unknown').trim(); - clinicMap.putIfAbsent(clinicKey, () => []).add(order); - - final hospitalKey = (order.projectName ?? order.projectID ?? 'Unknown').toString().trim(); - hospitalMap.putIfAbsent(hospitalKey, () => []).add(order); + order.testDetails!.sort((a, b) => a.description!.compareTo(b.description!)); } - patientLabOrdersByClinic = clinicMap.values.toList(); - patientLabOrdersByHospital = hospitalMap.values.toList(); - patientLabOrdersViewList = isSortByClinic ? patientLabOrdersByClinic : patientLabOrdersByHospital; + // --- Build groups by clinic and by hospital (projectName) --- + // final clinicMap = >{}; + // final hospitalMap = >{}; + // + // for (var order in patientLabOrders) { + // final clinicKey = (order.clinicDescription ?? 'Unknown').trim(); + // clinicMap.putIfAbsent(clinicKey, () => []).add(order); + // + // final hospitalKey = (order.projectName ?? order.projectID ?? 'Unknown').toString().trim(); + // hospitalMap.putIfAbsent(hospitalKey, () => []).add(order); + // } + + // patientLabOrdersByClinic = clinicMap.values.toList(); + // patientLabOrdersByHospital = hospitalMap.values.toList(); + // patientLabOrdersViewList = isSortByClinic ? patientLabOrdersByClinic : patientLabOrdersByHospital; + // patientLabOrdersViewList = patientLabOrdersByClinic; filterSuggestions(); getUniqueTestDescription(); diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 031e1be9..ac9f3f7c 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1582,5 +1582,7 @@ abstract class LocaleKeys { static const hmgPharmacyText = 'hmgPharmacyText'; static const insuranceRequestSubmittedSuccessfully = 'insuranceRequestSubmittedSuccessfully'; static const updatingEmailAddress = 'updatingEmailAddress'; + static const verifyInsurance = 'verifyInsurance'; + static const tests = 'tests'; } diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index 71cf4e16..072cb04a 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -14,6 +14,7 @@ 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/ask_doctor/ask_doctor_view_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart'; import 'package:hmg_patient_app_new/features/contact_us/contact_us_view_model.dart'; @@ -31,6 +32,8 @@ import 'package:hmg_patient_app_new/presentation/appointments/appointment_paymen import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_checkin_bottom_sheet.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_doctor_card.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/ask_doctor_request_type_select.dart'; +import 'package:hmg_patient_app_new/presentation/ask_doctor/ask_doctor_page.dart'; +import 'package:hmg_patient_app_new/presentation/ask_doctor/doctor_response_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart'; import 'package:hmg_patient_app_new/presentation/contact_us/feedback_page.dart'; import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_detail_page.dart'; @@ -556,6 +559,22 @@ class _AppointmentDetailsPageState extends State { // ), // ); }), + MedicalFileCard( + label: LocaleKeys.doctorResponses.tr(context: context), + textColor: AppColors.blackColor, + backgroundColor: AppColors.whiteColor, + svgIcon: AppAssets.ask_doctor_medical_file_icon, + isLargeText: true, + iconSize: 36.w, + ).onPress(() { + getIt.get().initAskDoctorViewModel(); + getIt.get().getDoctorResponses(); + Navigator.of(context).push( + CustomPageRoute( + page: DoctorResponsePage(), + ), + ); + }), ], ), // Column( @@ -839,8 +858,8 @@ class _AppointmentDetailsPageState extends State { onPressed: () { openDoctorScheduleCalendar(); }, - backgroundColor: AppColors.successColor, - borderColor: AppColors.successColor, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, textColor: Colors.white, fontSize: 16.f, fontWeight: FontWeight.w500, diff --git a/lib/presentation/appointments/widgets/appointment_card.dart b/lib/presentation/appointments/widgets/appointment_card.dart index ac63432f..44fcfa86 100644 --- a/lib/presentation/appointments/widgets/appointment_card.dart +++ b/lib/presentation/appointments/widgets/appointment_card.dart @@ -329,12 +329,19 @@ class AppointmentCard extends StatelessWidget { flex: 1, child: Container( height: (isFoldable || isTablet) ? 50.h : 40.h, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.textColor, borderRadius: 10.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.transparent, + borderRadius: 10.h, + side: BorderSide( + color: AppColors.textColor, + width: 1.2, + ), + ), child: Transform.flip( flipX: appState.isArabic(), child: Utils.buildSvgWithAssets( icon: AppAssets.forward_arrow_icon, - iconColor: AppColors.whiteColor, + iconColor: AppColors.textColor, width: 24.w, height: 24.h, fit: BoxFit.contain, @@ -401,9 +408,10 @@ class AppointmentCard extends StatelessWidget { return CustomButton( text: LocaleKeys.rebookSameDoctor.tr(context: context), onPressed: () => openDoctorScheduleCalendar(context), - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, + backgroundColor: AppColors.transparent, + borderColor: AppColors.textColor, textColor: AppColors.blackColor, + borderWidth: 1.h, fontSize: (isFoldable || isTablet) ? 12.f : 14.f, fontWeight: FontWeight.w500, borderRadius: 12.r, diff --git a/lib/presentation/appointments/widgets/appointment_doctor_card.dart b/lib/presentation/appointments/widgets/appointment_doctor_card.dart index ef8c76ee..5a47708e 100644 --- a/lib/presentation/appointments/widgets/appointment_doctor_card.dart +++ b/lib/presentation/appointments/widgets/appointment_doctor_card.dart @@ -155,25 +155,27 @@ class AppointmentDoctorCard extends StatelessWidget { icon: AppAssets.ask_doctor_icon, iconColor: AppColors.primaryRedColor, ) - : !patientAppointmentHistoryResponseModel.isLiveCareAppointment! - ? CustomButton( - text: LocaleKeys.rebookSameDoctor.tr(), - onPressed: () { - onRescheduleTap(); - }, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 12.f, - fontWeight: FontWeight.w500, - borderRadius: 12.r, - padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), - height: 40.h, - icon: AppAssets.rebook_appointment_icon, - iconColor: AppColors.blackColor, - iconSize: 14.h, - ) - : SizedBox.shrink(); + : + // !patientAppointmentHistoryResponseModel.isLiveCareAppointment! + // ? CustomButton( + // text: LocaleKeys.rebookSameDoctor.tr(), + // onPressed: () { + // onRescheduleTap(); + // }, + // backgroundColor: AppColors.greyColor, + // borderColor: AppColors.greyColor, + // textColor: AppColors.blackColor, + // fontSize: 12.f, + // fontWeight: FontWeight.w500, + // borderRadius: 12.r, + // padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), + // height: 40.h, + // icon: AppAssets.rebook_appointment_icon, + // iconColor: AppColors.blackColor, + // iconSize: 14.h, + // ) + // : + SizedBox.shrink(); } else { return patientAppointmentHistoryResponseModel.isLiveCareAppointment! ? CustomButton( diff --git a/lib/presentation/emergency_services/emergency_services_page.dart b/lib/presentation/emergency_services/emergency_services_page.dart index 41597e40..7970d819 100644 --- a/lib/presentation/emergency_services/emergency_services_page.dart +++ b/lib/presentation/emergency_services/emergency_services_page.dart @@ -35,7 +35,7 @@ class EmergencyServicesPage extends StatelessWidget { return CollapsingListView( title: LocaleKeys.emergencyServices.tr(), - requests: () { + history: () { emergencyServicesViewModel.changeOrderDisplayItems(OrderDislpay.ALL); Navigator.of(context).push(CustomPageRoute(page: ErHistoryListing(), direction: AxisDirection.up)); }, diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 768a31d1..14684c0c 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -48,6 +48,7 @@ import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/welcome_widget.dart'; import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart'; +import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_update_details_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; import 'package:hmg_patient_app_new/presentation/my_family/my_family.dart'; import 'package:hmg_patient_app_new/presentation/notifications/notifications_list_page.dart'; @@ -171,7 +172,11 @@ class _LandingPageState extends State { return Stack( children: [ SingleChildScrollView( - padding: EdgeInsets.only(top: (!insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired) ? (MediaQuery.paddingOf(context).top + 70.h) : kToolbarHeight + 0.h, bottom: 24), + padding: EdgeInsets.only( + top: (!insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired && insuranceVM.isInsuranceExpiryBannerShown) + ? (MediaQuery.paddingOf(context).top + 70.h) + : kToolbarHeight + 0.h, + bottom: 24), child: Column( spacing: 16.h, children: [ @@ -728,7 +733,7 @@ class _LandingPageState extends State { ], ), ), - (!insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired) + (!insuranceVM.isInsuranceLoading && insuranceVM.isInsuranceExpired && insuranceVM.isInsuranceExpiryBannerShown) ? Container( height: MediaQuery.paddingOf(context).top + 50.h, decoration: ShapeDecoration( @@ -745,27 +750,30 @@ class _LandingPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.insuranceExpiredOrInactive.tr(context: context).toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500).paddingSymmetrical(24.h, 0.h), + LocaleKeys.insuranceExpiredOrInactive.tr(context: context).toText14(color: AppColors.primaryRedColor, weight: FontWeight.w500).paddingSymmetrical(0.h, 0.h), Row( children: [ CustomButton( text: LocaleKeys.updateInsurance.tr(context: context), onPressed: () { - Navigator.of(context).push( - CustomPageRoute( - page: InsuranceHomePage(), - ), - ); + insuranceVM.setIsInsuranceUpdateDetailsLoading(true); + insuranceVM.getPatientInsuranceDetailsForUpdate( + appState.getAuthenticatedUser()!.patientId.toString(), appState.getAuthenticatedUser()!.patientIdentificationNo.toString()); + showCommonBottomSheetWithoutHeight(context, + child: PatientInsuranceCardUpdateCard(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); }, backgroundColor: AppColors.primaryRedColor, borderColor: AppColors.secondaryLightRedBorderColor, - textColor: AppColors.whiteColor, - fontSize: 10.f, + textColor: Colors.white, + fontSize: 12.f, fontWeight: FontWeight.bold, borderRadius: 8.r, padding: EdgeInsets.fromLTRB(15, 0, 15, 0), height: 36.h, - ).paddingSymmetrical(24.h, 0.h), + ).paddingSymmetrical(12.h, 0.h), + Icon(Icons.close, color: AppColors.primaryRedColor).onPress(() { + insuranceVM.setIsInsuranceExpiryBannerShown(false); + }), ], ), ], @@ -774,7 +782,7 @@ class _LandingPageState extends State { height: 10.h, ) ], - ), + ).paddingSymmetrical(24.h, 0.h), ) : SizedBox.shrink() ], diff --git a/lib/presentation/insurance/insurance_home_page.dart b/lib/presentation/insurance/insurance_home_page.dart index 519d8306..35e3acb8 100644 --- a/lib/presentation/insurance/insurance_home_page.dart +++ b/lib/presentation/insurance/insurance_home_page.dart @@ -48,11 +48,11 @@ class _InsuranceHomePageState extends State { insuranceViewModel = Provider.of(context, listen: false); return CollapsingListView( title: "${LocaleKeys.insurance.tr(context: context)} ${LocaleKeys.updateInsurance.tr(context: context)}", - history: () { - insuranceViewModel.setIsInsuranceHistoryLoading(true); - insuranceViewModel.getPatientInsuranceCardHistory(); - showCommonBottomSheetWithoutHeight(context, child: InsuranceHistory(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); - }, + // history: () { + // // insuranceViewModel.setIsInsuranceHistoryLoading(true); + // // insuranceViewModel.getPatientInsuranceCardHistory(); + // showCommonBottomSheetWithoutHeight(context, child: InsuranceHistory(), callBackFunc: () {}, title: "", isCloseButtonVisible: false, isFullScreen: false); + // }, child: SingleChildScrollView( child: Consumer(builder: (context, insuranceVM, child) { return Column( @@ -66,12 +66,23 @@ class _InsuranceHomePageState extends State { isLoading: true, ).paddingSymmetrical(24.h, 24.h) : insuranceVM.patientInsuranceList.isNotEmpty - ? Padding( - padding: EdgeInsets.only(top: 24.h), - child: PatientInsuranceCard( - insuranceCardDetailsModel: insuranceVM.patientInsuranceList.first, - isInsuranceExpired: DateTime.now().isAfter(DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo))) - .paddingSymmetrical(24.w, 0.h), + ? ListView.builder( + shrinkWrap: true, + padding: EdgeInsets.all(16.h), + physics: const BouncingScrollPhysics(), + itemBuilder: (context, index) { + return Column( + children: [ + PatientInsuranceCard( + insuranceCardDetailsModel: insuranceVM.patientInsuranceList[index], + isInsuranceExpired: DateTime.now().isAfter(DateUtil.convertStringToDate(insuranceVM.patientInsuranceList.first.cardValidTo))), + SizedBox( + height: 12.h, + ) + ], + ); + }, + itemCount: insuranceVM.patientInsuranceList.length, ) : Padding( padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.12), diff --git a/lib/presentation/insurance/widgets/insurance_update_details_card.dart b/lib/presentation/insurance/widgets/insurance_update_details_card.dart index 2136f0cb..770f4da2 100644 --- a/lib/presentation/insurance/widgets/insurance_update_details_card.dart +++ b/lib/presentation/insurance/widgets/insurance_update_details_card.dart @@ -105,49 +105,51 @@ class PatientInsuranceCardUpdateCard extends StatelessWidget { iconSize: 20.w, text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", onPressed: () { - LoaderBottomSheet.showLoader(); - getIt().sendPatientUpdateRequest(onSuccess: (val) { - LoaderBottomSheet.hideLoader(); - insuranceViewModel.setIsInsuranceDataToBeLoaded(true); - insuranceViewModel.initInsuranceProvider(); - Navigator.pop(context); - }, onError: (err) { - insuranceViewModel.updatePatientInsuranceCard( - patientID: appState.getAuthenticatedUser()!.patientId!, - patientType: appState.getAuthenticatedUser()!.patientType!, - patientIdentificationID: appState.getAuthenticatedUser()!.patientIdentificationNo!, - mobileNo: appState.getAuthenticatedUser()!.mobileNumber!, - insuranceCardImage: "", - onSuccess: (val) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - title: LocaleKeys.success.tr(context: context), - context, - child: Utils.getSuccessWidget(loadingText: LocaleKeys.insuranceRequestSubmittedSuccessfully.tr(context: context)), - callBackFunc: () { - Navigator.pop(context); - }, - isFullScreen: false, - isCloseButtonVisible: false, - ); - // Future.delayed(Duration(milliseconds: 2000)).then((value) async { - // Navigator.pop(context); - // }); - }, - onError: (err) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - title: LocaleKeys.notice.tr(context: context), - context, - child: Utils.getErrorWidget(loadingText: err.toString()), - callBackFunc: () { - Navigator.pop(context); - }, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }); - }); + if (insuranceViewModel.patientInsuranceUpdateResponseModel != null) { + LoaderBottomSheet.showLoader(); + getIt().sendPatientUpdateRequest(onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + insuranceViewModel.setIsInsuranceDataToBeLoaded(true); + insuranceViewModel.initInsuranceProvider(); + Navigator.pop(context); + }, onError: (err) { + insuranceViewModel.updatePatientInsuranceCard( + patientID: appState.getAuthenticatedUser()!.patientId!, + patientType: appState.getAuthenticatedUser()!.patientType!, + patientIdentificationID: appState.getAuthenticatedUser()!.patientIdentificationNo!, + mobileNo: appState.getAuthenticatedUser()!.mobileNumber!, + insuranceCardImage: "", + onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.success.tr(context: context), + context, + child: Utils.getSuccessWidget(loadingText: LocaleKeys.insuranceRequestSubmittedSuccessfully.tr(context: context)), + callBackFunc: () { + Navigator.pop(context); + }, + isFullScreen: false, + isCloseButtonVisible: false, + ); + // Future.delayed(Duration(milliseconds: 2000)).then((value) async { + // Navigator.pop(context); + // }); + }, + onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.notice.tr(context: context), + context, + child: Utils.getErrorWidget(loadingText: err.toString()), + callBackFunc: () { + Navigator.pop(context); + }, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + }); + } }, backgroundColor: insuranceViewModel.patientInsuranceUpdateResponseModel != null ? AppColors.successColor : AppColors.lightGrayBGColor, borderColor: AppColors.successColor.withOpacity(0.01), diff --git a/lib/presentation/insurance/widgets/patient_insurance_card.dart b/lib/presentation/insurance/widgets/patient_insurance_card.dart index d6bb204f..1607a7c6 100644 --- a/lib/presentation/insurance/widgets/patient_insurance_card.dart +++ b/lib/presentation/insurance/widgets/patient_insurance_card.dart @@ -53,26 +53,30 @@ class PatientInsuranceCard extends StatelessWidget { SizedBox( width: MediaQuery.of(context).size.width * 0.4, child: "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}".toText18(isBold: true, textOverflow: TextOverflow.clip, isEnglishOnly: true)), - LocaleKeys.policyNumber.tr(namedArgs: {'number': insuranceCardDetailsModel.insurancePolicyNo ?? ''}, context: context).toText12(isBold: true, color: AppColors.lightGrayColor), + Row( + children: [ + "${LocaleKeys.policyNumber.tr(context: context)}${insuranceCardDetailsModel.insurancePolicyNo}".toText12(isBold: true, color: AppColors.lightGrayColor), + ], + ), ], ), AppCustomChipWidget( - icon: insuranceViewModel.isInsuranceExpired + icon: isCurrentPatientInsuranceExpired(insuranceCardDetailsModel.cardValidTo!) ? AppAssets.cancel_circle_icon : insuranceViewModel.isInsuranceActive ? AppAssets.insurance_active_icon : AppAssets.alertSquare, - labelText: insuranceViewModel.isInsuranceExpired + labelText: isCurrentPatientInsuranceExpired(insuranceCardDetailsModel.cardValidTo!) ? LocaleKeys.insuranceExpired.tr(context: context) : insuranceViewModel.isInsuranceActive ? LocaleKeys.insuranceActive.tr(context: context) : LocaleKeys.insuranceInActive.tr(context: context), - iconColor: insuranceViewModel.isInsuranceExpired + iconColor: isCurrentPatientInsuranceExpired(insuranceCardDetailsModel.cardValidTo!) ? AppColors.primaryRedColor : insuranceViewModel.isInsuranceActive ? AppColors.successColor : AppColors.warningColorYellow, - textColor: insuranceViewModel.isInsuranceExpired + textColor: isCurrentPatientInsuranceExpired(insuranceCardDetailsModel.cardValidTo!) ? AppColors.primaryRedColor : insuranceViewModel.isInsuranceActive ? AppColors.successColor @@ -110,7 +114,7 @@ class PatientInsuranceCard extends StatelessWidget { // ); } }, - backgroundColor: insuranceViewModel.isInsuranceExpired + backgroundColor: isCurrentPatientInsuranceExpired(insuranceCardDetailsModel.cardValidTo!) ? AppColors.primaryRedColor.withOpacity(0.1) : insuranceViewModel.isInsuranceActive ? AppColors.successColor.withOpacity(0.1) @@ -130,7 +134,23 @@ class PatientInsuranceCard extends StatelessWidget { ), SizedBox(height: 12.h), insuranceCardDetailsModel.groupName!.toText12(isBold: true), - insuranceCardDetailsModel.companyName!.toText12(isBold: true), + Row( + children: [ + insuranceCardDetailsModel.companyName!.toText12(isBold: true), + SizedBox( + width: 6.h, + ), + Container( + padding: EdgeInsets.symmetric(horizontal: 6.h, vertical: 4.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.infoColor, + borderRadius: 50.r, + ), + child: (insuranceCardDetailsModel.subCategoryDesc!.length > 5 ? insuranceCardDetailsModel.subCategoryDesc!.substring(0, 12) : insuranceCardDetailsModel.subCategoryDesc!) + .toText8(isBold: true, color: AppColors.whiteColor), + ), + ], + ), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, @@ -150,9 +170,10 @@ class PatientInsuranceCard extends StatelessWidget { isInsuranceExpired ? CustomButton( icon: AppAssets.update_insurance_card_icon, - iconColor: AppColors.successColor, + iconColor: AppColors.warningColorYellow, iconSize: 15.h, - text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", + // text: "${LocaleKeys.updateInsurance.tr(context: context)} ${LocaleKeys.updateInsuranceSubtitle.tr(context: context)}", + text: LocaleKeys.verifyInsurance.tr(context: context), onPressed: () { insuranceViewModel.setIsInsuranceUpdateDetailsLoading(true); insuranceViewModel.getPatientInsuranceDetailsForUpdate( @@ -165,9 +186,9 @@ class PatientInsuranceCard extends StatelessWidget { isCloseButtonVisible: false, isFullScreen: false); }, - backgroundColor: AppColors.bgGreenColor.withOpacity(0.20), - borderColor: AppColors.bgGreenColor.withOpacity(0.0), - textColor: AppColors.bgGreenColor, + backgroundColor: AppColors.warningColorYellow.withOpacity(0.20), + borderColor: AppColors.warningColorYellow.withOpacity(0.0), + textColor: AppColors.warningColorYellow, fontSize: 14, fontWeight: FontWeight.w500, borderRadius: 12, @@ -180,4 +201,10 @@ class PatientInsuranceCard extends StatelessWidget { ), ).paddingSymmetrical(0.h, 0.h); } + + bool isCurrentPatientInsuranceExpired(String cardValidTo) { + return DateTime.now().isAfter( + DateUtil.convertStringToDate(cardValidTo), + ); + } } diff --git a/lib/presentation/lab/lab_orders_page.dart b/lib/presentation/lab/lab_orders_page.dart index bb2c3034..b38ad737 100644 --- a/lib/presentation/lab/lab_orders_page.dart +++ b/lib/presentation/lab/lab_orders_page.dart @@ -1 +1 @@ -import 'dart:async'; import 'dart:convert'; 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/appbar/collapsing_list_view.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'; import 'dart:ui' as ui; 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 CollapsingListView( title: LocaleKeys.labResults.tr(context: context), search: () async { if (labProvider.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: labProvider.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; labProvider.filterLabReports(value); } } }, child: Consumer( builder: (context, labViewModel, child) { return SingleChildScrollView( physics: NeverScrollableScrollPhysics(), 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: () { labViewModel.setIsSortByClinic(true); }, backgroundColor: labViewModel.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, borderColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12.f, 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: () { labViewModel.setIsSortByClinic(false); }, backgroundColor: labViewModel.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, borderColor: labViewModel.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, textColor: labViewModel.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 ? Column( children: [ AppCustomChipWidget( labelText: selectedFilterText!, backgroundColor: AppColors.alertColor, textColor: AppColors.whiteColor, deleteIcon: AppAssets.close_bottom_sheet_icon, deleteIconColor: AppColors.whiteColor, deleteIconHasColor: true, onDeleteTap: () { selectedFilterText = ""; labProvider.filterLabReports(""); }, ), SizedBox(height: 8.h), ], ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available labViewModel.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (labViewModel.patientLabOrdersViewList.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: labViewModel.patientLabOrdersViewList.length, itemBuilder: (context, index) { final group = labViewModel.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( labViewModel.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: ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemBuilder: (cxt, index) { PatientLabOrdersResponseModel order = group[index]; 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!}"), isEnglishOnly: true, ), Directionality( textDirection: ui.TextDirection.ltr, child: AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), isEnglishOnly: true, )), AppCustomChipWidget( labelText: labViewModel.isSortByClinic ? (order.projectName ?? "") : (order.clinicDescription ?? ""), ), ], ), // 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: () { labViewModel.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), ], ).paddingOnly(top: 16, bottom: 16); }, separatorBuilder: (cxt, index) => Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), itemCount: group.length)) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (labViewModel.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: labViewModel.indexedCharacterForUniqueTest, details: labViewModel.uniqueTestsList, labViewModel: labViewModel, 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 'dart:convert'; 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/appbar/collapsing_list_view.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'; import 'dart:ui' as ui; 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 CollapsingListView( title: LocaleKeys.labResults.tr(context: context), search: () async { if (labProvider.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: labProvider.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; labProvider.filterLabReports(value); } } }, child: Consumer( builder: (context, labViewModel, child) { return SingleChildScrollView( physics: NeverScrollableScrollPhysics(), 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: () { // labViewModel.setIsSortByClinic(true); // }, // backgroundColor: labViewModel.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, // borderColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), // textColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, // fontSize: 12.f, // 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: () { // labViewModel.setIsSortByClinic(false); // }, // backgroundColor: labViewModel.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, // borderColor: labViewModel.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, // textColor: labViewModel.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 ? Column( children: [ AppCustomChipWidget( labelText: selectedFilterText!, backgroundColor: AppColors.alertColor, textColor: AppColors.whiteColor, deleteIcon: AppAssets.close_bottom_sheet_icon, deleteIconColor: AppColors.whiteColor, deleteIconHasColor: true, onDeleteTap: () { selectedFilterText = ""; labProvider.filterLabReports(""); }, ), SizedBox(height: 8.h), ], ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available labViewModel.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (labViewModel.patientLabOrders.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: labViewModel.patientLabOrders.length, itemBuilder: (context, index) { final group = labViewModel.patientLabOrders[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.testDetails!.length} ${LocaleKeys.tests.tr(context: context)}", backgroundColor: AppColors.successColor.withOpacity(0.1), textColor: AppColors.successColor, ), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), Row( mainAxisSize: MainAxisSize.min, children: [ Image.network( group.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: (group.doctorName ?? group.doctorNameEnglish ?? "").toString().toText14(weight: FontWeight.w500)), ], ), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ Directionality( textDirection: ui.TextDirection.ltr, child: AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(group.orderDate ?? ""), false), isEnglishOnly: true, )), AppCustomChipWidget( labelText: (group.projectName ?? ""), ), AppCustomChipWidget( labelText: (group.clinicDescription ?? ""), ), ], ), ], ), ), 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( children: [ ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemBuilder: (cxt, index) { PatientLabOrdersResponseModel order = group; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ "• ${order.testDetails![index].description!}".toText14(weight: FontWeight.w500), SizedBox(height: 4.h), order.testDetails![index].testDescriptionEn!.toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), // 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!}"), isEnglishOnly: true, // ), // Directionality( // textDirection: ui.TextDirection.ltr, // child: AppCustomChipWidget( // labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), // isEnglishOnly: true, // )), // AppCustomChipWidget( // labelText: labViewModel.isSortByClinic ? (order.projectName ?? "") : (order.clinicDescription ?? ""), // ), // ], // ), // // 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: () { // labViewModel.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), ], ).paddingOnly(top: 16, bottom: 16); }, separatorBuilder: (cxt, index) => Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), itemCount: group.testDetails!.length > 3 ? 3 : group.testDetails!.length), SizedBox(height: 16.h), CustomButton( text: "${LocaleKeys.viewResults.tr()} (${group.testDetails!.length})", onPressed: () { labProvider.currentlySelectedPatientOrder = group; labProvider.getPatientLabResultByHospital(group); labProvider.getPatientSpecialResult(group); Navigator.of(context).push( CustomPageRoute( page: LabResultByClinic(labOrder: group), ), ); }, backgroundColor: AppColors.infoColor.withAlpha(20), borderColor: AppColors.infoColor.withAlpha(0), textColor: AppColors.infoColor, fontSize: (isFoldable || isTablet) ? 12.f : 14.f, fontWeight: FontWeight.w500, borderRadius: 12.r, padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), height: 40.h, iconSize: 14.h, icon: AppAssets.view_report_icon, iconColor: AppColors.infoColor, ), SizedBox(height: 16.h), ], ), ) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (labViewModel.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: labViewModel.indexedCharacterForUniqueTest, details: labViewModel.uniqueTestsList, labViewModel: labViewModel, 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_result_via_clinic/lab_order_result_item.dart b/lib/presentation/lab/lab_result_via_clinic/lab_order_result_item.dart index cf6ce97b..1a97d48d 100644 --- a/lib/presentation/lab/lab_result_via_clinic/lab_order_result_item.dart +++ b/lib/presentation/lab/lab_result_via_clinic/lab_order_result_item.dart @@ -114,15 +114,15 @@ class LabOrderResultItem extends StatelessWidget { ), CustomButton( icon: AppAssets.view_report_icon, - iconColor: AppColors.primaryRedColor, + iconColor: AppColors.infoColor, iconSize: 16.h, text: LocaleKeys.viewReport.tr(context: context), onPressed: () { onTap(); }, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, + backgroundColor: AppColors.infoColor.withAlpha(20), + borderColor: AppColors.infoColor.withAlpha(0), + textColor: AppColors.infoColor, fontSize: 14, fontWeight: FontWeight.w500, borderRadius: 12, diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 5301d2e0..cddc4757 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -522,7 +522,7 @@ class _MedicalFilePageState extends State { ], ), ExpandableListItem( - title: LocaleKeys.trackerAndOthers.tr(context: context).toText18(weight: FontWeight.w600), + title: LocaleKeys.healthTrackers.tr(context: context).toText18(weight: FontWeight.w600), expandedBackgroundColor: Colors.transparent, children: [ SizedBox(height: 10.h), @@ -1347,12 +1347,12 @@ class _MedicalFilePageState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - LocaleKeys.healthTrackers.tr(context: context).toText16(weight: FontWeight.w500, color: AppColors.textColor), - ], - ), - SizedBox(height: 16.h), + // Row( + // children: [ + // LocaleKeys.healthTrackers.tr(context: context).toText16(weight: FontWeight.w500, color: AppColors.textColor), + // ], + // ), + // SizedBox(height: 16.h), GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, @@ -1391,11 +1391,11 @@ class _MedicalFilePageState extends State { ], ).paddingSymmetrical(0.w, 0.0), SizedBox(height: 16.h), - Row( - children: [ - LocaleKeys.others.tr(context: context).toText16(weight: FontWeight.w500, color: AppColors.textColor), - ], - ), + // Row( + // children: [ + // LocaleKeys.others.tr(context: context).toText16(weight: FontWeight.w500, color: AppColors.textColor), + // ], + // ), SizedBox(height: 16.h), GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( @@ -1408,21 +1408,22 @@ class _MedicalFilePageState extends State { padding: EdgeInsets.zero, shrinkWrap: true, children: [ - MedicalFileCard( - label: LocaleKeys.askYourDoctor.tr(context: context), - textColor: AppColors.blackColor, - backgroundColor: AppColors.whiteColor, - svgIcon: AppAssets.ask_doctor_medical_file_icon, - isLargeText: true, - iconSize: 36.w, - ).onPress(() { - getIt.get().initAskDoctorViewModel(); - Navigator.of(context).push( - CustomPageRoute( - page: AskDoctorPage(), - ), - ); - }), + // MedicalFileCard( + // label: LocaleKeys.askYourDoctor.tr(context: context), + // textColor: AppColors.blackColor, + // backgroundColor: AppColors.whiteColor, + // svgIcon: AppAssets.ask_doctor_medical_file_icon, + // isLargeText: true, + // iconSize: 36.w, + // ).onPress(() { + // getIt.get().initAskDoctorViewModel(); + // Navigator.of(context).push( + // CustomPageRoute( + // page: AskDoctorPage(), + // ), + // ); + // }), + // MedicalFileCard( // label: LocaleKeys.internetPairing.tr(context: context), // textColor: AppColors.blackColor, From 1709b80e84191906e489c0186dfde6475c308f26 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 30 Mar 2026 13:41:24 +0300 Subject: [PATCH 13/17] Updates --- assets/images/svg/image_icon.svg | 4 + assets/langs/ar-SA.json | 4 +- assets/langs/en-US.json | 4 +- lib/core/app_assets.dart | 1 + lib/core/location_util.dart | 22 +- lib/core/utils/calender_utils_new.dart | 28 +- .../contact_us/contact_us_view_model.dart | 30 +- .../prescriptions_view_model.dart | 2 +- .../radiology/radiology_view_model.dart | 28 +- lib/generated/locale_keys.g.dart | 2 + lib/presentation/contact_us/contact_us.dart | 2 + lib/presentation/contact_us/find_us_page.dart | 13 + .../contact_us/widgets/find_us_item_card.dart | 10 +- lib/presentation/lab/lab_orders_page.dart | 2 +- .../prescription_detail_page.dart | 19 +- .../prescriptions/prescription_item_view.dart | 93 +-- .../prescriptions_list_page.dart | 634 +++++++++++----- .../profile_settings/profile_settings.dart | 33 + .../radiology/radiology_orders_page.dart | 705 +++++++++++++----- .../radiology/radiology_result_page.dart | 98 +-- lib/widgets/appbar/collapsing_list_view.dart | 6 + lib/widgets/common_bottom_sheet.dart | 61 +- 22 files changed, 1289 insertions(+), 512 deletions(-) create mode 100644 assets/images/svg/image_icon.svg diff --git a/assets/images/svg/image_icon.svg b/assets/images/svg/image_icon.svg new file mode 100644 index 00000000..73945847 --- /dev/null +++ b/assets/images/svg/image_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 6df6d8c7..b78b8545 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1589,5 +1589,7 @@ "insuranceRequestSubmittedSuccessfully": "تم إرسال طلب تحديث بيانات التأمين بنجاح. سيتم إعلامك بمجرد الانتهاء.", "updatingEmailAddress": "جارٍ تحديث عنوان البريد الإلكتروني، يرجى الانتظار...", "verifyInsurance": "التحقق من التأمين", - "tests": "تحليل" + "tests": "تحليل", + "calendarPermissionAlert": "يرجى منح إذن الوصول إلى التقويم من إعدادات التطبيق لضبط تذكير تناول الدواء.", + "sortByLocation": "الترتيب حسب الموقع" } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index bedf03fd..cbea7b94 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1583,5 +1583,7 @@ "insuranceRequestSubmittedSuccessfully": "Your insurance update request has been successfully submitted. You will be notified once completed.", "updatingEmailAddress": "Updating email address, Please wait...", "verifyInsurance": "Verify Insurance", - "tests": "tests" + "tests": "tests", + "calendarPermissionAlert": "Please grant calendar access permission from app settings to set medication reminder.", + "sortByLocation": "Sort by location" } diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index 9d5f28c8..86fbb07e 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -336,6 +336,7 @@ class AppAssets { static const String aiOverView = '$svgBasePath/ai_overview.svg'; static const String darkModeIcon = '$svgBasePath/dark_mode_icon.svg'; static const String biometricLockIcon = '$svgBasePath/biometric_lock_icon.svg'; + static const String imageIcon = '$svgBasePath/image_icon.svg'; // PNGS // static const String hmgLogo = '$pngBasePath/hmg_logo.png'; diff --git a/lib/core/location_util.dart b/lib/core/location_util.dart index cf26d24e..95b154ba 100644 --- a/lib/core/location_util.dart +++ b/lib/core/location_util.dart @@ -94,7 +94,27 @@ class LocationUtils { permissionGranted = await Geolocator.requestPermission(); if (permissionGranted != LocationPermission.whileInUse && permissionGranted != LocationPermission.always) { appState.resetLocation(); - onFailure?.call(); + if (onFailure == null && isShowConfirmDialog) { + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.notice.tr(context: navigationService.navigatorKey.currentContext!), + navigationService.navigatorKey.currentContext!, + child: Utils.getWarningWidget( + loadingText: "Please grant location permission from app settings to see better results", + isShowActionButtons: true, + onCancelTap: () { + navigationService.pop(); + }, + onConfirmTap: () async { + navigationService.pop(); + openAppSettings(); + }), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } else { + onFailure?.call(); + } return; } } else if (permissionGranted == LocationPermission.deniedForever) { diff --git a/lib/core/utils/calender_utils_new.dart b/lib/core/utils/calender_utils_new.dart index 9edfdced..331cf6d5 100644 --- a/lib/core/utils/calender_utils_new.dart +++ b/lib/core/utils/calender_utils_new.dart @@ -1,9 +1,16 @@ import 'dart:async'; import 'package:device_calendar_plus/device_calendar_plus.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:get_it/get_it.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:jiffy/jiffy.dart' show Jiffy; import 'package:manage_calendar_events/manage_calendar_events.dart' hide Calendar; +import 'package:permission_handler/permission_handler.dart'; class CalenderUtilsNew { final DeviceCalendar calender = DeviceCalendar.instance; @@ -17,7 +24,26 @@ class CalenderUtilsNew { Future getCalenders() async { CalendarPermissionStatus result = await DeviceCalendar.instance.hasPermissions(); - if (result != CalendarPermissionStatus.granted) await DeviceCalendar.instance.requestPermissions(); + if (result != CalendarPermissionStatus.granted) { + // await DeviceCalendar.instance.requestPermissions(); + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.notice.tr(context: GetIt.instance().navigatorKey.currentContext!), + GetIt.instance().navigatorKey.currentContext!, + child: Utils.getWarningWidget( + loadingText: LocaleKeys.calendarPermissionAlert.tr(), + isShowActionButtons: true, + onCancelTap: () { + GetIt.instance().pop(); + }, + onConfirmTap: () async { + GetIt.instance().pop(); + openAppSettings(); + }), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } var calenders = await calender.listCalendars(); calenders.forEach((calender) { if (!calender.readOnly) { diff --git a/lib/features/contact_us/contact_us_view_model.dart b/lib/features/contact_us/contact_us_view_model.dart index d627c55e..dba89a51 100644 --- a/lib/features/contact_us/contact_us_view_model.dart +++ b/lib/features/contact_us/contact_us_view_model.dart @@ -12,6 +12,7 @@ import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_p import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_status_coc_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; +import 'package:permission_handler/permission_handler.dart'; class ContactUsViewModel extends ChangeNotifier { ContactUsRepo contactUsRepo; @@ -22,6 +23,7 @@ class ContactUsViewModel extends ChangeNotifier { bool isHMGHospitalsListSelected = true; bool isLiveChatProjectsListLoading = false; bool isSendFeedbackTabSelected = true; + bool hasLocationEnabled = false; List hmgHospitalsLocationsList = []; List hmgPharmacyLocationsList = []; @@ -52,11 +54,12 @@ class ContactUsViewModel extends ChangeNotifier { ContactUsViewModel({required this.contactUsRepo, required this.errorHandlerService, required this.appState}); - initContactUsViewModel() { + initContactUsViewModel() async { isHMGLocationsListLoading = true; isHMGHospitalsListSelected = true; isLiveChatProjectsListLoading = true; isCOCItemsListLoading = true; + hasLocationEnabled = false; hmgHospitalsLocationsList.clear(); hmgPharmacyLocationsList.clear(); liveChatProjectsList.clear(); @@ -65,6 +68,18 @@ class ContactUsViewModel extends ChangeNotifier { selectedFeedbackType = FeedbackType(id: 5, nameEN: "Not classified", nameAR: 'غير محدد'); setPatientFeedbackSelectedAppointment(null); getHMGLocations(); + + if (await Permission.location.isGranted) { + setHasLocationEnabled(true); + } else { + setHasLocationEnabled(false); + } + + notifyListeners(); + } + + setHasLocationEnabled(bool hasLocationEnabled) { + this.hasLocationEnabled = hasLocationEnabled; notifyListeners(); } @@ -128,6 +143,19 @@ class ContactUsViewModel extends ChangeNotifier { hmgPharmacyLocationsList.add(location); } } + + if (hmgHospitalsLocationsList.first.distanceInKilometers != 0) { + hmgHospitalsLocationsList.sort((a, b) => a.distanceInKilometers.compareTo(b.distanceInKilometers)); + } else { + hmgHospitalsLocationsList.sort((a, b) => a.locationName!.compareTo(b.locationName!)); + } + + if (hmgPharmacyLocationsList.first.distanceInKilometers != 0) { + hmgPharmacyLocationsList.sort((a, b) => a.distanceInKilometers.compareTo(b.distanceInKilometers)); + } else { + hmgPharmacyLocationsList.sort((a, b) => a.locationName!.compareTo(b.locationName!)); + } + isHMGLocationsListLoading = false; notifyListeners(); if (onSuccess != null) { diff --git a/lib/features/prescriptions/prescriptions_view_model.dart b/lib/features/prescriptions/prescriptions_view_model.dart index c0f9c7b5..1fd8a000 100644 --- a/lib/features/prescriptions/prescriptions_view_model.dart +++ b/lib/features/prescriptions/prescriptions_view_model.dart @@ -163,7 +163,7 @@ class PrescriptionsViewModel extends ChangeNotifier { } else if (apiResponse.messageStatus == 1) { prescriptionDetailsList = apiResponse.data!; prescriptionDetailsList.forEach((element) async { - await checkIfReminderExistForPrescription(prescriptionDetailsList.indexOf(element)); + // await checkIfReminderExistForPrescription(prescriptionDetailsList.indexOf(element)); }); isPrescriptionsDetailsLoading = false; notifyListeners(); diff --git a/lib/features/radiology/radiology_view_model.dart b/lib/features/radiology/radiology_view_model.dart index ee5c970f..fa43a96d 100644 --- a/lib/features/radiology/radiology_view_model.dart +++ b/lib/features/radiology/radiology_view_model.dart @@ -68,17 +68,17 @@ class RadiologyViewModel extends ChangeNotifier { filteredRadiologyOrders = List.from(patientRadiologyOrders); tempRadiologyOrders = [...patientRadiologyOrders]; - final clinicMap = >{}; - final hospitalMap = >{}; - for (var order in patientRadiologyOrders) { - final clinicKey = (order.clinicDescription ?? 'Unknown').trim(); - clinicMap.putIfAbsent(clinicKey, () => []).add(order); - final hospitalKey = (order.projectName ?? order.projectID ?? 'Unknown').toString().trim(); - hospitalMap.putIfAbsent(hospitalKey, () => []).add(order); - } - patientRadiologyOrdersByClinic = clinicMap.values.toList(); - patientRadiologyOrdersByHospital = hospitalMap.values.toList(); - patientRadiologyOrdersViewList = isSortByClinic ? patientRadiologyOrdersByClinic : patientRadiologyOrdersByHospital; + // final clinicMap = >{}; + // final hospitalMap = >{}; + // for (var order in patientRadiologyOrders) { + // final clinicKey = (order.clinicDescription ?? 'Unknown').trim(); + // clinicMap.putIfAbsent(clinicKey, () => []).add(order); + // final hospitalKey = (order.projectName ?? order.projectID ?? 'Unknown').toString().trim(); + // hospitalMap.putIfAbsent(hospitalKey, () => []).add(order); + // } + // patientRadiologyOrdersByClinic = clinicMap.values.toList(); + // patientRadiologyOrdersByHospital = hospitalMap.values.toList(); + // patientRadiologyOrdersViewList = isSortByClinic ? patientRadiologyOrdersByClinic : patientRadiologyOrdersByHospital; isRadiologyOrdersLoading = false; filterSuggestions(); @@ -173,7 +173,7 @@ class RadiologyViewModel extends ChangeNotifier { } filterSuggestions() { - final List labels = patientRadiologyOrders.map((detail) => detail.description).whereType().toList(); + final List labels = patientRadiologyOrders.map((detail) => detail.procedureName.toString().trim()).whereType().toList(); _radiologySuggestionsList = labels.toSet().toList(); notifyListeners(); } @@ -193,7 +193,7 @@ class RadiologyViewModel extends ChangeNotifier { patientRadiologyOrdersByHospital = hospitalMap.values.toList(); patientRadiologyOrdersViewList = isSortByClinic ? patientRadiologyOrdersByClinic : patientRadiologyOrdersByHospital; } else { - filteredRadiologyOrders = filteredRadiologyOrders.where((desc) => (desc.description ?? "").toLowerCase().contains(query.toLowerCase())).toList(); + filteredRadiologyOrders = filteredRadiologyOrders.where((desc) => (desc.procedureName ?? "").toLowerCase().contains(query.toLowerCase())).toList(); final clinicMap = >{}; final hospitalMap = >{}; @@ -206,6 +206,8 @@ class RadiologyViewModel extends ChangeNotifier { patientRadiologyOrdersByClinic = clinicMap.values.toList(); patientRadiologyOrdersByHospital = hospitalMap.values.toList(); patientRadiologyOrdersViewList = isSortByClinic ? patientRadiologyOrdersByClinic : patientRadiologyOrdersByHospital; + + patientRadiologyOrders = filteredRadiologyOrders; } notifyListeners(); } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index ac9f3f7c..4f66d29c 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1584,5 +1584,7 @@ abstract class LocaleKeys { static const updatingEmailAddress = 'updatingEmailAddress'; static const verifyInsurance = 'verifyInsurance'; static const tests = 'tests'; + static const calendarPermissionAlert = 'calendarPermissionAlert'; + static const sortByLocation = 'sortByLocation'; } diff --git a/lib/presentation/contact_us/contact_us.dart b/lib/presentation/contact_us/contact_us.dart index 16a154a1..70ef6e3f 100644 --- a/lib/presentation/contact_us/contact_us.dart +++ b/lib/presentation/contact_us/contact_us.dart @@ -57,6 +57,7 @@ class ContactUs extends StatelessWidget { ), ); }, onFailure: () { + contactUsViewModel.initContactUsViewModel(); Navigator.pop(context); Navigator.of(context).push( CustomPageRoute( @@ -64,6 +65,7 @@ class ContactUs extends StatelessWidget { ), ); }, onLocationDeniedForever: () { + contactUsViewModel.initContactUsViewModel(); Navigator.pop(context); Navigator.of(context).push( CustomPageRoute( diff --git a/lib/presentation/contact_us/find_us_page.dart b/lib/presentation/contact_us/find_us_page.dart index 5957bb83..7707754a 100644 --- a/lib/presentation/contact_us/find_us_page.dart +++ b/lib/presentation/contact_us/find_us_page.dart @@ -3,6 +3,7 @@ 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/location_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; @@ -20,15 +21,27 @@ class FindUsPage extends StatelessWidget { late AppState appState; late ContactUsViewModel contactUsViewModel; + late LocationUtils locationUtils; @override Widget build(BuildContext context) { contactUsViewModel = Provider.of(context); appState = getIt.get(); + locationUtils = getIt.get(); + locationUtils.isShowConfirmDialog = true; return Scaffold( backgroundColor: AppColors.bgScaffoldColor, body: CollapsingListView( title: LocaleKeys.location.tr(), + location: contactUsViewModel.hasLocationEnabled + ? null + : () { + locationUtils.getCurrentLocation( + onSuccess: (value) { + contactUsViewModel.initContactUsViewModel(); + }, + onFailure: () {},); + }, child: Consumer(builder: (context, contactUsVM, child) { return Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/presentation/contact_us/widgets/find_us_item_card.dart b/lib/presentation/contact_us/widgets/find_us_item_card.dart index 4738a63a..063ea153 100644 --- a/lib/presentation/contact_us/widgets/find_us_item_card.dart +++ b/lib/presentation/contact_us/widgets/find_us_item_card.dart @@ -69,13 +69,15 @@ class FindUsItemCard extends StatelessWidget { Widget get distanceInfo => Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - AppCustomChipWidget( - labelText: "${getHMGLocationsModel.distanceInKilometers ?? ""} km", - icon: AppAssets.location_red, + getHMGLocationsModel.distanceInKilometers != 0 + ? AppCustomChipWidget( + labelText: "${getHMGLocationsModel.distanceInKilometers ?? ""} km", + icon: AppAssets.location_red, iconColor: AppColors.primaryRedColor, backgroundColor: AppColors.secondaryLightRedColor, textColor: AppColors.errorColor, - ), + ) + : SizedBox.shrink(), Row( children: [ AppCustomChipWidget( diff --git a/lib/presentation/lab/lab_orders_page.dart b/lib/presentation/lab/lab_orders_page.dart index b38ad737..bde9d90e 100644 --- a/lib/presentation/lab/lab_orders_page.dart +++ b/lib/presentation/lab/lab_orders_page.dart @@ -1 +1 @@ -import 'dart:async'; import 'dart:convert'; 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/appbar/collapsing_list_view.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'; import 'dart:ui' as ui; 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 CollapsingListView( title: LocaleKeys.labResults.tr(context: context), search: () async { if (labProvider.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: labProvider.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; labProvider.filterLabReports(value); } } }, child: Consumer( builder: (context, labViewModel, child) { return SingleChildScrollView( physics: NeverScrollableScrollPhysics(), 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: () { // labViewModel.setIsSortByClinic(true); // }, // backgroundColor: labViewModel.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, // borderColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), // textColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, // fontSize: 12.f, // 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: () { // labViewModel.setIsSortByClinic(false); // }, // backgroundColor: labViewModel.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, // borderColor: labViewModel.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, // textColor: labViewModel.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 ? Column( children: [ AppCustomChipWidget( labelText: selectedFilterText!, backgroundColor: AppColors.alertColor, textColor: AppColors.whiteColor, deleteIcon: AppAssets.close_bottom_sheet_icon, deleteIconColor: AppColors.whiteColor, deleteIconHasColor: true, onDeleteTap: () { selectedFilterText = ""; labProvider.filterLabReports(""); }, ), SizedBox(height: 8.h), ], ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available labViewModel.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (labViewModel.patientLabOrders.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: labViewModel.patientLabOrders.length, itemBuilder: (context, index) { final group = labViewModel.patientLabOrders[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.testDetails!.length} ${LocaleKeys.tests.tr(context: context)}", backgroundColor: AppColors.successColor.withOpacity(0.1), textColor: AppColors.successColor, ), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), Row( mainAxisSize: MainAxisSize.min, children: [ Image.network( group.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: (group.doctorName ?? group.doctorNameEnglish ?? "").toString().toText14(weight: FontWeight.w500)), ], ), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ Directionality( textDirection: ui.TextDirection.ltr, child: AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(group.orderDate ?? ""), false), isEnglishOnly: true, )), AppCustomChipWidget( labelText: (group.projectName ?? ""), ), AppCustomChipWidget( labelText: (group.clinicDescription ?? ""), ), ], ), ], ), ), 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( children: [ ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemBuilder: (cxt, index) { PatientLabOrdersResponseModel order = group; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ "• ${order.testDetails![index].description!}".toText14(weight: FontWeight.w500), SizedBox(height: 4.h), order.testDetails![index].testDescriptionEn!.toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), // 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!}"), isEnglishOnly: true, // ), // Directionality( // textDirection: ui.TextDirection.ltr, // child: AppCustomChipWidget( // labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), // isEnglishOnly: true, // )), // AppCustomChipWidget( // labelText: labViewModel.isSortByClinic ? (order.projectName ?? "") : (order.clinicDescription ?? ""), // ), // ], // ), // // 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: () { // labViewModel.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), ], ).paddingOnly(top: 16, bottom: 16); }, separatorBuilder: (cxt, index) => Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), itemCount: group.testDetails!.length > 3 ? 3 : group.testDetails!.length), SizedBox(height: 16.h), CustomButton( text: "${LocaleKeys.viewResults.tr()} (${group.testDetails!.length})", onPressed: () { labProvider.currentlySelectedPatientOrder = group; labProvider.getPatientLabResultByHospital(group); labProvider.getPatientSpecialResult(group); Navigator.of(context).push( CustomPageRoute( page: LabResultByClinic(labOrder: group), ), ); }, backgroundColor: AppColors.infoColor.withAlpha(20), borderColor: AppColors.infoColor.withAlpha(0), textColor: AppColors.infoColor, fontSize: (isFoldable || isTablet) ? 12.f : 14.f, fontWeight: FontWeight.w500, borderRadius: 12.r, padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), height: 40.h, iconSize: 14.h, icon: AppAssets.view_report_icon, iconColor: AppColors.infoColor, ), SizedBox(height: 16.h), ], ), ) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (labViewModel.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: labViewModel.indexedCharacterForUniqueTest, details: labViewModel.uniqueTestsList, labViewModel: labViewModel, 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 'dart:convert'; 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/appbar/collapsing_list_view.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'; import 'dart:ui' as ui; 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 CollapsingListView( title: LocaleKeys.labResults.tr(context: context), search: () async { if (labProvider.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: labProvider.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; labProvider.filterLabReports(value); } } }, child: Consumer( builder: (context, labViewModel, child) { return SingleChildScrollView( physics: NeverScrollableScrollPhysics(), 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: () { // labViewModel.setIsSortByClinic(true); // }, // backgroundColor: labViewModel.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, // borderColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), // textColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, // fontSize: 12.f, // 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: () { // labViewModel.setIsSortByClinic(false); // }, // backgroundColor: labViewModel.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, // borderColor: labViewModel.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, // textColor: labViewModel.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 ? Column( children: [ AppCustomChipWidget( labelText: selectedFilterText!, backgroundColor: AppColors.alertColor, textColor: AppColors.whiteColor, deleteIcon: AppAssets.close_bottom_sheet_icon, deleteIconColor: AppColors.whiteColor, deleteIconHasColor: true, onDeleteTap: () { selectedFilterText = ""; labProvider.filterLabReports(""); }, ), SizedBox(height: 8.h), ], ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available labViewModel.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (labViewModel.patientLabOrders.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: labViewModel.patientLabOrders.length, itemBuilder: (context, index) { final group = labViewModel.patientLabOrders[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: [ Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ AppCustomChipWidget( labelText: "${group.testDetails!.length} ${LocaleKeys.tests.tr(context: context)}", backgroundColor: AppColors.successColor.withOpacity(0.1), textColor: AppColors.successColor, ), AppCustomChipWidget( labelText: "${_appState.isArabic() ? group.isInOutPatientDescriptionN : group.isInOutPatientDescription}", backgroundColor: group.isInOutPatient! ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.warningColorYellow.withOpacity(0.1), textColor: group.isInOutPatient! ? AppColors.primaryRedColor : AppColors.warningColorYellow, ) ], ), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), Row( mainAxisSize: MainAxisSize.min, children: [ Image.network( group.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: (group.doctorName ?? group.doctorNameEnglish ?? "").toString().toText14(weight: FontWeight.w500)), ], ), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ Directionality( textDirection: ui.TextDirection.ltr, child: AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(group.orderDate ?? ""), false), isEnglishOnly: true, )), AppCustomChipWidget( labelText: (group.projectName ?? ""), ), AppCustomChipWidget( labelText: (group.clinicDescription ?? ""), ), ], ), ], ), ), 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( children: [ ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemBuilder: (cxt, index) { PatientLabOrdersResponseModel order = group; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ "• ${order.testDetails![index].description!}".toText14(weight: FontWeight.w500), SizedBox(height: 4.h), order.testDetails![index].testDescriptionEn!.toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), // 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!}"), isEnglishOnly: true, // ), // Directionality( // textDirection: ui.TextDirection.ltr, // child: AppCustomChipWidget( // labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), // isEnglishOnly: true, // )), // AppCustomChipWidget( // labelText: labViewModel.isSortByClinic ? (order.projectName ?? "") : (order.clinicDescription ?? ""), // ), // ], // ), // // 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: () { // labViewModel.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), ], ).paddingOnly(top: 16, bottom: 16); }, separatorBuilder: (cxt, index) => Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), itemCount: group.testDetails!.length > 3 ? 3 : group.testDetails!.length), SizedBox(height: 16.h), CustomButton( text: "${LocaleKeys.viewResults.tr()} (${group.testDetails!.length})", onPressed: () { labProvider.currentlySelectedPatientOrder = group; labProvider.getPatientLabResultByHospital(group); labProvider.getPatientSpecialResult(group); Navigator.of(context).push( CustomPageRoute( page: LabResultByClinic(labOrder: group), ), ); }, backgroundColor: AppColors.infoColor.withAlpha(20), borderColor: AppColors.infoColor.withAlpha(0), textColor: AppColors.infoColor, fontSize: (isFoldable || isTablet) ? 12.f : 14.f, fontWeight: FontWeight.w500, borderRadius: 12.r, padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), height: 40.h, iconSize: 14.h, icon: AppAssets.view_report_icon, iconColor: AppColors.infoColor, ), SizedBox(height: 16.h), ], ), ) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (labViewModel.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: labViewModel.indexedCharacterForUniqueTest, details: labViewModel.uniqueTestsList, labViewModel: labViewModel, 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/prescriptions/prescription_detail_page.dart b/lib/presentation/prescriptions/prescription_detail_page.dart index ec2cd1a0..235ad554 100644 --- a/lib/presentation/prescriptions/prescription_detail_page.dart +++ b/lib/presentation/prescriptions/prescription_detail_page.dart @@ -4,6 +4,8 @@ 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_assets.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/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; @@ -63,8 +65,9 @@ class _PrescriptionDetailPageState extends State { Expanded( child: CollapsingListView( title: LocaleKeys.prescriptions.tr(context: context), - instructions: () async { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingPrescriptionPDFPleaseWait.tr(context: context)); + instructions: widget.prescriptionsResponseModel.isInOutPatient! + ? () async { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingPrescriptionPDFPleaseWait.tr(context: context)); await prescriptionsViewModel.getPrescriptionInstructionsPDF(widget.prescriptionsResponseModel, onSuccess: (val) { LoaderBottomSheet.hideLoader(); if (prescriptionsViewModel.prescriptionInstructionsPDFLink.isNotEmpty) { @@ -89,7 +92,8 @@ class _PrescriptionDetailPageState extends State { isCloseButtonVisible: true, ); }); - }, + } + : null, child: SingleChildScrollView( child: Consumer(builder: (context, prescriptionVM, child) { return Column( @@ -107,6 +111,13 @@ class _PrescriptionDetailPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + AppCustomChipWidget( + labelText: + "${getIt.get().isArabic() ? widget.prescriptionsResponseModel.isInOutPatientDescriptionN : widget.prescriptionsResponseModel.isInOutPatientDescription}", + backgroundColor: widget.prescriptionsResponseModel.isInOutPatient! ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.warningColorYellow.withOpacity(0.1), + textColor: widget.prescriptionsResponseModel.isInOutPatient! ? AppColors.primaryRedColor : AppColors.warningColorYellow, + ), + SizedBox(height: 16.h), Row( mainAxisSize: MainAxisSize.min, children: [ @@ -241,7 +252,7 @@ class _PrescriptionDetailPageState extends State { }); } }, - backgroundColor: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.greyF7Color, + backgroundColor: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.15), borderColor: AppColors.successColor.withOpacity(0.01), textColor: widget.prescriptionsResponseModel.isHomeMedicineDeliverySupported! ? Colors.white : AppColors.textColor.withOpacity(0.35), fontSize: 16, diff --git a/lib/presentation/prescriptions/prescription_item_view.dart b/lib/presentation/prescriptions/prescription_item_view.dart index c5cd50c2..2b19e3a4 100644 --- a/lib/presentation/prescriptions/prescription_item_view.dart +++ b/lib/presentation/prescriptions/prescription_item_view.dart @@ -103,55 +103,60 @@ class PrescriptionItemView extends StatelessWidget { Switch( activeColor: AppColors.successColor, activeTrackColor: AppColors.successColor.withValues(alpha: .15), - value: isLoading ? false : prescriptionVM.prescriptionDetailsList[index].hasReminder!, + // value: isLoading ? false : prescriptionVM.prescriptionDetailsList[index].hasReminder!, + value: prescriptionVM.prescriptionDetailsList[index].hasReminder!, onChanged: (newValue) async { CalenderUtilsNew calender = CalenderUtilsNew.instance; - if (prescriptionVM.prescriptionDetailsList[index].hasReminder ?? false) { - LoaderBottomSheet.showLoader(loadingText: "Removing Reminders"); - bool resultValue = await calender.checkAndRemoveMultipleItems(id: prescriptionVM.prescriptionDetailsList[index].itemID.toString()); + if (await prescriptionVM.checkIfReminderExistForPrescription(index)) { + prescriptionVM.prescriptionDetailsList[index].hasReminder = true; + } else { + if (prescriptionVM.prescriptionDetailsList[index].hasReminder ?? false) { + LoaderBottomSheet.showLoader(loadingText: "Removing Reminders"); + bool resultValue = await calender.checkAndRemoveMultipleItems(id: prescriptionVM.prescriptionDetailsList[index].itemID.toString()); - prescriptionVM.setPrescriptionItemReminder(newValue, prescriptionVM.prescriptionDetailsList[index]); - LoaderBottomSheet.hideLoader(); - return; - } + prescriptionVM.setPrescriptionItemReminder(newValue, prescriptionVM.prescriptionDetailsList[index]); + LoaderBottomSheet.hideLoader(); + return; + } - DateTime startDate = DateTime.now(); - DateTime endDate = DateTime(startDate.year, startDate.month, startDate.day + prescriptionVM.prescriptionDetailsList[index].days!.toInt()); - BottomSheetUtils().showReminderBottomSheet( - context, - endDate, - "", - prescriptionVM.prescriptionDetailsList[index].itemID.toString(), - "", - "", - title: "${prescriptionVM.prescriptionDetailsList[index].itemDescription} Prescription Reminder", - description: - "${prescriptionVM.prescriptionDetailsList[index].itemDescription} ${prescriptionVM.prescriptionDetailsList[index].frequency} ${prescriptionVM.prescriptionDetailsList[index].route} ", - onSuccess: () {}, - isMultiAllowed: true, - onMultiDateSuccess: (int selectedIndex) async { - bool isEventAdded = await calender.createMultipleEvents( - reminderMinutes: selectedIndex, - frequencyNumber: prescriptionVM.prescriptionDetailsList[index].frequencyNumber?.toInt(), - days: prescriptionVM.prescriptionDetailsList[index].days!.toInt(), - orderDate: prescriptionVM.prescriptionDetailsList[index].orderDate!, - itemDescriptionN: prescriptionVM.prescriptionDetailsList[index].itemDescription!, - route: prescriptionVM.prescriptionDetailsList[index].route!, - onFailure: (errorMessage) => prescriptionVM.showError(errorMessage), - prescriptionNumber: prescriptionVM.prescriptionDetailsList[index].itemID.toString(), - ); - prescriptionVM.setPrescriptionItemReminder(isEventAdded, prescriptionVM.prescriptionDetailsList[index]); - // setCalender(context, - // eventId: prescriptionVM.prescriptionDetailsList[index].itemID.toString(), - // selectedMinutes: selectedIndex, - // frequencyNumber: prescriptionVM.prescriptionDetailsList[index].frequencyNumber?.toInt(), - // days: prescriptionVM.prescriptionDetailsList[index].days!.toInt(), - // orderDate: prescriptionVM.prescriptionDetailsList[index].orderDate!, - // itemDescriptionN: prescriptionVM.prescriptionDetailsList[index].itemDescription!, - // route: prescriptionVM.prescriptionDetailsList[index].route!); - }, - ); + DateTime startDate = DateTime.now(); + DateTime endDate = DateTime(startDate.year, startDate.month, startDate.day + prescriptionVM.prescriptionDetailsList[index].days!.toInt()); + BottomSheetUtils().showReminderBottomSheet( + context, + endDate, + "", + prescriptionVM.prescriptionDetailsList[index].itemID.toString(), + "", + "", + title: "${prescriptionVM.prescriptionDetailsList[index].itemDescription} Prescription Reminder", + description: + "${prescriptionVM.prescriptionDetailsList[index].itemDescription} ${prescriptionVM.prescriptionDetailsList[index].frequency} ${prescriptionVM.prescriptionDetailsList[index].route} ", + onSuccess: () {}, + isMultiAllowed: true, + onMultiDateSuccess: (int selectedIndex) async { + bool isEventAdded = await calender.createMultipleEvents( + reminderMinutes: selectedIndex, + frequencyNumber: prescriptionVM.prescriptionDetailsList[index].frequencyNumber?.toInt(), + days: prescriptionVM.prescriptionDetailsList[index].days!.toInt(), + orderDate: prescriptionVM.prescriptionDetailsList[index].orderDate!, + itemDescriptionN: prescriptionVM.prescriptionDetailsList[index].itemDescription!, + route: prescriptionVM.prescriptionDetailsList[index].route!, + onFailure: (errorMessage) => prescriptionVM.showError(errorMessage), + prescriptionNumber: prescriptionVM.prescriptionDetailsList[index].itemID.toString(), + ); + prescriptionVM.setPrescriptionItemReminder(isEventAdded, prescriptionVM.prescriptionDetailsList[index]); + // setCalender(context, + // eventId: prescriptionVM.prescriptionDetailsList[index].itemID.toString(), + // selectedMinutes: selectedIndex, + // frequencyNumber: prescriptionVM.prescriptionDetailsList[index].frequencyNumber?.toInt(), + // days: prescriptionVM.prescriptionDetailsList[index].days!.toInt(), + // orderDate: prescriptionVM.prescriptionDetailsList[index].orderDate!, + // itemDescriptionN: prescriptionVM.prescriptionDetailsList[index].itemDescription!, + // route: prescriptionVM.prescriptionDetailsList[index].route!); + }, + ); + } }, ).toShimmer2(isShow: isLoading), ], diff --git a/lib/presentation/prescriptions/prescriptions_list_page.dart b/lib/presentation/prescriptions/prescriptions_list_page.dart index 4eb297d5..da211f9d 100644 --- a/lib/presentation/prescriptions/prescriptions_list_page.dart +++ b/lib/presentation/prescriptions/prescriptions_list_page.dart @@ -69,52 +69,52 @@ class _PrescriptionsListPageState extends State { children: [ SizedBox(height: 16.h), // Clinic & Hospital Sort - 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.withOpacity(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.withOpacity(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, - ), - ], - ).paddingSymmetrical(24.h, 0.h), - SizedBox(height: 20.h), + // 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.withOpacity(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.withOpacity(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, + // ), + // ], + // ).paddingSymmetrical(24.h, 0.h), + // SizedBox(height: 20.h), // Expandable list ListView.builder( itemCount: model.isPrescriptionsOrdersLoading ? 4 : model.patientPrescriptionOrders.isNotEmpty - ? model.patientPrescriptionOrdersViewList.length + ? model.patientPrescriptionOrders.length : 1, physics: NeverScrollableScrollPhysics(), shrinkWrap: true, padding: const EdgeInsets.only(left: 0, right: 8), itemBuilder: (context, index) { - final isExpanded = expandedIndex == index; + // final isExpanded = expandedIndex == index; return model.isPrescriptionsOrdersLoading ? LabResultItemView( onTap: () {}, @@ -134,180 +134,416 @@ class _PrescriptionsListPageState extends State { 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: Container( + key: ValueKey(index), + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 16.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - CustomButton( - text: "${model.patientPrescriptionOrdersViewList[index].prescriptionsList!.length} Prescriptions Available", - 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: 30.h, - ), - Icon(isExpanded ? Icons.expand_less : Icons.expand_more), - ], + AppCustomChipWidget( + labelText: + "${getIt.get().isArabic() ? model.patientPrescriptionOrders[index].isInOutPatientDescriptionN : model.patientPrescriptionOrders[index].isInOutPatientDescription}", + backgroundColor: + model.patientPrescriptionOrders[index].isInOutPatient! ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.warningColorYellow.withOpacity(0.1), + textColor: model.patientPrescriptionOrders[index].isInOutPatient! ? AppColors.primaryRedColor : AppColors.warningColorYellow, + ), + SizedBox(height: 16.h), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Image.network( + model.patientPrescriptionOrders[index].doctorImageURL!, + width: 24.h, + height: 24.h, + fit: BoxFit.fill, + ).circle(100), + SizedBox(width: 8.h), + Expanded(child: model.patientPrescriptionOrders[index].doctorName!.toText14(weight: FontWeight.w500)), + ], + ), + SizedBox(height: 8.h), + Wrap( + direction: Axis.horizontal, + spacing: 6.h, + runSpacing: 6.h, + children: [ + Directionality( + textDirection: ui.TextDirection.ltr, + child: AppCustomChipWidget( + labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(model.patientPrescriptionOrders[index].appointmentDate), false), + isEnglishOnly: true, ), - SizedBox(height: 8.h), - (model.patientPrescriptionOrdersViewList[index].filterName ?? "").toText16(isBold: true) - ], - ), + ), + AppCustomChipWidget( + labelText: model.patientPrescriptionOrders[index].name, + ), + AppCustomChipWidget( + labelText: model.patientPrescriptionOrders[index].clinicDescription!, + ), + ], ), - 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, + SizedBox(height: 8.h), + Row( + children: [ + Expanded( + flex: 6, + child: CustomButton( + text: model.patientPrescriptionOrders[index].isHomeMedicineDeliverySupported! + ? LocaleKeys.resendOrder.tr(context: context) + : LocaleKeys.prescriptionDeliveryError.tr(context: context), + onPressed: () async { + if (model.patientPrescriptionOrders[index].isHomeMedicineDeliverySupported!) { + LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingPrescriptionDetails.tr(context: context)); + await prescriptionsViewModel.getPrescriptionDetails(prescriptionsViewModel.patientPrescriptionOrders[index], onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + prescriptionsViewModel.initiatePrescriptionDelivery(); + }); + } + }, + backgroundColor: model.patientPrescriptionOrders[index].isHomeMedicineDeliverySupported! + ? AppColors.successColor.withOpacity(0.15) + : AppColors.textColor.withOpacity(0.15), + borderColor: AppColors.successColor.withOpacity(0.01), + textColor: model.patientPrescriptionOrders[index].isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35), + fontSize: model.patientPrescriptionOrders[index].isHomeMedicineDeliverySupported! ? 14.f : 12.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + icon: AppAssets.prescription_refill_icon, + iconColor: model.patientPrescriptionOrders[index].isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35), + iconSize: 16.h, ), - ); - }, - child: isExpanded - ? Container( - key: ValueKey(index), - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 8.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ...model.patientPrescriptionOrdersViewList[index].prescriptionsList!.map((prescription) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisSize: MainAxisSize.min, - children: [ - Image.network( - prescription.doctorImageURL!, - width: 24.h, - height: 24.h, - fit: BoxFit.fill, - ).circle(100), - SizedBox(width: 8.h), - Expanded(child: prescription.doctorName!.toText14(weight: FontWeight.w500)), - ], - ), - SizedBox(height: 8.h), - Wrap( - direction: Axis.horizontal, - spacing: 6.h, - runSpacing: 6.h, - children: [ - Directionality( - textDirection: ui.TextDirection.ltr, - child: AppCustomChipWidget( - labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(prescription.appointmentDate), false), isEnglishOnly: true, - ), - ), - AppCustomChipWidget( - labelText: model.isSortByClinic ? prescription.name ?? "" : prescription.clinicDescription!, - ), - ], - ), - SizedBox(height: 8.h), - Row( - children: [ - Expanded( - flex: 6, - child: CustomButton( - text: prescription.isHomeMedicineDeliverySupported! - ? LocaleKeys.resendOrder.tr(context: context) - : LocaleKeys.prescriptionDeliveryError.tr(context: context), - onPressed: () async { - if (prescription.isHomeMedicineDeliverySupported!) { - LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingPrescriptionDetails.tr(context: context)); - await prescriptionsViewModel.getPrescriptionDetails(prescriptionsViewModel.patientPrescriptionOrders[index], - onSuccess: (val) { - LoaderBottomSheet.hideLoader(); - prescriptionsViewModel.initiatePrescriptionDelivery(); - }); - } - }, - backgroundColor: - prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor.withOpacity(0.15) : AppColors.greyF7Color, - borderColor: AppColors.successColor.withOpacity(0.01), - textColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35), - fontSize: prescription.isHomeMedicineDeliverySupported! ? 14.f : 12.f, - fontWeight: FontWeight.w500, - borderRadius: 12.r, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - icon: AppAssets.prescription_refill_icon, - iconColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35), - iconSize: 16.h, - ), - ), - SizedBox(width: 8.h), - 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.setPrescriptionsDetailsLoading(); - Navigator.of(context).push( - CustomPageRoute( - page: PrescriptionDetailPage( - prescriptionsResponseModel: prescription, - isFromAppointments: false, - ), - ), - ); - }), - ), - ], - ), - SizedBox(height: 12.h), - Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), - SizedBox(height: 12.h), - ], - ); - }).toList(), - ], + ), + SizedBox(width: 8.h), + 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.setPrescriptionsDetailsLoading(); + Navigator.of(context).push( + CustomPageRoute( + page: PrescriptionDetailPage( + prescriptionsResponseModel: model.patientPrescriptionOrders[index], + isFromAppointments: false, + ), ), - ) - : SizedBox.shrink(), + ); + }), + ), + ], ), + // SizedBox(height: 12.h), + // Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + // SizedBox(height: 12.h), ], ), + // Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // ...model.patientPrescriptionOrders.map((prescription) { + // return Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Row( + // mainAxisSize: MainAxisSize.min, + // children: [ + // Image.network( + // prescription.doctorImageURL!, + // width: 24.h, + // height: 24.h, + // fit: BoxFit.fill, + // ).circle(100), + // SizedBox(width: 8.h), + // Expanded(child: prescription.doctorName!.toText14(weight: FontWeight.w500)), + // ], + // ), + // SizedBox(height: 8.h), + // Wrap( + // direction: Axis.horizontal, + // spacing: 6.h, + // runSpacing: 6.h, + // children: [ + // Directionality( + // textDirection: ui.TextDirection.ltr, + // child: AppCustomChipWidget( + // labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(prescription.appointmentDate), false), isEnglishOnly: true, + // ), + // ), + // AppCustomChipWidget( + // labelText: model.isSortByClinic ? prescription.name ?? "" : prescription.clinicDescription!, + // ), + // ], + // ), + // SizedBox(height: 8.h), + // Row( + // children: [ + // Expanded( + // flex: 6, + // child: CustomButton( + // text: prescription.isHomeMedicineDeliverySupported! + // ? LocaleKeys.resendOrder.tr(context: context) + // : LocaleKeys.prescriptionDeliveryError.tr(context: context), + // onPressed: () async { + // if (prescription.isHomeMedicineDeliverySupported!) { + // LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingPrescriptionDetails.tr(context: context)); + // await prescriptionsViewModel.getPrescriptionDetails(prescriptionsViewModel.patientPrescriptionOrders[index], + // onSuccess: (val) { + // LoaderBottomSheet.hideLoader(); + // prescriptionsViewModel.initiatePrescriptionDelivery(); + // }); + // } + // }, + // backgroundColor: + // prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor.withOpacity(0.15) : AppColors.greyF7Color, + // borderColor: AppColors.successColor.withOpacity(0.01), + // textColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35), + // fontSize: prescription.isHomeMedicineDeliverySupported! ? 14.f : 12.f, + // fontWeight: FontWeight.w500, + // borderRadius: 12.r, + // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + // height: 40.h, + // icon: AppAssets.prescription_refill_icon, + // iconColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35), + // iconSize: 16.h, + // ), + // ), + // SizedBox(width: 8.h), + // 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.setPrescriptionsDetailsLoading(); + // Navigator.of(context).push( + // CustomPageRoute( + // page: PrescriptionDetailPage( + // prescriptionsResponseModel: prescription, + // isFromAppointments: false, + // ), + // ), + // ); + // }), + // ), + // ], + // ), + // SizedBox(height: 12.h), + // Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + // SizedBox(height: 12.h), + // ], + // ); + // }).toList(), + // ], + // ), ), + + // 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: [ + // CustomButton( + // text: "${model.patientPrescriptionOrdersViewList[index].prescriptionsList!.length} Prescriptions Available", + // 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: 30.h, + // ), + // Icon(isExpanded ? Icons.expand_less : Icons.expand_more), + // ], + // ), + // SizedBox(height: 8.h), + // (model.patientPrescriptionOrdersViewList[index].filterName ?? "").toText16(isBold: true) + // ], + // ), + // ), + // 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.h, vertical: 8.h), + // // child: Column( + // // crossAxisAlignment: CrossAxisAlignment.start, + // // children: [ + // // ...model.patientPrescriptionOrdersViewList[index].prescriptionsList!.map((prescription) { + // // return Column( + // // crossAxisAlignment: CrossAxisAlignment.start, + // // children: [ + // // Row( + // // mainAxisSize: MainAxisSize.min, + // // children: [ + // // Image.network( + // // prescription.doctorImageURL!, + // // width: 24.h, + // // height: 24.h, + // // fit: BoxFit.fill, + // // ).circle(100), + // // SizedBox(width: 8.h), + // // Expanded(child: prescription.doctorName!.toText14(weight: FontWeight.w500)), + // // ], + // // ), + // // SizedBox(height: 8.h), + // // Wrap( + // // direction: Axis.horizontal, + // // spacing: 6.h, + // // runSpacing: 6.h, + // // children: [ + // // Directionality( + // // textDirection: ui.TextDirection.ltr, + // // child: AppCustomChipWidget( + // // labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(prescription.appointmentDate), false), isEnglishOnly: true, + // // ), + // // ), + // // AppCustomChipWidget( + // // labelText: model.isSortByClinic ? prescription.name ?? "" : prescription.clinicDescription!, + // // ), + // // ], + // // ), + // // SizedBox(height: 8.h), + // // Row( + // // children: [ + // // Expanded( + // // flex: 6, + // // child: CustomButton( + // // text: prescription.isHomeMedicineDeliverySupported! + // // ? LocaleKeys.resendOrder.tr(context: context) + // // : LocaleKeys.prescriptionDeliveryError.tr(context: context), + // // onPressed: () async { + // // if (prescription.isHomeMedicineDeliverySupported!) { + // // LoaderBottomSheet.showLoader(loadingText: LocaleKeys.fetchingPrescriptionDetails.tr(context: context)); + // // await prescriptionsViewModel.getPrescriptionDetails(prescriptionsViewModel.patientPrescriptionOrders[index], + // // onSuccess: (val) { + // // LoaderBottomSheet.hideLoader(); + // // prescriptionsViewModel.initiatePrescriptionDelivery(); + // // }); + // // } + // // }, + // // backgroundColor: + // // prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor.withOpacity(0.15) : AppColors.greyF7Color, + // // borderColor: AppColors.successColor.withOpacity(0.01), + // // textColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35), + // // fontSize: prescription.isHomeMedicineDeliverySupported! ? 14.f : 12.f, + // // fontWeight: FontWeight.w500, + // // borderRadius: 12.r, + // // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + // // height: 40.h, + // // icon: AppAssets.prescription_refill_icon, + // // iconColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35), + // // iconSize: 16.h, + // // ), + // // ), + // // SizedBox(width: 8.h), + // // 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.setPrescriptionsDetailsLoading(); + // // Navigator.of(context).push( + // // CustomPageRoute( + // // page: PrescriptionDetailPage( + // // prescriptionsResponseModel: prescription, + // // isFromAppointments: false, + // // ), + // // ), + // // ); + // // }), + // // ), + // // ], + // // ), + // // SizedBox(height: 12.h), + // // Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + // // SizedBox(height: 12.h), + // // ], + // // ); + // // }).toList(), + // // ], + // // ), + // // ) + // // : SizedBox.shrink(), + // ), + // ], + // ), + // ), ), ), ), diff --git a/lib/presentation/profile_settings/profile_settings.dart b/lib/presentation/profile_settings/profile_settings.dart index 50b8eb07..1a10e0de 100644 --- a/lib/presentation/profile_settings/profile_settings.dart +++ b/lib/presentation/profile_settings/profile_settings.dart @@ -53,6 +53,7 @@ class ProfileSettingsState extends State { scheduleMicrotask(() { insuranceViewModel.initInsuranceProvider(); }); + _loadPermissions(); super.initState(); } @@ -92,6 +93,7 @@ class ProfileSettingsState extends State { final SwiperController _controller = SwiperController(); late InsuranceViewModel insuranceViewModel; late ContactUsViewModel contactUsViewModel; + String _permissionsLabel = ""; @override Widget build(BuildContext context) { @@ -294,6 +296,9 @@ class ProfileSettingsState extends State { launchUrl(Uri.parse("tel://" + "+966 92 006 6666")); }, trailingLabel: "92 006 6666"), 1.divider, + actionItem(AppAssets.permission, LocaleKeys.permissionsProfile.tr(context: context), () { + openAppSettings(); + }, trailingLabel: getCurrentPermissions()), actionItem(AppAssets.feedbackFill, LocaleKeys.feedback.tr(context: context), () { contactUsViewModel.setSelectedFeedbackType( FeedbackType(id: 5, nameEN: "Not classified", nameAR: 'غير محدد'), @@ -349,6 +354,34 @@ class ProfileSettingsState extends State { ); } + Future _loadPermissions() async { + final Map permissionMap = { + 'Camera': Permission.camera, + 'Microphone': Permission.microphone, + 'Location': Permission.location, + 'Notifications': Permission.notification, + 'Calendar': Permission.calendarFullAccess, + }; + + final List granted = []; + + for (final entry in permissionMap.entries) { + if (await entry.value.isGranted) { + granted.add(entry.key); + } + } + + if (mounted) { + setState(() { + _permissionsLabel = granted.isEmpty ? 'No permissions granted' : granted.join(', '); + }); + } + } + + String getCurrentPermissions() { + return _permissionsLabel; + } + Widget actionItem(String icon, String label, VoidCallback onPress, {String trailingLabel = "", bool? switchValue, ValueChanged? onSwitchChanged, bool isExternalLink = false}) { return SizedBox( height: 56.h, diff --git a/lib/presentation/radiology/radiology_orders_page.dart b/lib/presentation/radiology/radiology_orders_page.dart index 81aef5c7..e24c3472 100644 --- a/lib/presentation/radiology/radiology_orders_page.dart +++ b/lib/presentation/radiology/radiology_orders_page.dart @@ -3,6 +3,8 @@ 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/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; @@ -96,40 +98,40 @@ class _RadiologyOrdersPageState extends State { children: [ // Clinic / Hospital toggle SizedBox(height: 16.h), - 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), + // 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 ? AppCustomChipWidget( padding: EdgeInsets.symmetric(horizontal: 5.h), @@ -171,198 +173,521 @@ class _RadiologyOrdersPageState extends State { return Utils.getNoDataWidget(ctx, noDataText: LocaleKeys.youDontHaveRadiologyOrders.tr(context: context)); } - return ListView.builder( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - padding: EdgeInsets.zero, - itemCount: model.patientRadiologyOrdersViewList.length, - itemBuilder: (context, index) { - final group = model.patientRadiologyOrdersViewList[index]; - final displayName = model.isSortByClinic ? (group.first.clinicDescription ?? 'Unknown') : (group.first.projectName ?? 'Unknown'); - final isExpanded = expandedIndex == index; - return AnimationConfiguration.staggeredList( + // return ListView.builder( + // shrinkWrap: true, + // physics: NeverScrollableScrollPhysics(), + // padding: EdgeInsets.zero, + // itemCount: model.patientRadiologyOrdersViewList.length, + // itemBuilder: (context, index) { + // final group = model.patientRadiologyOrdersViewList[index]; + // final displayName = model.isSortByClinic ? (group.first.clinicDescription ?? 'Unknown') : (group.first.projectName ?? 'Unknown'); + // final isExpanded = expandedIndex == index; + // return AnimationConfiguration.staggeredList( + // position: index, + // duration: const Duration(milliseconds: 400), + // child: SlideAnimation( + // verticalOffset: 50.0, + // child: FadeInAnimation( + // child: AnimatedContainer( + // duration: const 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; + // }); + // WidgetsBinding.instance.addPostFrameCallback((_) { + // final key = _groupKeys.putIfAbsent(index, () => GlobalKey()); + // if (key.currentContext != null && expandedIndex == index) { + // Future.delayed(const Duration(milliseconds: 450), () { + // if (key.currentContext != null) { + // Scrollable.ensureVisible( + // key.currentContext!, + // duration: const Duration(milliseconds: 350), + // curve: Curves.easeInOut, + // alignment: 0.0, + // ); + // } + // }); + // } + // }); + // }, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Padding( + // key: _groupKeys.putIfAbsent(index, () => GlobalKey()), + // 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( + // displayName, + // style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), + // overflow: TextOverflow.ellipsis, + // ), + // ], + // ), + // ), + // AnimatedSwitcher( + // duration: const 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), + // 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 ?? '').toString().toText14(weight: FontWeight.w500), + // ), + // ], + // ), + // SizedBox(height: 8.h), + // Wrap( + // direction: Axis.horizontal, + // spacing: 4.h, + // runSpacing: 4.h, + // children: [ + // if ((order.description ?? '').isNotEmpty) + // AppCustomChipWidget( + // labelText: (order.description ?? '').toString(), + // ), + // Directionality( + // textDirection: ui.TextDirection.ltr, + // child: AppCustomChipWidget( + // labelText: DateUtil.formatDateToDate( + // (order.orderDate ?? order.appointmentDate), + // false, + // ), isEnglishOnly: true, + // ), + // ), + // AppCustomChipWidget( + // labelText: model.isSortByClinic ? (order.projectName ?? '') : (order.clinicDescription ?? ''), + // ), + // ], + // ), + // SizedBox(height: 12.h), + // Row( + // children: [ + // Expanded(flex: 2, child: const SizedBox()), + // Expanded( + // flex: 2, + // child: CustomButton( + // icon: AppAssets.view_report_icon, + // iconColor: AppColors.primaryRedColor, + // iconSize: 16.h, + // text: LocaleKeys.viewResults.tr(context: context), + // onPressed: () { + // model.navigationService.push( + // CustomPageRoute( + // page: RadiologyResultPage(patientRadiologyResponseModel: order), + // ), + // ); + // }, + // backgroundColor: AppColors.secondaryLightRedColor, + // borderColor: AppColors.secondaryLightRedColor, + // textColor: AppColors.primaryRedColor, + // fontSize: 14, + // fontWeight: FontWeight.w500, + // borderRadius: 12, + // padding: const 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), + // ], + // ); + // }).toList(), + // ], + // ), + // ) + // : const SizedBox.shrink(), + // ), + // ], + // ), + // ), + // ), + // ), + // ), + // ); + // }, + // ); + + return ListView.builder( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.zero, + itemCount: model.patientRadiologyOrders.length, + itemBuilder: (context, index) { + final group = model.patientRadiologyOrders[index]; + final isExpanded = expandedIndex == index; + return AnimationConfiguration.staggeredList( position: index, - duration: const Duration(milliseconds: 400), + duration: const Duration(milliseconds: 500), child: SlideAnimation( - verticalOffset: 50.0, + verticalOffset: 100.0, child: FadeInAnimation( child: AnimatedContainer( - duration: const Duration(milliseconds: 300), + duration: Duration(milliseconds: 300), curve: Curves.easeInOut, margin: EdgeInsets.symmetric(vertical: 8.h), - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.h, - hasShadow: true, - ), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true), child: InkWell( onTap: () { setState(() { expandedIndex = isExpanded ? null : index; }); - WidgetsBinding.instance.addPostFrameCallback((_) { - final key = _groupKeys.putIfAbsent(index, () => GlobalKey()); - if (key.currentContext != null && expandedIndex == index) { - Future.delayed(const Duration(milliseconds: 450), () { - if (key.currentContext != null) { - Scrollable.ensureVisible( - key.currentContext!, - duration: const Duration(milliseconds: 350), - curve: Curves.easeInOut, - alignment: 0.0, - ); - } - }); - } - }); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - key: _groupKeys.putIfAbsent(index, () => GlobalKey()), padding: EdgeInsets.all(16.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + AppCustomChipWidget( + labelText: "${getIt.get().isArabic() ? group.isInOutPatientDescriptionN : group.isInOutPatientDescription}", + backgroundColor: group.isInOutPatient! ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.warningColorYellow.withOpacity(0.1), + textColor: group.isInOutPatient! ? AppColors.primaryRedColor : AppColors.warningColorYellow, + ), + SizedBox(height: 16.h), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, children: [ - AppCustomChipWidget(labelText: "${group.length} ${LocaleKeys.results.tr(context: context)}"), - Icon(isExpanded ? Icons.expand_less : Icons.expand_more), + Image.network( + group.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: (group.doctorName ?? "").toString().toText14(weight: FontWeight.w500)), ], ), SizedBox(height: 8.h), - Text( - displayName, - style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), - overflow: TextOverflow.ellipsis, + Wrap( + direction: Axis.horizontal, + spacing: 4.h, + runSpacing: 4.h, + children: [ + Directionality( + textDirection: ui.TextDirection.ltr, + child: AppCustomChipWidget( + labelText: DateUtil.formatDateToDate(group.orderDate!, false), + isEnglishOnly: true, + )), + AppCustomChipWidget( + labelText: (group.projectName ?? ""), + ), + AppCustomChipWidget( + labelText: (group.clinicDescription ?? ""), + ), + ], ), + SizedBox(height: 16.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "• ${group.procedureName.toString().trim() ?? ""}".toText14(weight: FontWeight.w500), + // "Lorem ipsum text".toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), + SizedBox(height: 16.h), + CustomButton( + text: LocaleKeys.viewReport.tr(), + onPressed: () { + model.navigationService.push( + CustomPageRoute( + page: RadiologyResultPage(patientRadiologyResponseModel: group), + ), + ); + }, + backgroundColor: AppColors.infoColor.withAlpha(20), + borderColor: AppColors.infoColor.withAlpha(0), + textColor: AppColors.infoColor, + fontSize: (isFoldable || isTablet) ? 12.f : 14.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), + height: 40.h, + iconSize: 14.h, + icon: AppAssets.view_report_icon, + iconColor: AppColors.infoColor, + ), + ], + ) ], ), ), - AnimatedSwitcher( - duration: const 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), - 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 ?? '').toString().toText14(weight: FontWeight.w500), - ), - ], - ), - SizedBox(height: 8.h), - Wrap( - direction: Axis.horizontal, - spacing: 4.h, - runSpacing: 4.h, - children: [ - if ((order.description ?? '').isNotEmpty) - AppCustomChipWidget( - labelText: (order.description ?? '').toString(), - ), - Directionality( - textDirection: ui.TextDirection.ltr, - child: AppCustomChipWidget( - labelText: DateUtil.formatDateToDate( - (order.orderDate ?? order.appointmentDate), - false, - ), isEnglishOnly: true, - ), - ), - AppCustomChipWidget( - labelText: model.isSortByClinic ? (order.projectName ?? '') : (order.clinicDescription ?? ''), - ), - ], - ), - SizedBox(height: 12.h), - Row( - children: [ - Expanded(flex: 2, child: const SizedBox()), - Expanded( - flex: 2, - child: CustomButton( - icon: AppAssets.view_report_icon, - iconColor: AppColors.primaryRedColor, - iconSize: 16.h, - text: LocaleKeys.viewResults.tr(context: context), - onPressed: () { - model.navigationService.push( - CustomPageRoute( - page: RadiologyResultPage(patientRadiologyResponseModel: order), - ), - ); - }, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 14, - fontWeight: FontWeight.w500, - borderRadius: 12, - padding: const 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), - ], - ); - }).toList(), - ], - ), - ) - : const SizedBox.shrink(), - ), + // 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( + // children: [ + // ListView.separated( + // shrinkWrap: true, + // physics: NeverScrollableScrollPhysics(), + // padding: EdgeInsets.zero, + // itemBuilder: (cxt, index) { + // PatientRadiologyResponseModel order = group; + // return Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // "• ${order.procedureName ?? ""}".toText14(weight: FontWeight.w500), + // "Lorem ipsum text".toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), + // // SizedBox(height: 4.h), + // // order.testDetails![index].testDescriptionEn!.toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), + // // 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!}"), isEnglishOnly: true, + // // ), + // // Directionality( + // // textDirection: ui.TextDirection.ltr, + // // child: AppCustomChipWidget( + // // labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), + // // isEnglishOnly: true, + // // )), + // // AppCustomChipWidget( + // // labelText: labViewModel.isSortByClinic ? (order.projectName ?? "") : (order.clinicDescription ?? ""), + // // ), + // // ], + // // ), + // // // 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: () { + // // labViewModel.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), + // ], + // ).paddingOnly(top: 16, bottom: 16); + // }, + // separatorBuilder: (cxt, index) => Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + // itemCount: 1), + // SizedBox(height: 16.h), + // CustomButton( + // text: LocaleKeys.viewReport.tr(), + // onPressed: () { + // model.navigationService.push( + // CustomPageRoute( + // page: RadiologyResultPage(patientRadiologyResponseModel: group), + // ), + // ); + // }, + // backgroundColor: AppColors.infoColor.withAlpha(20), + // borderColor: AppColors.infoColor.withAlpha(0), + // textColor: AppColors.infoColor, + // fontSize: (isFoldable || isTablet) ? 12.f : 14.f, + // fontWeight: FontWeight.w500, + // borderRadius: 12.r, + // padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), + // height: 40.h, + // iconSize: 14.h, + // icon: AppAssets.view_report_icon, + // iconColor: AppColors.infoColor, + // ), + // SizedBox(height: 16.h), + // ], + // ), + // ) + // : SizedBox.shrink(), + // ), ], ), ), ), ), - ), - ); - }, - ); - }), - ], - ), - ); - }, - ), + )); + }, + ); + }), + ], + ), + ); + }, ), ), + ), ); } diff --git a/lib/presentation/radiology/radiology_result_page.dart b/lib/presentation/radiology/radiology_result_page.dart index 02f30be5..05f23530 100644 --- a/lib/presentation/radiology/radiology_result_page.dart +++ b/lib/presentation/radiology/radiology_result_page.dart @@ -53,14 +53,48 @@ class _RadiologyResultPageState extends State { Expanded( child: CollapsingListView( title: LocaleKeys.radiologyResult.tr(context: context), - viewImage: () { - if (radiologyViewModel.radiologyImageURL.isNotEmpty) { - Uri uri = Uri.parse(radiologyViewModel.radiologyImageURL); - launchUrl(uri, mode: LaunchMode.platformDefault, webOnlyWindowName: ""); - } else { - Utils.showToast("Radiology image not available"); - } + downloadReport: () async { + LoaderBottomSheet.showLoader(); + await radiologyViewModel + .getRadiologyPDF( + patientRadiologyResponseModel: widget.patientRadiologyResponseModel, + authenticatedUser: _appState.getAuthenticatedUser()!, + onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: err), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }) + .then((val) async { + LoaderBottomSheet.hideLoader(); + if (radiologyViewModel.patientRadiologyReportPDFBase64.isNotEmpty) { + String path = await Utils.createFileFromString(radiologyViewModel.patientRadiologyReportPDFBase64, "pdf"); + try { + OpenFilex.open(path); + } catch (ex) { + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: "Cannot open file"), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + } + } + }); }, + // viewImage: () { + // if (radiologyViewModel.radiologyImageURL.isNotEmpty) { + // Uri uri = Uri.parse(radiologyViewModel.radiologyImageURL); + // launchUrl(uri, mode: LaunchMode.platformDefault, webOnlyWindowName: ""); + // } else { + // Utils.showToast("Radiology image not available"); + // } + // }, child: SingleChildScrollView( child: Padding( padding: EdgeInsets.symmetric(horizontal: 24.h), @@ -124,54 +158,28 @@ class _RadiologyResultPageState extends State { borderRadius: 24.h, hasShadow: true, ), - child: CustomButton( - text: LocaleKeys.downloadReport.tr(context: context), + child: widget.patientRadiologyResponseModel.dIAPACSURL != "" ? CustomButton( + text: LocaleKeys.openRad.tr(context: context), onPressed: () async { - LoaderBottomSheet.showLoader(); - await radiologyViewModel - .getRadiologyPDF( - patientRadiologyResponseModel: widget.patientRadiologyResponseModel, - authenticatedUser: _appState.getAuthenticatedUser()!, - onError: (err) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - context, - child: Utils.getErrorWidget(loadingText: err), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }) - .then((val) async { - LoaderBottomSheet.hideLoader(); - if (radiologyViewModel.patientRadiologyReportPDFBase64.isNotEmpty) { - String path = await Utils.createFileFromString(radiologyViewModel.patientRadiologyReportPDFBase64, "pdf"); - try { - OpenFilex.open(path); - } catch (ex) { - showCommonBottomSheetWithoutHeight( - context, - child: Utils.getErrorWidget(loadingText: "Cannot open file"), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - } - } - }); + if (radiologyViewModel.radiologyImageURL.isNotEmpty) { + Uri uri = Uri.parse(radiologyViewModel.radiologyImageURL); + launchUrl(uri, mode: LaunchMode.platformDefault, webOnlyWindowName: ""); + } else { + Utils.showToast("Radiology image not available"); + } }, - backgroundColor: AppColors.successColor, - borderColor: AppColors.successColor, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, textColor: Colors.white, fontSize: 16, fontWeight: FontWeight.w500, borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 45.h, - icon: AppAssets.download, + icon: AppAssets.imageIcon, iconColor: Colors.white, iconSize: 20.h, - ).paddingSymmetrical(24.h, 24.h), + ).paddingSymmetrical(24.h, 24.h) : SizedBox.shrink(), ), ], ), diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index b933e530..4c754b65 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -27,6 +27,7 @@ class CollapsingListView extends StatelessWidget { VoidCallback? doctorResponse; VoidCallback? downloadReport; VoidCallback? viewImage; + VoidCallback? location; Widget? bottomChild; Widget? trailing; bool isClose; @@ -51,6 +52,7 @@ class CollapsingListView extends StatelessWidget { this.doctorResponse, this.downloadReport, this.viewImage, + this.location, this.isLeading = true, this.trailing, this.leadingCallback, @@ -95,6 +97,7 @@ class CollapsingListView extends StatelessWidget { doctorResponse: doctorResponse, downloadReport: downloadReport, viewImage: viewImage, + location: location, bottomChild: bottomChild, trailing: trailing, aiOverview: aiOverview, @@ -208,6 +211,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget VoidCallback? doctorResponse; VoidCallback? downloadReport; VoidCallback? viewImage; + VoidCallback? location; Widget? bottomChild; Widget? trailing; @@ -227,6 +231,7 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget this.doctorResponse, this.downloadReport, this.viewImage, + this.location, this.bottomChild, this.trailing, }); @@ -307,6 +312,7 @@ class _ScrollAnimatedTitleState extends State { if (widget.aiOverview != null) actionButton(context, t, title: LocaleKeys.aiOverView.tr(context: context), icon: AppAssets.aiOverView, isAiButton: true).onPress(widget.aiOverview!), if (widget.downloadReport != null) actionButton(context, t, title: LocaleKeys.downloadReport.tr(context: context), icon: AppAssets.download).onPress(widget.downloadReport!), if (widget.viewImage != null) actionButton(context, t, title: LocaleKeys.viewRadiologyImage.tr(context: context), icon: AppAssets.download).onPress(widget.viewImage!), + if (widget.location != null) actionButton(context, t, title: LocaleKeys.sortByLocation.tr(context: context), icon: AppAssets.location).onPress(widget.location!), if (widget.trailing != null) widget.trailing!, ] ], diff --git a/lib/widgets/common_bottom_sheet.dart b/lib/widgets/common_bottom_sheet.dart index 5269a8dc..bc52c0cc 100644 --- a/lib/widgets/common_bottom_sheet.dart +++ b/lib/widgets/common_bottom_sheet.dart @@ -2,6 +2,7 @@ import 'dart:io' show Platform; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:get_it/get_it.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/utils/calender_utils_new.dart'; @@ -10,6 +11,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/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_reminder_view.dart'; +import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/services/permission_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:permission_handler/permission_handler.dart'; @@ -22,19 +24,66 @@ class BottomSheetUtils { _showReminderBottomSheet(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); } else { - // Utils.showPermissionConsentDialog(context, TranslationBase.of(context).calendarPermission, () async { - // if (await Permission.calendarFullAccess.request().isGranted) { - // _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, - // onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); - // } - // }); + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.notice.tr(context: GetIt.instance().navigatorKey.currentContext!), + GetIt.instance().navigatorKey.currentContext!, + child: Utils.getWarningWidget( + loadingText: LocaleKeys.calendarPermissionAlert.tr(), + isShowActionButtons: true, + onCancelTap: () { + GetIt.instance().pop(); + }, + onConfirmTap: () async { + GetIt.instance().pop(); + openAppSettings(); + }), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); } } else { if (await Permission.calendarWriteOnly.request().isGranted) { if (await Permission.calendarFullAccess.request().isGranted) { _showReminderBottomSheet(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted, onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed); + } else { + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.notice.tr(context: GetIt.instance().navigatorKey.currentContext!), + GetIt.instance().navigatorKey.currentContext!, + child: Utils.getWarningWidget( + loadingText: LocaleKeys.calendarPermissionAlert.tr(), + isShowActionButtons: true, + onCancelTap: () { + GetIt.instance().pop(); + }, + onConfirmTap: () async { + GetIt.instance().pop(); + openAppSettings(); + }), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); } + } else { + showCommonBottomSheetWithoutHeight( + title: LocaleKeys.notice.tr(context: GetIt.instance().navigatorKey.currentContext!), + GetIt.instance().navigatorKey.currentContext!, + child: Utils.getWarningWidget( + loadingText: LocaleKeys.calendarPermissionAlert.tr(), + isShowActionButtons: true, + onCancelTap: () { + GetIt.instance().pop(); + }, + onConfirmTap: () async { + GetIt.instance().pop(); + openAppSettings(); + }), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); } } } From fc217466835bae3e1be45939eded9b0d7ae59e9a Mon Sep 17 00:00:00 2001 From: tahaalam Date: Mon, 30 Mar 2026 15:24:20 +0300 Subject: [PATCH 14/17] graph values fix and comparision with the pdf --- lib/features/lab/lab_view_model.dart | 38 +++++++++++----- .../lab/lab_results/lab_result_details.dart | 44 ++++++++++--------- lib/widgets/graph/custom_graph.dart | 2 +- 3 files changed, 52 insertions(+), 32 deletions(-) diff --git a/lib/features/lab/lab_view_model.dart b/lib/features/lab/lab_view_model.dart index 07cbbde3..a787c6b6 100644 --- a/lib/features/lab/lab_view_model.dart +++ b/lib/features/lab/lab_view_model.dart @@ -377,7 +377,8 @@ class LabViewModel extends ChangeNotifier { LoaderBottomSheet.hideLoader(); if (apiResponse.messageStatus == 2) { } else if (apiResponse.messageStatus == 1) { - var recentThree = sort(apiResponse.data!); + var sortedResult = sort(apiResponse.data!); + var recentThree = sortedResult.take(3).toList(); mainLabResults = recentThree; double highRefrenceValue = double.negativeInfinity; @@ -385,11 +386,12 @@ class LabViewModel extends ChangeNotifier { double lowRefenceValue = double.infinity; String? flagForLowReferenceRange; - recentThree.reversed.forEach((element) { + sortedResult.take(3).toList().reversed.forEach((element) { try { var dateTime = DateUtil.convertStringToDate(element.verifiedOnDateTime!); var resultValue = double.parse(element.resultValue!); - var transformedValue = transformValueInRange(double.parse(element.resultValue!), element.calculatedResultFlag ?? ""); + // var transformedValue = transformValueInRange(double.parse(element.resultValue!), element.calculatedResultFlag ?? ""); + var transformedValue = resultValue; if (resultValue > maxY) { maxY = resultValue; maxX = maxY; @@ -421,9 +423,9 @@ class LabViewModel extends ChangeNotifier { highRefrenceValue = maxY; lowRefenceValue = minY; } - + // if (minY > lowRefenceValue) { - minY = lowRefenceValue - 25; + minY = lowRefenceValue - getInterval(); } this.flagForHighReferenceRange = flagForHighReferenceRange; @@ -432,12 +434,16 @@ class LabViewModel extends ChangeNotifier { lowTransformedReferenceValue = double.parse(transformValueInRange(lowRefenceValue, flagForLowReferenceRange ?? "").toStringAsFixed(1)); this.highRefrenceValue = double.parse(highRefrenceValue.toStringAsFixed(1)); this.lowRefenceValue = double.parse(lowRefenceValue.toStringAsFixed(1)); - - if (maxY < highRefrenceValue) { + if(maxY=1.0 && maxX < 5.0) return .3; + if(maxX >=5.0 && maxX < 10.0) return 1.5; + if(maxX >=10.0 && maxX < 50.0) return 2.5; + if(maxX >=50.0 && maxX < 100.0) return 5; + if(maxX >=100.0 && maxX < 200.0) return 10; + return 15; + } void checkIfGraphShouldBeDisplayed(LabResult recentResult) { shouldShowGraph = recentResult.checkIfGraphShouldBeDisplayed(); @@ -576,7 +593,8 @@ class LabViewModel extends ChangeNotifier { try { var dateTime = DateUtil.convertStringToDate(element.verifiedOnDateTime!); var resultValue = double.parse(element.resultValue!); - var transformedValue = transformValueInRange(double.parse(element.resultValue!), element.calculatedResultFlag ?? ""); + // var transformedValue = transformValueInRange(double.parse(element.resultValue!), element.calculatedResultFlag ?? ""); + var transformedValue = double.parse(element.resultValue!); if (resultValue > maxY) { maxY = resultValue; } diff --git a/lib/presentation/lab/lab_results/lab_result_details.dart b/lib/presentation/lab/lab_results/lab_result_details.dart index d2c1b524..d1ed1470 100644 --- a/lib/presentation/lab/lab_results/lab_result_details.dart +++ b/lib/presentation/lab/lab_results/lab_result_details.dart @@ -326,20 +326,20 @@ class LabResultDetails extends StatelessWidget { }, leftLabelFormatter: (value) { value = double.parse(value.toStringAsFixed(1)); - // return leftLabels(value.toStringAsFixed(2)); - if (value == labmodel.highRefrenceValue) { - return leftLabels(LocaleKeys.high.tr()); - } - - if (value == labmodel.lowRefenceValue) { - return leftLabels(LocaleKeys.low.tr()); - } + return leftLabels(value.toStringAsFixed(2)); + // if (value == labmodel.highRefrenceValue) { + // return leftLabels(LocaleKeys.high.tr()); + // } + // + // if (value == labmodel.lowRefenceValue) { + // return leftLabels(LocaleKeys.low.tr()); + // } return SizedBox.shrink(); // } }, - graphColor: AppColors.blackColor, - graphShadowColor: Colors.transparent, + graphColor: AppColors.graphGridColor, + graphShadowColor: AppColors.graphGridColor.withOpacity(.5), graphGridColor: graphColor.withOpacity(.4), bottomLabelFormatter: (value, data) { if (data.isEmpty) return SizedBox.shrink(); @@ -371,7 +371,7 @@ class LabResultDetails extends StatelessWidget { ranges.add(HorizontalRangeAnnotation( y1: model.minY, y2: model.lowRefenceValue, - color: AppColors.highAndLow.withOpacity(0.05), + color: Colors.transparent, )); ranges.add(HorizontalRangeAnnotation( @@ -383,7 +383,7 @@ class LabResultDetails extends StatelessWidget { ranges.add(HorizontalRangeAnnotation( y1: model.highRefrenceValue, y2: model.maxY, - color: AppColors.criticalLowAndHigh.withOpacity(0.05), + color: Colors.transparent, )); return ranges; } @@ -412,15 +412,17 @@ class LabResultDetails extends StatelessWidget { } double? getInterval(LabViewModel labmodel) { - return .1; - // var maxX = labmodel.maxY; - // if(maxX<1) return .5; - // if(maxX >1 && maxX < 5) return 1; - // if(maxX >5 && maxX < 10) return 5; - // if(maxX >10 && maxX < 50) return 10; - // if(maxX >50 && maxX < 100) return 20; - // if(maxX >100 && maxX < 200) return 30; - // return 50; + // return .1; + var maxX = labmodel.maxY; + if(maxX<1) return .3; + if(maxX >1 && maxX <= 5) return .7; + if(maxX >5 && maxX <= 10) return 2.5; + if(maxX >10 && maxX <= 50) return 5; + if(maxX >50 && maxX <= 100) return 10; + if(maxX >100 && maxX <= 200) return 30; + if(maxX >200 && maxX <= 300) return 50; + if(maxX >300 && maxX <= 400) return 100; + return 200 ; } Widget getLabDescription(BuildContext context) { diff --git a/lib/widgets/graph/custom_graph.dart b/lib/widgets/graph/custom_graph.dart index d9a69a99..3b0629f0 100644 --- a/lib/widgets/graph/custom_graph.dart +++ b/lib/widgets/graph/custom_graph.dart @@ -257,7 +257,7 @@ class CustomGraph extends StatelessWidget { isCurved: true, isStrokeCapRound: true, isStrokeJoinRound: true, - barWidth: 2, + barWidth: 3, gradient: LinearGradient( colors: [resolvedGraphColor, resolvedGraphColor], begin: Alignment.centerLeft, From 4dce062daff4899c7753457d56e8b7fc3925e4c4 Mon Sep 17 00:00:00 2001 From: tahaalam Date: Mon, 30 Mar 2026 15:31:02 +0300 Subject: [PATCH 15/17] Revert "graph values fix and comparision with the pdf" This reverts commit fc217466835bae3e1be45939eded9b0d7ae59e9a. --- lib/features/lab/lab_view_model.dart | 38 +++++----------- .../lab/lab_results/lab_result_details.dart | 44 +++++++++---------- lib/widgets/graph/custom_graph.dart | 2 +- 3 files changed, 32 insertions(+), 52 deletions(-) diff --git a/lib/features/lab/lab_view_model.dart b/lib/features/lab/lab_view_model.dart index a787c6b6..07cbbde3 100644 --- a/lib/features/lab/lab_view_model.dart +++ b/lib/features/lab/lab_view_model.dart @@ -377,8 +377,7 @@ class LabViewModel extends ChangeNotifier { LoaderBottomSheet.hideLoader(); if (apiResponse.messageStatus == 2) { } else if (apiResponse.messageStatus == 1) { - var sortedResult = sort(apiResponse.data!); - var recentThree = sortedResult.take(3).toList(); + var recentThree = sort(apiResponse.data!); mainLabResults = recentThree; double highRefrenceValue = double.negativeInfinity; @@ -386,12 +385,11 @@ class LabViewModel extends ChangeNotifier { double lowRefenceValue = double.infinity; String? flagForLowReferenceRange; - sortedResult.take(3).toList().reversed.forEach((element) { + recentThree.reversed.forEach((element) { try { var dateTime = DateUtil.convertStringToDate(element.verifiedOnDateTime!); var resultValue = double.parse(element.resultValue!); - // var transformedValue = transformValueInRange(double.parse(element.resultValue!), element.calculatedResultFlag ?? ""); - var transformedValue = resultValue; + var transformedValue = transformValueInRange(double.parse(element.resultValue!), element.calculatedResultFlag ?? ""); if (resultValue > maxY) { maxY = resultValue; maxX = maxY; @@ -423,9 +421,9 @@ class LabViewModel extends ChangeNotifier { highRefrenceValue = maxY; lowRefenceValue = minY; } - // + if (minY > lowRefenceValue) { - minY = lowRefenceValue - getInterval(); + minY = lowRefenceValue - 25; } this.flagForHighReferenceRange = flagForHighReferenceRange; @@ -434,16 +432,12 @@ class LabViewModel extends ChangeNotifier { lowTransformedReferenceValue = double.parse(transformValueInRange(lowRefenceValue, flagForLowReferenceRange ?? "").toStringAsFixed(1)); this.highRefrenceValue = double.parse(highRefrenceValue.toStringAsFixed(1)); this.lowRefenceValue = double.parse(lowRefenceValue.toStringAsFixed(1)); - if(maxY=1.0 && maxX < 5.0) return .3; - if(maxX >=5.0 && maxX < 10.0) return 1.5; - if(maxX >=10.0 && maxX < 50.0) return 2.5; - if(maxX >=50.0 && maxX < 100.0) return 5; - if(maxX >=100.0 && maxX < 200.0) return 10; - return 15; - } void checkIfGraphShouldBeDisplayed(LabResult recentResult) { shouldShowGraph = recentResult.checkIfGraphShouldBeDisplayed(); @@ -593,8 +576,7 @@ class LabViewModel extends ChangeNotifier { try { var dateTime = DateUtil.convertStringToDate(element.verifiedOnDateTime!); var resultValue = double.parse(element.resultValue!); - // var transformedValue = transformValueInRange(double.parse(element.resultValue!), element.calculatedResultFlag ?? ""); - var transformedValue = double.parse(element.resultValue!); + var transformedValue = transformValueInRange(double.parse(element.resultValue!), element.calculatedResultFlag ?? ""); if (resultValue > maxY) { maxY = resultValue; } diff --git a/lib/presentation/lab/lab_results/lab_result_details.dart b/lib/presentation/lab/lab_results/lab_result_details.dart index d1ed1470..d2c1b524 100644 --- a/lib/presentation/lab/lab_results/lab_result_details.dart +++ b/lib/presentation/lab/lab_results/lab_result_details.dart @@ -326,20 +326,20 @@ class LabResultDetails extends StatelessWidget { }, leftLabelFormatter: (value) { value = double.parse(value.toStringAsFixed(1)); - return leftLabels(value.toStringAsFixed(2)); - // if (value == labmodel.highRefrenceValue) { - // return leftLabels(LocaleKeys.high.tr()); - // } - // - // if (value == labmodel.lowRefenceValue) { - // return leftLabels(LocaleKeys.low.tr()); - // } + // return leftLabels(value.toStringAsFixed(2)); + if (value == labmodel.highRefrenceValue) { + return leftLabels(LocaleKeys.high.tr()); + } + + if (value == labmodel.lowRefenceValue) { + return leftLabels(LocaleKeys.low.tr()); + } return SizedBox.shrink(); // } }, - graphColor: AppColors.graphGridColor, - graphShadowColor: AppColors.graphGridColor.withOpacity(.5), + graphColor: AppColors.blackColor, + graphShadowColor: Colors.transparent, graphGridColor: graphColor.withOpacity(.4), bottomLabelFormatter: (value, data) { if (data.isEmpty) return SizedBox.shrink(); @@ -371,7 +371,7 @@ class LabResultDetails extends StatelessWidget { ranges.add(HorizontalRangeAnnotation( y1: model.minY, y2: model.lowRefenceValue, - color: Colors.transparent, + color: AppColors.highAndLow.withOpacity(0.05), )); ranges.add(HorizontalRangeAnnotation( @@ -383,7 +383,7 @@ class LabResultDetails extends StatelessWidget { ranges.add(HorizontalRangeAnnotation( y1: model.highRefrenceValue, y2: model.maxY, - color: Colors.transparent, + color: AppColors.criticalLowAndHigh.withOpacity(0.05), )); return ranges; } @@ -412,17 +412,15 @@ class LabResultDetails extends StatelessWidget { } double? getInterval(LabViewModel labmodel) { - // return .1; - var maxX = labmodel.maxY; - if(maxX<1) return .3; - if(maxX >1 && maxX <= 5) return .7; - if(maxX >5 && maxX <= 10) return 2.5; - if(maxX >10 && maxX <= 50) return 5; - if(maxX >50 && maxX <= 100) return 10; - if(maxX >100 && maxX <= 200) return 30; - if(maxX >200 && maxX <= 300) return 50; - if(maxX >300 && maxX <= 400) return 100; - return 200 ; + return .1; + // var maxX = labmodel.maxY; + // if(maxX<1) return .5; + // if(maxX >1 && maxX < 5) return 1; + // if(maxX >5 && maxX < 10) return 5; + // if(maxX >10 && maxX < 50) return 10; + // if(maxX >50 && maxX < 100) return 20; + // if(maxX >100 && maxX < 200) return 30; + // return 50; } Widget getLabDescription(BuildContext context) { diff --git a/lib/widgets/graph/custom_graph.dart b/lib/widgets/graph/custom_graph.dart index 3b0629f0..d9a69a99 100644 --- a/lib/widgets/graph/custom_graph.dart +++ b/lib/widgets/graph/custom_graph.dart @@ -257,7 +257,7 @@ class CustomGraph extends StatelessWidget { isCurved: true, isStrokeCapRound: true, isStrokeJoinRound: true, - barWidth: 3, + barWidth: 2, gradient: LinearGradient( colors: [resolvedGraphColor, resolvedGraphColor], begin: Alignment.centerLeft, From d4ed2b47bc178041306be41c5407daa19483e8aa Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 30 Mar 2026 17:01:45 +0300 Subject: [PATCH 16/17] updates --- .../contact_us/contact_us_view_model.dart | 24 +- .../my_invoices/my_invoices_view_model.dart | 3 + .../prescriptions_view_model.dart | 15 +- .../widgets/appointment_card.dart | 4 +- .../book_appointment_page.dart | 4 + lib/presentation/contact_us/find_us_page.dart | 51 +- .../contact_us/widgets/find_us_item_card.dart | 155 ++++-- .../insurance_approval_details_page.dart | 4 +- .../insurance/insurance_approvals_page.dart | 2 +- .../widgets/insurance_approval_card.dart | 37 +- lib/presentation/lab/lab_orders_page.dart | 2 +- .../patient_sickleaves_list_page.dart | 513 ++++++++++++------ .../my_invoices/my_invoices_details_page.dart | 112 ++-- .../my_invoices/my_invoices_list.dart | 2 +- .../widgets/invoice_list_card.dart | 4 +- .../prescription_detail_page.dart | 4 +- .../prescriptions/prescription_item_view.dart | 7 +- .../prescriptions_list_page.dart | 5 +- .../radiology/radiology_orders_page.dart | 6 +- 19 files changed, 636 insertions(+), 318 deletions(-) diff --git a/lib/features/contact_us/contact_us_view_model.dart b/lib/features/contact_us/contact_us_view_model.dart index dba89a51..34657a85 100644 --- a/lib/features/contact_us/contact_us_view_model.dart +++ b/lib/features/contact_us/contact_us_view_model.dart @@ -144,18 +144,7 @@ class ContactUsViewModel extends ChangeNotifier { } } - if (hmgHospitalsLocationsList.first.distanceInKilometers != 0) { - hmgHospitalsLocationsList.sort((a, b) => a.distanceInKilometers.compareTo(b.distanceInKilometers)); - } else { - hmgHospitalsLocationsList.sort((a, b) => a.locationName!.compareTo(b.locationName!)); - } - - if (hmgPharmacyLocationsList.first.distanceInKilometers != 0) { - hmgPharmacyLocationsList.sort((a, b) => a.distanceInKilometers.compareTo(b.distanceInKilometers)); - } else { - hmgPharmacyLocationsList.sort((a, b) => a.locationName!.compareTo(b.locationName!)); - } - + sortHMGLocations(hasLocationEnabled); isHMGLocationsListLoading = false; notifyListeners(); if (onSuccess != null) { @@ -166,6 +155,17 @@ class ContactUsViewModel extends ChangeNotifier { ); } + sortHMGLocations(bool isByLocation) { + if (isByLocation) { + hmgHospitalsLocationsList.sort((a, b) => a.distanceInKilometers.compareTo(b.distanceInKilometers)); + hmgPharmacyLocationsList.sort((a, b) => a.distanceInKilometers.compareTo(b.distanceInKilometers)); + } else { + hmgHospitalsLocationsList.sort((a, b) => a.locationName!.compareTo(b.locationName!)); + hmgPharmacyLocationsList.sort((a, b) => a.locationName!.compareTo(b.locationName!)); + } + notifyListeners(); + } + Future getLiveChatProjectsList({Function(dynamic)? onSuccess, Function(String)? onError}) async { isLiveChatProjectsListLoading = true; liveChatProjectsList.clear(); diff --git a/lib/features/my_invoices/my_invoices_view_model.dart b/lib/features/my_invoices/my_invoices_view_model.dart index 20d7869f..f3c716ae 100644 --- a/lib/features/my_invoices/my_invoices_view_model.dart +++ b/lib/features/my_invoices/my_invoices_view_model.dart @@ -60,6 +60,9 @@ class MyInvoicesViewModel extends ChangeNotifier { (failure) async { isInvoiceDetailsLoading = false; notifyListeners(); + if (onError != null) { + onError(failure.message); + } }, (apiResponse) { if (apiResponse.messageStatus == 2) { diff --git a/lib/features/prescriptions/prescriptions_view_model.dart b/lib/features/prescriptions/prescriptions_view_model.dart index 1fd8a000..4baf6882 100644 --- a/lib/features/prescriptions/prescriptions_view_model.dart +++ b/lib/features/prescriptions/prescriptions_view_model.dart @@ -19,6 +19,7 @@ import 'package:hmg_patient_app_new/services/error_handler_service.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/widgets/map/map_utility_screen.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; +import 'package:permission_handler/permission_handler.dart'; class PrescriptionsViewModel extends ChangeNotifier { bool isPrescriptionsOrdersLoading = false; @@ -68,9 +69,9 @@ class PrescriptionsViewModel extends ChangeNotifier { notifyListeners(); } - - checkIfReminderExistForPrescription(int index) async { + Future checkIfReminderExistForPrescription(int index) async { prescriptionDetailsList[index].hasReminder = await CalenderUtilsNew.instance.checkIfEventExist(prescriptionDetailsList[index].itemID?.toString() ?? ""); + return prescriptionDetailsList[index].hasReminder ?? false; } setPrescriptionsDetailsLoading() { @@ -157,14 +158,16 @@ class PrescriptionsViewModel extends ChangeNotifier { (failure) async { onError!(failure.message); }, - (apiResponse) { + (apiResponse) async { if (apiResponse.messageStatus == 2) { // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); } else if (apiResponse.messageStatus == 1) { prescriptionDetailsList = apiResponse.data!; - prescriptionDetailsList.forEach((element) async { - // await checkIfReminderExistForPrescription(prescriptionDetailsList.indexOf(element)); - }); + if (await Permission.calendarFullAccess.isGranted && await Permission.calendarWriteOnly.isGranted) { + prescriptionDetailsList.forEach((element) async { + await checkIfReminderExistForPrescription(prescriptionDetailsList.indexOf(element)); + }); + } isPrescriptionsDetailsLoading = false; notifyListeners(); if (onSuccess != null) { diff --git a/lib/presentation/appointments/widgets/appointment_card.dart b/lib/presentation/appointments/widgets/appointment_card.dart index 44fcfa86..52a1c219 100644 --- a/lib/presentation/appointments/widgets/appointment_card.dart +++ b/lib/presentation/appointments/widgets/appointment_card.dart @@ -104,8 +104,8 @@ class AppointmentCard extends StatelessWidget { AppCustomChipWidget( labelText: isLoading ? 'OutPatient' : (appState.isArabic() ? patientAppointmentHistoryResponseModel.isInOutPatientDescriptionN! : patientAppointmentHistoryResponseModel.isInOutPatientDescription!), - backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1), - textColor: AppColors.primaryRedColor, + backgroundColor: AppColors.warningColorYellow.withValues(alpha: 0.1), + textColor: AppColors.warningColorYellow, ).toShimmer2(isShow: isLoading), AppCustomChipWidget( labelText: isLoading ? 'Booked' : AppointmentType.getAppointmentStatusType(patientAppointmentHistoryResponseModel.patientStatusType!), diff --git a/lib/presentation/book_appointment/book_appointment_page.dart b/lib/presentation/book_appointment/book_appointment_page.dart index aea34ff0..4a8ada6a 100644 --- a/lib/presentation/book_appointment/book_appointment_page.dart +++ b/lib/presentation/book_appointment/book_appointment_page.dart @@ -59,10 +59,14 @@ class _BookAppointmentPageState extends State { bookAppointmentsViewModel.initBookAppointmentViewModel(); bookAppointmentsViewModel.getLocation(); immediateLiveCareViewModel.initImmediateLiveCare(); + if (appState.isAuthenticated) { + getIt.get().getPatientMyDoctors(); + } }); WidgetsBinding.instance.addPostFrameCallback((_) { if (bookAppointmentsViewModel.selectedTabIndex == 1) { if (appState.isAuthenticated) { + getIt.get().getPatientMyDoctors(); showUnKnownClinicBottomSheet(); } } else { diff --git a/lib/presentation/contact_us/find_us_page.dart b/lib/presentation/contact_us/find_us_page.dart index 7707754a..9091f74d 100644 --- a/lib/presentation/contact_us/find_us_page.dart +++ b/lib/presentation/contact_us/find_us_page.dart @@ -33,15 +33,6 @@ class FindUsPage extends StatelessWidget { backgroundColor: AppColors.bgScaffoldColor, body: CollapsingListView( title: LocaleKeys.location.tr(), - location: contactUsViewModel.hasLocationEnabled - ? null - : () { - locationUtils.getCurrentLocation( - onSuccess: (value) { - contactUsViewModel.initContactUsViewModel(); - }, - onFailure: () {},); - }, child: Consumer(builder: (context, contactUsVM, child) { return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -60,8 +51,48 @@ class FindUsPage extends StatelessWidget { contactUsVM.setHMGHospitalsListSelected(index == 0); }, ).paddingSymmetrical(24.h, 0.h), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.sortByLocation.tr(context: context).toText14(isBold: true), + SizedBox(height: 4.h), + "Sort the locations by nearest to your location".toText11(color: AppColors.textColorLight, weight: FontWeight.w500), + ], + ), + const Spacer(), + Switch( + activeThumbColor: AppColors.successColor, + activeTrackColor: AppColors.successColor.withValues(alpha: .15), + value: contactUsVM.hasLocationEnabled, + onChanged: (newValue) async { + if (newValue) { + locationUtils.getCurrentLocation( + onSuccess: (value) { + // if (contactUsVM.hmgHospitalsLocationsList.isNotEmpty) { + // contactUsVM.sortHMGLocations(true); + // contactUsVM.setHasLocationEnabled(newValue); + // } else { + contactUsVM.initContactUsViewModel(); + contactUsVM.setHasLocationEnabled(newValue); + contactUsVM.sortHMGLocations(true); + // } + }, + onFailure: () {}, + ); + } else { + contactUsVM.sortHMGLocations(false); + contactUsVM.setHasLocationEnabled(newValue); + } + // bookAppointmentsVM.setIsNearestAppointmentSelected(newValue); + }, + ), + ], + ).paddingSymmetrical(24.h, 12.h), ListView.separated( - padding: EdgeInsets.only(top: 16.h), + padding: EdgeInsets.only(top: 4.h), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: contactUsVM.isHMGLocationsListLoading diff --git a/lib/presentation/contact_us/widgets/find_us_item_card.dart b/lib/presentation/contact_us/widgets/find_us_item_card.dart index 063ea153..521775bc 100644 --- a/lib/presentation/contact_us/widgets/find_us_item_card.dart +++ b/lib/presentation/contact_us/widgets/find_us_item_card.dart @@ -6,24 +6,30 @@ import 'package:hmg_patient_app_new/core/app_assets.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/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/contact_us/contact_us_view_model.dart'; import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_hmg_locations.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/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:map_launcher/map_launcher.dart'; +import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; class FindUsItemCard extends StatelessWidget { FindUsItemCard({super.key, required this.getHMGLocationsModel}); late AppState appState; + late ContactUsViewModel contactUsViewModel; GetHMGLocationsModel getHMGLocationsModel; @override Widget build(BuildContext context) { appState = getIt.get(); + contactUsViewModel = getIt.get(); return DecoratedBox( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, @@ -45,73 +51,108 @@ class FindUsItemCard extends StatelessWidget { ); } - Widget get hospitalName => Row( + Widget get hospitalName => Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Image.network( - getHMGLocationsModel.projectImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", - width: 40.h, - height: 40.h, - fit: BoxFit.cover, - ).circle(100).toShimmer2(isShow: false).paddingOnly(right: 10), - Expanded( - child: Text( - getHMGLocationsModel.locationName!, - style: TextStyle( - fontWeight: FontWeight.w600, - fontSize: 16, - color: AppColors.blackColor, - ), - ), - ) + (getHMGLocationsModel.distanceInKilometers != 0 && contactUsViewModel.hasLocationEnabled) + ? Column( + children: [ + AppCustomChipWidget( + labelText: "${getHMGLocationsModel.distanceInKilometers ?? ""} km", + labelPadding: EdgeInsetsDirectional.only(start: -4.h, end: 8.w), + icon: AppAssets.location_red, + // iconColor: AppColors.primaryRedColor, + // backgroundColor: AppColors.secondaryLightRedColor, + // textColor: AppColors.errorColor, + ), + SizedBox( + height: 16.h, + ), + ], + ) + : SizedBox.shrink(), + Row( + children: [ + Image.network( + getHMGLocationsModel.projectImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + width: 40.h, + height: 40.h, + fit: BoxFit.cover, + ).circle(100).toShimmer2(isShow: false).paddingOnly(right: 10), + Expanded( + child: Text( + getHMGLocationsModel.locationName!, + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 16, + color: AppColors.blackColor, + ), + ), + ) + ], + ), ], ); Widget get distanceInfo => Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - getHMGLocationsModel.distanceInKilometers != 0 - ? AppCustomChipWidget( - labelText: "${getHMGLocationsModel.distanceInKilometers ?? ""} km", - icon: AppAssets.location_red, - iconColor: AppColors.primaryRedColor, - backgroundColor: AppColors.secondaryLightRedColor, - textColor: AppColors.errorColor, - ) - : SizedBox.shrink(), - Row( - children: [ - AppCustomChipWidget( - labelText: LocaleKeys.getDirections.tr(), - icon: AppAssets.directions_icon, - iconColor: AppColors.whiteColor, - backgroundColor: AppColors.textColor.withValues(alpha: 0.8), - textColor: AppColors.whiteColor, - onChipTap: () async { - await MapLauncher.showMarker( - mapType: MapType.google, + Expanded( + flex: 7, + child: CustomButton( + text: LocaleKeys.getDirections.tr(), + onPressed: () async { + await MapLauncher.showMarker( + mapType: MapType.google, + coords: Coords(double.parse(getHMGLocationsModel.latitude ?? "0.0"), double.parse(getHMGLocationsModel.longitude ?? "0.0")), + title: getHMGLocationsModel.locationName ?? "Hospital", + ).catchError((err) { + MapLauncher.showMarker( + mapType: Platform.isIOS ? MapType.apple : MapType.google, coords: Coords(double.parse(getHMGLocationsModel.latitude ?? "0.0"), double.parse(getHMGLocationsModel.longitude ?? "0.0")), title: getHMGLocationsModel.locationName ?? "Hospital", - ).catchError((err) { - MapLauncher.showMarker( - mapType: Platform.isIOS ? MapType.apple : MapType.google, - coords: Coords(double.parse(getHMGLocationsModel.latitude ?? "0.0"), double.parse(getHMGLocationsModel.longitude ?? "0.0")), - title: getHMGLocationsModel.locationName ?? "Hospital", - ); - }); - }, + ); + }); + }, + backgroundColor: AppColors.transparent, + borderColor: AppColors.textColor, + textColor: AppColors.blackColor, + borderWidth: 1.h, + fontSize: (isFoldable || isTablet) ? 12.f : 14.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + padding: EdgeInsets.symmetric(horizontal: 10.w), + height: 40.h, + icon: AppAssets.directions_icon, + iconColor: AppColors.blackColor, + iconSize: 16.h, + ), + ), + SizedBox(width: 8.w), + Expanded( + flex: 1, + child: Container( + height: (isFoldable || isTablet) ? 50.h : 40.h, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.transparent, + borderRadius: 10.h, + side: BorderSide( + color: AppColors.textColor, + width: 1.2, + ), ), - SizedBox(width: 4.w), - AppCustomChipWidget( - labelText: LocaleKeys.callNow.tr(), - icon: AppAssets.call_fill, - iconColor: Colors.white, - backgroundColor: AppColors.primaryRedColor.withValues(alpha: 1.0), - textColor: Colors.white, - onChipTap: () { - launchUrl(Uri.parse("tel://" + "${getHMGLocationsModel.phoneNumber}")); - }, + child: Transform.flip( + flipX: appState.isArabic(), + child: Utils.buildSvgWithAssets( + icon: AppAssets.call_fill, + iconColor: AppColors.textColor, + width: 5.w, + height: 5.h, + fit: BoxFit.scaleDown, + ), ), - ], + ).onPress(() { + launchUrl(Uri.parse("tel://" + "${getHMGLocationsModel.phoneNumber}")); + }), ), ], ); diff --git a/lib/presentation/insurance/insurance_approval_details_page.dart b/lib/presentation/insurance/insurance_approval_details_page.dart index a074a8d8..7a69e088 100644 --- a/lib/presentation/insurance/insurance_approval_details_page.dart +++ b/lib/presentation/insurance/insurance_approval_details_page.dart @@ -63,8 +63,8 @@ class InsuranceApprovalDetailsPage extends StatelessWidget { ), AppCustomChipWidget( labelText: appState.isArabic() ? insuranceApprovalResponseModel.isInOutPatientDescriptionN! : insuranceApprovalResponseModel.isInOutPatientDescription!, - backgroundColor: AppColors.primaryRedColor.withOpacity(0.1), - textColor: AppColors.primaryRedColor, + backgroundColor: AppColors.warningColorYellow.withOpacity(0.1), + textColor: AppColors.warningColorYellow, ), ], ), diff --git a/lib/presentation/insurance/insurance_approvals_page.dart b/lib/presentation/insurance/insurance_approvals_page.dart index 52f8b1f6..feac2e3a 100644 --- a/lib/presentation/insurance/insurance_approvals_page.dart +++ b/lib/presentation/insurance/insurance_approvals_page.dart @@ -51,7 +51,7 @@ class _InsuranceApprovalsPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ ListView.separated( - padding: EdgeInsets.only(top: 24.h), + padding: EdgeInsets.only(top: 12.h), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: insuranceVM.isInsuranceApprovalsLoading diff --git a/lib/presentation/insurance/widgets/insurance_approval_card.dart b/lib/presentation/insurance/widgets/insurance_approval_card.dart index 588f9887..8f5f7cfb 100644 --- a/lib/presentation/insurance/widgets/insurance_approval_card.dart +++ b/lib/presentation/insurance/widgets/insurance_approval_card.dart @@ -9,8 +9,11 @@ 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/insurance/models/resp_models/patient_insurance_approval_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/presentation/insurance/insurance_approval_details_page.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; +import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; class InsuranceApprovalCard extends StatelessWidget { InsuranceApprovalCard({super.key, required this.insuranceApprovalResponseModel, required this.isLoading, required this.appState}); @@ -64,8 +67,8 @@ class InsuranceApprovalCard extends StatelessWidget { : appState.isArabic() ? insuranceApprovalResponseModel.isInOutPatientDescriptionN! : insuranceApprovalResponseModel.isInOutPatientDescription!, - backgroundColor: AppColors.primaryRedColor.withOpacity(0.1), - textColor: AppColors.primaryRedColor, + backgroundColor: AppColors.warningColorYellow.withOpacity(0.1), + textColor: AppColors.warningColorYellow, ).toShimmer2(isShow: isLoading), ], ).toShimmer2(isShow: isLoading), @@ -111,12 +114,30 @@ class InsuranceApprovalCard extends StatelessWidget { ), ], ), - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Transform.flip( - flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon_small, width: 15.h, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor)), - ], + SizedBox( + height: 12.h, + ), + CustomButton( + text: LocaleKeys.viewDetails.tr(context: context), + onPressed: () async { + Navigator.of(context).push( + CustomPageRoute( + page: InsuranceApprovalDetailsPage(insuranceApprovalResponseModel: insuranceApprovalResponseModel), + ), + ); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: (isFoldable || isTablet) ? 12.f : 14.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + padding: EdgeInsets.symmetric(horizontal: 10.w), + height: isTablet || isFoldable ? 46.h : 40.h, + // height: 40.h, + // icon: AppAssets.insurance, + // iconColor: AppColors.primaryRedColor, + iconSize: 16.h, ).toShimmer2(isShow: isLoading), ], ), diff --git a/lib/presentation/lab/lab_orders_page.dart b/lib/presentation/lab/lab_orders_page.dart index bde9d90e..900477e4 100644 --- a/lib/presentation/lab/lab_orders_page.dart +++ b/lib/presentation/lab/lab_orders_page.dart @@ -1 +1 @@ -import 'dart:async'; import 'dart:convert'; 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/appbar/collapsing_list_view.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'; import 'dart:ui' as ui; 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 CollapsingListView( title: LocaleKeys.labResults.tr(context: context), search: () async { if (labProvider.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: labProvider.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; labProvider.filterLabReports(value); } } }, child: Consumer( builder: (context, labViewModel, child) { return SingleChildScrollView( physics: NeverScrollableScrollPhysics(), 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: () { // labViewModel.setIsSortByClinic(true); // }, // backgroundColor: labViewModel.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, // borderColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), // textColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, // fontSize: 12.f, // 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: () { // labViewModel.setIsSortByClinic(false); // }, // backgroundColor: labViewModel.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, // borderColor: labViewModel.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, // textColor: labViewModel.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 ? Column( children: [ AppCustomChipWidget( labelText: selectedFilterText!, backgroundColor: AppColors.alertColor, textColor: AppColors.whiteColor, deleteIcon: AppAssets.close_bottom_sheet_icon, deleteIconColor: AppColors.whiteColor, deleteIconHasColor: true, onDeleteTap: () { selectedFilterText = ""; labProvider.filterLabReports(""); }, ), SizedBox(height: 8.h), ], ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available labViewModel.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (labViewModel.patientLabOrders.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: labViewModel.patientLabOrders.length, itemBuilder: (context, index) { final group = labViewModel.patientLabOrders[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: [ Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ AppCustomChipWidget( labelText: "${group.testDetails!.length} ${LocaleKeys.tests.tr(context: context)}", backgroundColor: AppColors.successColor.withOpacity(0.1), textColor: AppColors.successColor, ), AppCustomChipWidget( labelText: "${_appState.isArabic() ? group.isInOutPatientDescriptionN : group.isInOutPatientDescription}", backgroundColor: group.isInOutPatient! ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.warningColorYellow.withOpacity(0.1), textColor: group.isInOutPatient! ? AppColors.primaryRedColor : AppColors.warningColorYellow, ) ], ), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), Row( mainAxisSize: MainAxisSize.min, children: [ Image.network( group.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: (group.doctorName ?? group.doctorNameEnglish ?? "").toString().toText14(weight: FontWeight.w500)), ], ), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ Directionality( textDirection: ui.TextDirection.ltr, child: AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(group.orderDate ?? ""), false), isEnglishOnly: true, )), AppCustomChipWidget( labelText: (group.projectName ?? ""), ), AppCustomChipWidget( labelText: (group.clinicDescription ?? ""), ), ], ), ], ), ), 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( children: [ ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemBuilder: (cxt, index) { PatientLabOrdersResponseModel order = group; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ "• ${order.testDetails![index].description!}".toText14(weight: FontWeight.w500), SizedBox(height: 4.h), order.testDetails![index].testDescriptionEn!.toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), // 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!}"), isEnglishOnly: true, // ), // Directionality( // textDirection: ui.TextDirection.ltr, // child: AppCustomChipWidget( // labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), // isEnglishOnly: true, // )), // AppCustomChipWidget( // labelText: labViewModel.isSortByClinic ? (order.projectName ?? "") : (order.clinicDescription ?? ""), // ), // ], // ), // // 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: () { // labViewModel.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), ], ).paddingOnly(top: 16, bottom: 16); }, separatorBuilder: (cxt, index) => Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), itemCount: group.testDetails!.length > 3 ? 3 : group.testDetails!.length), SizedBox(height: 16.h), CustomButton( text: "${LocaleKeys.viewResults.tr()} (${group.testDetails!.length})", onPressed: () { labProvider.currentlySelectedPatientOrder = group; labProvider.getPatientLabResultByHospital(group); labProvider.getPatientSpecialResult(group); Navigator.of(context).push( CustomPageRoute( page: LabResultByClinic(labOrder: group), ), ); }, backgroundColor: AppColors.infoColor.withAlpha(20), borderColor: AppColors.infoColor.withAlpha(0), textColor: AppColors.infoColor, fontSize: (isFoldable || isTablet) ? 12.f : 14.f, fontWeight: FontWeight.w500, borderRadius: 12.r, padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), height: 40.h, iconSize: 14.h, icon: AppAssets.view_report_icon, iconColor: AppColors.infoColor, ), SizedBox(height: 16.h), ], ), ) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (labViewModel.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: labViewModel.indexedCharacterForUniqueTest, details: labViewModel.uniqueTestsList, labViewModel: labViewModel, 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 'dart:convert'; 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/appbar/collapsing_list_view.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'; import 'dart:ui' as ui; 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 CollapsingListView( title: LocaleKeys.labResults.tr(context: context), search: () async { if (labProvider.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: labProvider.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; labProvider.filterLabReports(value); } } }, child: Consumer( builder: (context, labViewModel, child) { return SingleChildScrollView( physics: NeverScrollableScrollPhysics(), 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: () { // labViewModel.setIsSortByClinic(true); // }, // backgroundColor: labViewModel.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, // borderColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), // textColor: labViewModel.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, // fontSize: 12.f, // 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: () { // labViewModel.setIsSortByClinic(false); // }, // backgroundColor: labViewModel.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, // borderColor: labViewModel.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, // textColor: labViewModel.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 ? Column( children: [ AppCustomChipWidget( labelText: selectedFilterText!, backgroundColor: AppColors.alertColor, textColor: AppColors.whiteColor, deleteIcon: AppAssets.close_bottom_sheet_icon, deleteIconColor: AppColors.whiteColor, deleteIconHasColor: true, onDeleteTap: () { selectedFilterText = ""; labProvider.filterLabReports(""); }, ), SizedBox(height: 8.h), ], ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available labViewModel.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (labViewModel.patientLabOrders.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: labViewModel.patientLabOrders.length, itemBuilder: (context, index) { final group = labViewModel.patientLabOrders[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: [ Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ AppCustomChipWidget( labelText: "${group.testDetails!.length} ${LocaleKeys.tests.tr(context: context)}", backgroundColor: AppColors.successColor.withOpacity(0.1), textColor: AppColors.successColor, ), AppCustomChipWidget( labelText: "${_appState.isArabic() ? group.isInOutPatientDescriptionN : group.isInOutPatientDescription}", backgroundColor: AppColors.warningColorYellow.withOpacity(0.1), textColor: AppColors.warningColorYellow, ) ], ), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), Row( mainAxisSize: MainAxisSize.min, children: [ Image.network( group.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: (group.doctorName ?? group.doctorNameEnglish ?? "").toString().toText14(weight: FontWeight.w500)), ], ), SizedBox(height: 8.h), Wrap( direction: Axis.horizontal, spacing: 4.h, runSpacing: 4.h, children: [ Directionality( textDirection: ui.TextDirection.ltr, child: AppCustomChipWidget( labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(group.orderDate ?? ""), false), isEnglishOnly: true, )), AppCustomChipWidget( labelText: (group.projectName ?? ""), ), AppCustomChipWidget( labelText: (group.clinicDescription ?? ""), ), ], ), ], ), ), 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( children: [ ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemBuilder: (cxt, index) { PatientLabOrdersResponseModel order = group; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ "• ${order.testDetails![index].description!}".toText14(weight: FontWeight.w500), SizedBox(height: 4.h), order.testDetails![index].testDescriptionEn!.toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), // 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!}"), isEnglishOnly: true, // ), // Directionality( // textDirection: ui.TextDirection.ltr, // child: AppCustomChipWidget( // labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(order.orderDate ?? ""), false), // isEnglishOnly: true, // )), // AppCustomChipWidget( // labelText: labViewModel.isSortByClinic ? (order.projectName ?? "") : (order.clinicDescription ?? ""), // ), // ], // ), // // 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: () { // labViewModel.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), ], ).paddingOnly(top: 16, bottom: 16); }, separatorBuilder: (cxt, index) => Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), itemCount: group.testDetails!.length > 3 ? 3 : group.testDetails!.length), SizedBox(height: 16.h), CustomButton( text: "${LocaleKeys.viewResults.tr()} (${group.testDetails!.length})", onPressed: () { labProvider.currentlySelectedPatientOrder = group; labProvider.getPatientLabResultByHospital(group); labProvider.getPatientSpecialResult(group); Navigator.of(context).push( CustomPageRoute( page: LabResultByClinic(labOrder: group), ), ); }, backgroundColor: AppColors.infoColor.withAlpha(20), borderColor: AppColors.infoColor.withAlpha(0), textColor: AppColors.infoColor, fontSize: (isFoldable || isTablet) ? 12.f : 14.f, fontWeight: FontWeight.w500, borderRadius: 12.r, padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), height: 40.h, iconSize: 14.h, icon: AppAssets.view_report_icon, iconColor: AppColors.infoColor, ), SizedBox(height: 16.h), ], ), ) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: LocaleKeys.noLabResults.tr(context: context))) : // By Test or other tabs keep existing behavior (labViewModel.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: labViewModel.indexedCharacterForUniqueTest, details: labViewModel.uniqueTestsList, labViewModel: labViewModel, 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/medical_file/patient_sickleaves_list_page.dart b/lib/presentation/medical_file/patient_sickleaves_list_page.dart index 93cf17ff..4518eca5 100644 --- a/lib/presentation/medical_file/patient_sickleaves_list_page.dart +++ b/lib/presentation/medical_file/patient_sickleaves_list_page.dart @@ -57,48 +57,48 @@ class _PatientSickleavesListPageState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox(height: 16.h), + // SizedBox(height: 16.h), // Clinic & Hospital Sort - Row( - children: [ - CustomButton( - text: LocaleKeys.byClinic.tr(context: context), - onPressed: () { - model.setIsSickLeavesSortByClinic(true); - }, - backgroundColor: model.isSickLeavesSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, - borderColor: model.isSickLeavesSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), - textColor: model.isSickLeavesSortByClinic ? 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.setIsSickLeavesSortByClinic(false); - }, - backgroundColor: model.isSickLeavesSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, - borderColor: model.isSickLeavesSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, - textColor: model.isSickLeavesSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, - fontSize: 12, - fontWeight: FontWeight.w500, - borderRadius: 10, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, - ), - ], - ).paddingSymmetrical(24.h, 0.h), - SizedBox(height: 20.h), + // Row( + // children: [ + // CustomButton( + // text: LocaleKeys.byClinic.tr(context: context), + // onPressed: () { + // model.setIsSickLeavesSortByClinic(true); + // }, + // backgroundColor: model.isSickLeavesSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, + // borderColor: model.isSickLeavesSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), + // textColor: model.isSickLeavesSortByClinic ? 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.setIsSickLeavesSortByClinic(false); + // }, + // backgroundColor: model.isSickLeavesSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, + // borderColor: model.isSickLeavesSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, + // textColor: model.isSickLeavesSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, + // fontSize: 12, + // fontWeight: FontWeight.w500, + // borderRadius: 10, + // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + // height: 40.h, + // ), + // ], + // ).paddingSymmetrical(24.h, 0.h), + // SizedBox(height: 20.h), // Expandable list ListView.builder( itemCount: model.isPatientSickLeaveListLoading ? 4 : model.patientSickLeaveList.isNotEmpty - ? model.patientSickLeavesViewList.length + ? model.patientSickLeaveList.length : 1, physics: NeverScrollableScrollPhysics(), shrinkWrap: true, @@ -122,155 +122,322 @@ class _PatientSickleavesListPageState extends State { 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, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppCustomChipWidget( + labelText: + "${getIt.get().isArabic() ? model.patientSickLeaveList[index].isInOutPatientDescriptionN : model.patientSickLeaveList[index].isInOutPatientDescription}", + backgroundColor: AppColors.warningColorYellow.withOpacity(0.1), + textColor: AppColors.warningColorYellow, + ), + SizedBox(height: 16.h), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Image.network( + model.patientSickLeaveList[index].doctorImageURL!, + width: 24.h, + height: 24.h, + fit: BoxFit.fill, + ).circle(100), + SizedBox(width: 8.h), + Expanded(child: model.patientSickLeaveList[index].doctorName!.toText14(weight: FontWeight.w500)), + ], + ), + SizedBox(height: 8.h), + Wrap( + direction: Axis.horizontal, + spacing: 6.h, + runSpacing: 6.h, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - CustomButton( - text: "${model.patientSickLeavesViewList[index].sickLeavesList!.length} ${LocaleKeys.sickSubtitle.tr(context: context)} Available", - 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: 30.h, - ), - Icon(isExpanded ? Icons.expand_less : Icons.expand_more), - ], + AppCustomChipWidget( + labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(model.patientSickLeaveList[index].appointmentDate), false), + ), + AppCustomChipWidget( + labelText: model.isSickLeavesSortByClinic ? model.patientSickLeaveList[index].projectName! : model.patientSickLeaveList[index].clinicName!, + ), + AppCustomChipWidget( + labelText: "${model.patientSickLeaveList[index].sickLeaveDays} Days", ), - SizedBox(height: 8.h), - model.patientSickLeavesViewList[index].filterName!.toText16(isBold: true) ], ), - ), - 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, + SizedBox(height: 12.h), + Row( + children: [ + Expanded( + flex: 6, + child: CustomButton( + text: LocaleKeys.downloadReport.tr(context: context), + onPressed: () async { + LoaderBottomSheet.showLoader(); + await medicalFileViewModel.getPatientSickLeavePDF(model.patientSickLeaveList[index], appState.getAuthenticatedUser()!).then((val) async { + LoaderBottomSheet.hideLoader(); + if (medicalFileViewModel.patientSickLeavePDFBase64.isNotEmpty) { + String path = await Utils.createFileFromString(medicalFileViewModel.patientSickLeavePDFBase64, "pdf"); + try { + OpenFilex.open(path); + } catch (ex) { + debugPrint("Error opening file: $ex"); + } + } + }); + }, + 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, + icon: AppAssets.download, + iconColor: AppColors.primaryRedColor, + iconSize: 14.h, + ), ), - ); - }, - child: isExpanded - ? Container( - key: ValueKey(index), - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 8.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ...model.patientSickLeavesViewList[index].sickLeavesList!.map((sickLeave) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisSize: MainAxisSize.min, - children: [ - Image.network( - sickLeave.doctorImageURL!, - width: 24.h, - height: 24.h, - fit: BoxFit.fill, - ).circle(100), - SizedBox(width: 8.h), - Expanded(child: sickLeave.doctorName!.toText14(weight: FontWeight.w500)), - ], - ), - SizedBox(height: 8.h), - Wrap( - direction: Axis.horizontal, - spacing: 6.h, - runSpacing: 6.h, - children: [ - AppCustomChipWidget( - labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(sickLeave.appointmentDate), false), - ), - AppCustomChipWidget( - labelText: model.isSickLeavesSortByClinic ? sickLeave.projectName! : sickLeave.clinicName!, - ), - AppCustomChipWidget( - labelText: "${sickLeave.sickLeaveDays} Days", - ), - ], - ), - SizedBox(height: 12.h), - Row( - children: [ - Expanded( - flex: 6, - child: CustomButton( - text: LocaleKeys.downloadReport.tr(context: context), - onPressed: () async { - LoaderBottomSheet.showLoader(); - await medicalFileViewModel.getPatientSickLeavePDF(sickLeave, appState.getAuthenticatedUser()!).then((val) async { - LoaderBottomSheet.hideLoader(); - if (medicalFileViewModel.patientSickLeavePDFBase64.isNotEmpty) { - String path = await Utils.createFileFromString(medicalFileViewModel.patientSickLeavePDFBase64, "pdf"); - try { - OpenFilex.open(path); - } catch (ex) { - debugPrint("Error opening file: $ex"); - } - } - }); - }, - 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, - icon: AppAssets.download, - iconColor: AppColors.primaryRedColor, - iconSize: 14.h, - ), - ), - ], - ), - SizedBox(height: 12.h), - Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), - SizedBox(height: 12.h), - ], - ); - }), - ], - ), - ) - : SizedBox.shrink(), - ), - ], + ], + ), + // SizedBox(height: 12.h), + // Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + // SizedBox(height: 12.h), + ], + ), + // Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // ...model.patientSickLeaveList[index].sickLeavesList!.map((sickLeave) { + // return Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Row( + // mainAxisSize: MainAxisSize.min, + // children: [ + // Image.network( + // sickLeave.doctorImageURL!, + // width: 24.h, + // height: 24.h, + // fit: BoxFit.fill, + // ).circle(100), + // SizedBox(width: 8.h), + // Expanded(child: sickLeave.doctorName!.toText14(weight: FontWeight.w500)), + // ], + // ), + // SizedBox(height: 8.h), + // Wrap( + // direction: Axis.horizontal, + // spacing: 6.h, + // runSpacing: 6.h, + // children: [ + // AppCustomChipWidget( + // labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(sickLeave.appointmentDate), false), + // ), + // AppCustomChipWidget( + // labelText: model.isSickLeavesSortByClinic ? sickLeave.projectName! : sickLeave.clinicName!, + // ), + // AppCustomChipWidget( + // labelText: "${sickLeave.sickLeaveDays} Days", + // ), + // ], + // ), + // SizedBox(height: 12.h), + // Row( + // children: [ + // Expanded( + // flex: 6, + // child: CustomButton( + // text: LocaleKeys.downloadReport.tr(context: context), + // onPressed: () async { + // LoaderBottomSheet.showLoader(); + // await medicalFileViewModel.getPatientSickLeavePDF(sickLeave, appState.getAuthenticatedUser()!).then((val) async { + // LoaderBottomSheet.hideLoader(); + // if (medicalFileViewModel.patientSickLeavePDFBase64.isNotEmpty) { + // String path = await Utils.createFileFromString(medicalFileViewModel.patientSickLeavePDFBase64, "pdf"); + // try { + // OpenFilex.open(path); + // } catch (ex) { + // debugPrint("Error opening file: $ex"); + // } + // } + // }); + // }, + // 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, + // icon: AppAssets.download, + // iconColor: AppColors.primaryRedColor, + // iconSize: 14.h, + // ), + // ), + // ], + // ), + // SizedBox(height: 12.h), + // Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + // SizedBox(height: 12.h), + // ], + // ); + // }), + // ], + // ), + ) + // 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: [ + // CustomButton( + // text: "${model.patientSickLeavesViewList[index].sickLeavesList!.length} ${LocaleKeys.sickSubtitle.tr(context: context)} Available", + // 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: 30.h, + // ), + // Icon(isExpanded ? Icons.expand_less : Icons.expand_more), + // ], + // ), + // SizedBox(height: 8.h), + // model.patientSickLeavesViewList[index].filterName!.toText16(isBold: true) + // ], + // ), + // ), + // // 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.h, vertical: 8.h), + // // child: Column( + // // crossAxisAlignment: CrossAxisAlignment.start, + // // children: [ + // // ...model.patientSickLeavesViewList[index].sickLeavesList!.map((sickLeave) { + // // return Column( + // // crossAxisAlignment: CrossAxisAlignment.start, + // // children: [ + // // Row( + // // mainAxisSize: MainAxisSize.min, + // // children: [ + // // Image.network( + // // sickLeave.doctorImageURL!, + // // width: 24.h, + // // height: 24.h, + // // fit: BoxFit.fill, + // // ).circle(100), + // // SizedBox(width: 8.h), + // // Expanded(child: sickLeave.doctorName!.toText14(weight: FontWeight.w500)), + // // ], + // // ), + // // SizedBox(height: 8.h), + // // Wrap( + // // direction: Axis.horizontal, + // // spacing: 6.h, + // // runSpacing: 6.h, + // // children: [ + // // AppCustomChipWidget( + // // labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(sickLeave.appointmentDate), false), + // // ), + // // AppCustomChipWidget( + // // labelText: model.isSickLeavesSortByClinic ? sickLeave.projectName! : sickLeave.clinicName!, + // // ), + // // AppCustomChipWidget( + // // labelText: "${sickLeave.sickLeaveDays} Days", + // // ), + // // ], + // // ), + // // SizedBox(height: 12.h), + // // Row( + // // children: [ + // // Expanded( + // // flex: 6, + // // child: CustomButton( + // // text: LocaleKeys.downloadReport.tr(context: context), + // // onPressed: () async { + // // LoaderBottomSheet.showLoader(); + // // await medicalFileViewModel.getPatientSickLeavePDF(sickLeave, appState.getAuthenticatedUser()!).then((val) async { + // // LoaderBottomSheet.hideLoader(); + // // if (medicalFileViewModel.patientSickLeavePDFBase64.isNotEmpty) { + // // String path = await Utils.createFileFromString(medicalFileViewModel.patientSickLeavePDFBase64, "pdf"); + // // try { + // // OpenFilex.open(path); + // // } catch (ex) { + // // debugPrint("Error opening file: $ex"); + // // } + // // } + // // }); + // // }, + // // 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, + // // icon: AppAssets.download, + // // iconColor: AppColors.primaryRedColor, + // // iconSize: 14.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.youDontHaveAnySickLeavesYet.tr(context: context)); }, ).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 24.h), ], ); }), diff --git a/lib/presentation/my_invoices/my_invoices_details_page.dart b/lib/presentation/my_invoices/my_invoices_details_page.dart index a38194fe..79e1adc3 100644 --- a/lib/presentation/my_invoices/my_invoices_details_page.dart +++ b/lib/presentation/my_invoices/my_invoices_details_page.dart @@ -9,6 +9,7 @@ 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/my_invoices/models/get_invoice_details_response_model.dart'; +import 'package:hmg_patient_app_new/features/my_invoices/models/get_invoices_list_response_model.dart'; import 'package:hmg_patient_app_new/features/my_invoices/my_invoices_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; @@ -20,8 +21,9 @@ import 'package:provider/provider.dart'; class MyInvoicesDetailsPage extends StatefulWidget { GetInvoiceDetailsResponseModel getInvoiceDetailsResponseModel; + GetInvoicesListResponseModel getInvoicesListResponseModel; - MyInvoicesDetailsPage({super.key, required this.getInvoiceDetailsResponseModel}); + MyInvoicesDetailsPage({super.key, required this.getInvoiceDetailsResponseModel, required this.getInvoicesListResponseModel}); @override State createState() => _MyInvoicesDetailsPageState(); @@ -82,6 +84,26 @@ class _MyInvoicesDetailsPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + Wrap( + alignment: WrapAlignment.start, + direction: Axis.horizontal, + spacing: 6.w, + runSpacing: 6.h, + children: [ + AppCustomChipWidget( + icon: AppAssets.walkin_appointment_icon, + iconColor: AppColors.textColor, + labelText: LocaleKeys.walkin.tr(context: context), + textColor: AppColors.textColor, + ), + AppCustomChipWidget( + labelText: LocaleKeys.outPatient.tr(context: context), + backgroundColor: AppColors.warningColorYellow.withValues(alpha: 0.1), + textColor: AppColors.warningColorYellow, + ), + ], + ), + SizedBox(height: 16.h), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -93,6 +115,29 @@ class _MyInvoicesDetailsPageState extends State { height: 63.h, fit: BoxFit.cover, ).circle(100.r), + Transform.translate( + offset: Offset(0.0, -20.h), + child: Container( + width: 40.w, + height: 40.h, + decoration: BoxDecoration( + color: AppColors.whiteColor, + shape: BoxShape.circle, // Makes the container circular + border: Border.all( + color: AppColors.scaffoldBgColor, // Color of the border + width: 1.5.w, // Width of the border + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.rating_icon, width: 15.w, height: 15.h, applyThemeColor: false), + SizedBox(height: 2.h), + "${widget.getInvoicesListResponseModel.decimalDoctorRate}".toText11(isBold: true, color: AppColors.textColor), + ], + ), + ).circle(100), + ), ], ), SizedBox(width: 16.w), @@ -138,41 +183,46 @@ class _MyInvoicesDetailsPageState extends State { ), ), SizedBox(height: 16.h), - Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.h, - hasShadow: true, - ), - child: Padding( - padding: EdgeInsets.all(14.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - widget.getInvoiceDetailsResponseModel.listConsultation!.first.procedureName!.toText16(isBold: true), - SizedBox(height: 16.h), - Wrap( - direction: Axis.horizontal, - spacing: 6.w, - runSpacing: 6.h, + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: true, + ), + child: Padding( + padding: EdgeInsets.all(14.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - AppCustomChipWidget( - labelText: "${LocaleKeys.quantity.tr()}: ${widget.getInvoiceDetailsResponseModel.listConsultation!.first.quantity!}", - labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), - ), - AppCustomChipWidget( - labelText: "${LocaleKeys.price.tr()}: ${widget.getInvoiceDetailsResponseModel.listConsultation!.first.price!} ${LocaleKeys.sar.tr()}", - labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), - ), - AppCustomChipWidget( - labelText: "${LocaleKeys.total.tr()}: ${widget.getInvoiceDetailsResponseModel.listConsultation!.first.total!} ${LocaleKeys.sar.tr()}", - labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), + widget.getInvoiceDetailsResponseModel.listConsultation!.first.procedureName!.toText16(isBold: true), + SizedBox(height: 16.h), + Wrap( + direction: Axis.horizontal, + spacing: 6.w, + runSpacing: 6.h, + children: [ + AppCustomChipWidget( + labelText: "${LocaleKeys.quantity.tr()}: ${widget.getInvoiceDetailsResponseModel.listConsultation!.first.quantity!}", + labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), + ), + AppCustomChipWidget( + labelText: "${LocaleKeys.price.tr()}: ${widget.getInvoiceDetailsResponseModel.listConsultation!.first.price!} ${LocaleKeys.sar.tr()}", + labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), + ), + AppCustomChipWidget( + labelText: "${LocaleKeys.total.tr()}: ${widget.getInvoiceDetailsResponseModel.listConsultation!.first.total!} ${LocaleKeys.sar.tr()}", + labelPadding: EdgeInsetsDirectional.only(start: 6.w, end: 6.w), + ), + ], ), ], ), - ], + ), ), - ), + ], ), SizedBox(height: 16.h), Container( diff --git a/lib/presentation/my_invoices/my_invoices_list.dart b/lib/presentation/my_invoices/my_invoices_list.dart index 177dde84..dddb0a15 100644 --- a/lib/presentation/my_invoices/my_invoices_list.dart +++ b/lib/presentation/my_invoices/my_invoices_list.dart @@ -86,7 +86,7 @@ class _MyInvoicesListState extends State { LoaderBottomSheet.hideLoader(); Navigator.of(context).push( CustomPageRoute( - page: MyInvoicesDetailsPage(getInvoiceDetailsResponseModel: myInvoicesVM.invoiceDetailsResponseModel), + page: MyInvoicesDetailsPage(getInvoiceDetailsResponseModel: myInvoicesVM.invoiceDetailsResponseModel, getInvoicesListResponseModel: myInvoicesVM.allInvoicesList[index],), ), ); }, diff --git a/lib/presentation/my_invoices/widgets/invoice_list_card.dart b/lib/presentation/my_invoices/widgets/invoice_list_card.dart index 6e0fa0e4..e5ae7de8 100644 --- a/lib/presentation/my_invoices/widgets/invoice_list_card.dart +++ b/lib/presentation/my_invoices/widgets/invoice_list_card.dart @@ -47,8 +47,8 @@ class InvoiceListCard extends StatelessWidget { ), AppCustomChipWidget( labelText: LocaleKeys.outPatient.tr(context: context), - backgroundColor: AppColors.primaryRedColor.withValues(alpha: 0.1), - textColor: AppColors.primaryRedColor, + backgroundColor: AppColors.warningColorYellow.withValues(alpha: 0.1), + textColor: AppColors.warningColorYellow, ), ], ), diff --git a/lib/presentation/prescriptions/prescription_detail_page.dart b/lib/presentation/prescriptions/prescription_detail_page.dart index 235ad554..0ac9ce40 100644 --- a/lib/presentation/prescriptions/prescription_detail_page.dart +++ b/lib/presentation/prescriptions/prescription_detail_page.dart @@ -114,8 +114,8 @@ class _PrescriptionDetailPageState extends State { AppCustomChipWidget( labelText: "${getIt.get().isArabic() ? widget.prescriptionsResponseModel.isInOutPatientDescriptionN : widget.prescriptionsResponseModel.isInOutPatientDescription}", - backgroundColor: widget.prescriptionsResponseModel.isInOutPatient! ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.warningColorYellow.withOpacity(0.1), - textColor: widget.prescriptionsResponseModel.isInOutPatient! ? AppColors.primaryRedColor : AppColors.warningColorYellow, + backgroundColor: AppColors.warningColorYellow.withOpacity(0.1), + textColor: AppColors.warningColorYellow, ), SizedBox(height: 16.h), Row( diff --git a/lib/presentation/prescriptions/prescription_item_view.dart b/lib/presentation/prescriptions/prescription_item_view.dart index 2b19e3a4..7f969b21 100644 --- a/lib/presentation/prescriptions/prescription_item_view.dart +++ b/lib/presentation/prescriptions/prescription_item_view.dart @@ -103,14 +103,13 @@ class PrescriptionItemView extends StatelessWidget { Switch( activeColor: AppColors.successColor, activeTrackColor: AppColors.successColor.withValues(alpha: .15), - // value: isLoading ? false : prescriptionVM.prescriptionDetailsList[index].hasReminder!, - value: prescriptionVM.prescriptionDetailsList[index].hasReminder!, + value: isLoading ? false : prescriptionVM.prescriptionDetailsList[index].hasReminder!, + // value: prescriptionVM.prescriptionDetailsList[index].hasReminder ?? false, onChanged: (newValue) async { CalenderUtilsNew calender = CalenderUtilsNew.instance; if (await prescriptionVM.checkIfReminderExistForPrescription(index)) { prescriptionVM.prescriptionDetailsList[index].hasReminder = true; - } else { if (prescriptionVM.prescriptionDetailsList[index].hasReminder ?? false) { LoaderBottomSheet.showLoader(loadingText: "Removing Reminders"); bool resultValue = await calender.checkAndRemoveMultipleItems(id: prescriptionVM.prescriptionDetailsList[index].itemID.toString()); @@ -119,7 +118,7 @@ class PrescriptionItemView extends StatelessWidget { LoaderBottomSheet.hideLoader(); return; } - + } else { DateTime startDate = DateTime.now(); DateTime endDate = DateTime(startDate.year, startDate.month, startDate.day + prescriptionVM.prescriptionDetailsList[index].days!.toInt()); BottomSheetUtils().showReminderBottomSheet( diff --git a/lib/presentation/prescriptions/prescriptions_list_page.dart b/lib/presentation/prescriptions/prescriptions_list_page.dart index da211f9d..3a54926f 100644 --- a/lib/presentation/prescriptions/prescriptions_list_page.dart +++ b/lib/presentation/prescriptions/prescriptions_list_page.dart @@ -143,9 +143,8 @@ class _PrescriptionsListPageState extends State { AppCustomChipWidget( labelText: "${getIt.get().isArabic() ? model.patientPrescriptionOrders[index].isInOutPatientDescriptionN : model.patientPrescriptionOrders[index].isInOutPatientDescription}", - backgroundColor: - model.patientPrescriptionOrders[index].isInOutPatient! ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.warningColorYellow.withOpacity(0.1), - textColor: model.patientPrescriptionOrders[index].isInOutPatient! ? AppColors.primaryRedColor : AppColors.warningColorYellow, + backgroundColor: AppColors.warningColorYellow.withOpacity(0.1), + textColor: AppColors.warningColorYellow, ), SizedBox(height: 16.h), Row( diff --git a/lib/presentation/radiology/radiology_orders_page.dart b/lib/presentation/radiology/radiology_orders_page.dart index e24c3472..1a3ab448 100644 --- a/lib/presentation/radiology/radiology_orders_page.dart +++ b/lib/presentation/radiology/radiology_orders_page.dart @@ -169,7 +169,7 @@ class _RadiologyOrdersPageState extends State { ); } - if (model.patientRadiologyOrdersViewList.isEmpty) { + if (model.patientRadiologyOrders.isEmpty) { return Utils.getNoDataWidget(ctx, noDataText: LocaleKeys.youDontHaveRadiologyOrders.tr(context: context)); } @@ -393,8 +393,8 @@ class _RadiologyOrdersPageState extends State { children: [ AppCustomChipWidget( labelText: "${getIt.get().isArabic() ? group.isInOutPatientDescriptionN : group.isInOutPatientDescription}", - backgroundColor: group.isInOutPatient! ? AppColors.primaryRedColor.withOpacity(0.1) : AppColors.warningColorYellow.withOpacity(0.1), - textColor: group.isInOutPatient! ? AppColors.primaryRedColor : AppColors.warningColorYellow, + backgroundColor: AppColors.warningColorYellow.withOpacity(0.1), + textColor: AppColors.warningColorYellow, ), SizedBox(height: 16.h), Row( From 6a4793f122416dc9caf15f7803538b712eb795d5 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Mon, 30 Mar 2026 17:02:14 +0300 Subject: [PATCH 17/17] Updates --- ios/Runner.xcodeproj/project.pbxproj | 17 ++++++----------- ios/Runner/Info.plist | 2 +- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 6a81b151..9f1f6de9 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -343,14 +343,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; @@ -364,14 +360,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; @@ -531,10 +523,11 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 14; + CURRENT_PROJECT_VERSION = 15; DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Dr. Alhabib"; IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -717,10 +710,11 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 14; + CURRENT_PROJECT_VERSION = 15; DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Dr. Alhabib"; IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -746,10 +740,11 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 14; + CURRENT_PROJECT_VERSION = 15; DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Dr. Alhabib"; IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index f412b006..bbe54c9a 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -13,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - Dr. Alhabib Beta + Dr. Alhabib CFBundlePackageType APPL CFBundleShortVersionString