Refund Request Started

faiz_dev
faizatflutter 2 days ago
parent 285287e596
commit 7cf593443d

@ -1845,5 +1845,6 @@
"maxOneFileAllowed": "يمكن رفع ملف واحد فقط",
"fileSizeExceedsLimit": "يجب ألا يتجاوز حجم الملف 1 ميغابايت",
"completedPrescriptionOrder": "تمت الخدمة",
"submitEReferral": "تقديم الطلب"
"submitEReferral": "تقديم الطلب",
"requestRefund": "طلب استرداد"
}

@ -1835,7 +1835,8 @@
"maxOneFileAllowed": "Only 1 file can be uploaded",
"fileSizeExceedsLimit": "File size must not exceed 1 MB",
"completedPrescriptionOrder": "Completed",
"submitEReferral": "Submit"
"submitEReferral": "Submit",
"requestRefund": "Request Refund"
}

@ -601,7 +601,7 @@ SPEC CHECKSUMS:
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
path_provider_foundation: 0b743cbb62d8e47eab856f09262bb8c1ddcfe6ba
PayFortSDK: 233eabe9a45601fdbeac67fa6e5aae46ed8faf82
PayFortSDK: e12f79051ae15b2e29536771a45354900180bfcb
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
Polyline: 2a1f29f87f8d9b7de868940f4f76deb8c678a5b1
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
@ -612,7 +612,7 @@ SPEC CHECKSUMS:
shared_preferences_foundation: 5086985c1d43c5ba4d5e69a4e8083a389e2909e6
Solar-dev: 4612dc9878b9fed2667d23b327f1d4e54e16e8d0
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
SwiftProtobuf: e1b437c8e31a4c5577b643249a0bb62ed4f02153
SwiftProtobuf: 9e106a71456f4d3f6a3b0c8fd87ef0be085efc38
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
Turf: aa2ede4298009639d10db36aba1a7ebaad072a5e
url_launcher_ios: bb13df5870e8c4234ca12609d04010a21be43dfa

@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
1587365701FF0D2AAAFED0D8 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A83C76CFF9D3F92EDE3B22B4 /* Pods_Runner.framework */; };
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 */; };
@ -25,7 +26,6 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
DE1EF78253E64BE86845D2CC /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D562310E31D1DDEFA02A6C12 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -52,11 +52,13 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
05E1B2A0E6844572ADA81174 /* 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 = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3EAE1F31D8D0AA94CA6C11EB /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
478CFA932E638C8E0064F3D7 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
478CFA952E6E20A60064F3D7 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
61243B3D2EC5FA3700D46FA0 /* HMGPenguinInPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMGPenguinInPlatformBridge.swift; sourceTree = "<group>"; };
@ -70,11 +72,10 @@
687F8A672F828A6300B0FFC1 /* PenNavUI.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = PenNavUI.xcframework; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
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 = "<group>"; };
769C9BF82E6F106D009F68A9 /* RunnerDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerDebug.entitlements; sourceTree = "<group>"; };
76AA18AC2F3B2A4D00DC8DFC /* ring_30Sec.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = ring_30Sec.caf; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
8E12CEEB8E334EE22D5259D7 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
7BEF44ABFEF585D64D3F266C /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -82,8 +83,7 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D562310E31D1DDEFA02A6C12 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D6BB17A036DF7FCE75271203 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
A83C76CFF9D3F92EDE3B22B4 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -91,10 +91,10 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DE1EF78253E64BE86845D2CC /* Pods_Runner.framework in Frameworks */,
687F8A682F828A6300B0FFC1 /* PenguinINRenderer.xcframework in Frameworks */,
687F8A692F828A6300B0FFC1 /* Penguin.xcframework in Frameworks */,
687F8A6A2F828A6300B0FFC1 /* PenNavUI.xcframework in Frameworks */,
1587365701FF0D2AAAFED0D8 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -135,7 +135,7 @@
687F8A652F828A6300B0FFC1 /* Penguin.xcframework */,
687F8A662F828A6300B0FFC1 /* PenguinINRenderer.xcframework */,
687F8A672F828A6300B0FFC1 /* PenNavUI.xcframework */,
D562310E31D1DDEFA02A6C12 /* Pods_Runner.framework */,
A83C76CFF9D3F92EDE3B22B4 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -143,9 +143,9 @@
79DD2093A1D9674C94359FC8 /* Pods */ = {
isa = PBXGroup;
children = (
8E12CEEB8E334EE22D5259D7 /* Pods-Runner.debug.xcconfig */,
7595037DD52211B91157B0F3 /* Pods-Runner.release.xcconfig */,
D6BB17A036DF7FCE75271203 /* Pods-Runner.profile.xcconfig */,
3EAE1F31D8D0AA94CA6C11EB /* Pods-Runner.debug.xcconfig */,
05E1B2A0E6844572ADA81174 /* Pods-Runner.release.xcconfig */,
7BEF44ABFEF585D64D3F266C /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@ -227,15 +227,15 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
BFED6CCFE59BB148875A533B /* [CP] Check Pods Manifest.lock */,
EA10FC42B68E41E75A052FAA /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
8372B02399CDF54531650AD4 /* [CP] Embed Pods Frameworks */,
81DE7C26F41956799E954FCE /* [CP] Copy Pods Resources */,
765A5A922F35CD8B0003FF7D /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
5D78F615DF2D966539B34DE2 /* [CP] Embed Pods Frameworks */,
4AA9AE39AD56A64A1F16E548 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@ -325,7 +325,7 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
81DE7C26F41956799E954FCE /* [CP] Copy Pods Resources */ = {
4AA9AE39AD56A64A1F16E548 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@ -342,7 +342,7 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
8372B02399CDF54531650AD4 /* [CP] Embed Pods Frameworks */ = {
5D78F615DF2D966539B34DE2 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@ -374,7 +374,7 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
BFED6CCFE59BB148875A533B /* [CP] Check Pods Manifest.lock */ = {
EA10FC42B68E41E75A052FAA /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (

@ -4,7 +4,7 @@ import 'package:hmg_patient_app_new/core/enums.dart';
class ApiConsts {
static const maxSmallScreen = 660;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod;
static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat;
// static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT
@ -269,6 +269,9 @@ class ApiConsts {
// static String getAiOverViewLabOrders = "Services/Patients.svc/REST/HMGAI_Lab_Analyze_Orders_API";
// static String getAiOverViewLabOrder = "Services/Patients.svc/REST/HMGAI_Lab_Analyzer_API";
//Refund Request
static String getRefundableInvoices = "Services/Outps.svc/REST/getRefundableInvoices";
static String getAiAnalysisURL = "https://api.labpredict.com";
static String getAiRadiologyAnalysis = "$getAiAnalysisURL/radiology";
static String getAiOverViewLabOrdersNew = "$getAiAnalysisURL/analyze_lab_orders";

@ -4,6 +4,7 @@ import 'package:get_it/get_it.dart';
import 'package:hmg_patient_app_new/core/api/api_client.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/location_util.dart';
import 'package:hmg_patient_app_new/features/active_prescriptions/active_prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_repo.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_view_model.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_repo.dart';
@ -12,8 +13,6 @@ import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_repo.
import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_repo.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/active_prescriptions/active_prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/features/active_prescriptions/models/active_prescriptions_response_model.dart';
import 'package:hmg_patient_app_new/features/common/common_repo.dart';
import 'package:hmg_patient_app_new/features/contact_us/contact_us_repo.dart';
import 'package:hmg_patient_app_new/features/contact_us/contact_us_view_model.dart';
@ -23,6 +22,7 @@ import 'package:hmg_patient_app_new/features/emergency_services/emergency_servic
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_repo.dart';
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart';
import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_repo.dart';
import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_view_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_repo.dart';
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_repo.dart';
@ -55,6 +55,8 @@ import 'package:hmg_patient_app_new/features/profile_settings/profile_settings_v
import 'package:hmg_patient_app_new/features/qr_parking/qr_parking_repo.dart';
import 'package:hmg_patient_app_new/features/radiology/radiology_repo.dart';
import 'package:hmg_patient_app_new/features/radiology/radiology_view_model.dart';
import 'package:hmg_patient_app_new/features/refund_request/refund_request_repo.dart';
import 'package:hmg_patient_app_new/features/refund_request/refund_request_view_model.dart';
import 'package:hmg_patient_app_new/features/services_price_list/services_price_list_repo.dart';
import 'package:hmg_patient_app_new/features/services_price_list/services_price_list_view_model.dart';
import 'package:hmg_patient_app_new/features/smartwatch_health_data/health_provider.dart';
@ -66,7 +68,6 @@ import 'package:hmg_patient_app_new/features/water_monitor/water_monitor_repo.da
import 'package:hmg_patient_app_new/features/water_monitor/water_monitor_view_model.dart';
import 'package:hmg_patient_app_new/features/weather/weather_repo.dart';
import 'package:hmg_patient_app_new/features/weather/weather_view_model.dart';
import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_view_model.dart';
import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart';
import 'package:hmg_patient_app_new/services/app_lifecycle_service.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart';
@ -83,13 +84,11 @@ import 'package:local_auth/local_auth.dart';
import 'package:logger/web.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../features/monthly_reports/monthly_reports_repo.dart';
import '../features/qr_parking/qr_parking_view_model.dart';
import '../presentation/health_calculators_and_converts/health_calculator_view_model.dart';
import '../features/active_prescriptions/active_prescriptions_repo.dart';
import '../features/monthly_reports/terms_conditions_repo.dart';
import '../features/monthly_reports/terms_conditions_view_model.dart';
import '../features/qr_parking/qr_parking_view_model.dart';
import '../presentation/health_calculators_and_converts/health_calculator_view_model.dart';
GetIt getIt = GetIt.instance;
@ -176,18 +175,14 @@ class AppDependencies {
getIt.registerLazySingleton<MonthlyReportRepo>(() => MonthlyReportRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<ActivePrescriptionsRepo>(() => ActivePrescriptionsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<TermsConditionsRepo>(() => TermsConditionsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerFactory<TermsConditionsViewModel>(
() => TermsConditionsViewModel(
termsConditionsRepo: getIt<TermsConditionsRepo>(),
errorHandlerService: getIt<ErrorHandlerService>(),
),
);
getIt.registerFactory<TermsConditionsViewModel>(() => TermsConditionsViewModel(termsConditionsRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton<MonthlyReportsRepo>(() => MonthlyReportsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<QrParkingRepo>(() => QrParkingRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<NotificationsRepo>(() => NotificationsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<AskDoctorRepo>(() => AskDoctorRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<ServicesPriceListRepo>(() => ServicesPriceListRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<ProfileSettingsRepo>(() => ProfileSettingsRepoImp(loggerService: getIt<LoggerService>(), apiClient: getIt()));
getIt.registerLazySingleton<RefundRequestRepo>(() => RefundRequestRepoImp(apiClient: getIt(), loggerService: getIt()));
// ViewModels
// Global/shared VMs LazySingleton
@ -198,13 +193,16 @@ class AppDependencies {
() => RadiologyViewModel(radiologyRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt()),
);
getIt.registerLazySingleton<PrescriptionsViewModel>(() => PrescriptionsViewModel(prescriptionsRepo: getIt(), errorHandlerService: getIt(), navServices: getIt()));
getIt.registerLazySingleton<PrescriptionsViewModel>(
() => PrescriptionsViewModel(prescriptionsRepo: getIt(), errorHandlerService: getIt(), navServices: getIt()));
getIt.registerLazySingleton<InsuranceViewModel>(() => InsuranceViewModel(insuranceRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton<MyAppointmentsViewModel>(() => MyAppointmentsViewModel(myAppointmentsRepo: getIt(), errorHandlerService: getIt(), appState: getIt()));
getIt.registerLazySingleton<MyAppointmentsViewModel>(
() => MyAppointmentsViewModel(myAppointmentsRepo: getIt(), errorHandlerService: getIt(), appState: getIt()));
getIt.registerLazySingleton<AppointmentRatingViewModel>(() => AppointmentRatingViewModel(myAppointmentsRepo: getIt(), errorHandlerService: getIt(), appState: getIt()));
getIt.registerLazySingleton<AppointmentRatingViewModel>(
() => AppointmentRatingViewModel(myAppointmentsRepo: getIt(), errorHandlerService: getIt(), appState: getIt()));
getIt.registerLazySingleton<PayfortViewModel>(
() => PayfortViewModel(payfortRepo: getIt(), errorHandlerService: getIt()),
@ -223,7 +221,12 @@ class AppDependencies {
getIt.registerLazySingleton<BookAppointmentsViewModel>(
() => BookAppointmentsViewModel(
bookAppointmentsRepo: getIt(), errorHandlerService: getIt(), navigationService: getIt(), myAppointmentsViewModel: getIt(), locationUtils: getIt(), dialogService: getIt()),
bookAppointmentsRepo: getIt(),
errorHandlerService: getIt(),
navigationService: getIt(),
myAppointmentsViewModel: getIt(),
locationUtils: getIt(),
dialogService: getIt()),
);
getIt.registerLazySingleton<ImmediateLiveCareViewModel>(
@ -237,7 +240,13 @@ class AppDependencies {
getIt.registerLazySingleton<AuthenticationViewModel>(
() => AuthenticationViewModel(
authenticationRepo: getIt(), cacheService: getIt(), navigationService: getIt(), dialogService: getIt(), appState: getIt(), errorHandlerService: getIt(), localAuthService: getIt()),
authenticationRepo: getIt(),
cacheService: getIt(),
navigationService: getIt(),
dialogService: getIt(),
appState: getIt(),
errorHandlerService: getIt(),
localAuthService: getIt()),
);
getIt.registerLazySingleton<ProfileSettingsViewModel>(() => ProfileSettingsViewModel(
@ -310,22 +319,33 @@ class AppDependencies {
getIt.registerLazySingleton<WaterMonitorViewModel>(() => WaterMonitorViewModel(waterMonitorRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton<WeatherMonitorViewModel>(() => WeatherMonitorViewModel(weatherRepo: getIt(), errorHandlerService: getIt(), locationUtils: getIt()));
getIt.registerLazySingleton<WeatherMonitorViewModel>(
() => WeatherMonitorViewModel(weatherRepo: getIt(), errorHandlerService: getIt(), locationUtils: getIt()));
//commenting this because its already define there was on run time error because of this.
getIt.registerLazySingleton<MyInvoicesViewModel>(() => MyInvoicesViewModel(myInvoicesRepo: getIt(), errorHandlerService: getIt(), navServices: getIt()));
getIt.registerLazySingleton<MyInvoicesViewModel>(
() => MyInvoicesViewModel(myInvoicesRepo: getIt(), errorHandlerService: getIt(), navServices: getIt()));
getIt.registerLazySingleton<MonthlyReportViewModel>(() => MonthlyReportViewModel(errorHandlerService: getIt(), monthlyReportRepo: getIt()));
getIt.registerLazySingleton<NotificationsViewModel>(() => NotificationsViewModel(notificationsRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton<HealthTrackersViewModel>(() => HealthTrackersViewModel(healthTrackersRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton<ActivePrescriptionsViewModel>(() => ActivePrescriptionsViewModel(errorHandlerService: getIt(), activePrescriptionsRepo: getIt()));
getIt.registerFactory<QrParkingViewModel>(() => QrParkingViewModel(qrParkingRepo: getIt<QrParkingRepo>(), errorHandlerService: getIt<ErrorHandlerService>(), cacheService: getIt<CacheService>()));
getIt.registerLazySingleton<ActivePrescriptionsViewModel>(
() => ActivePrescriptionsViewModel(errorHandlerService: getIt(), activePrescriptionsRepo: getIt()));
getIt.registerFactory<QrParkingViewModel>(() => QrParkingViewModel(
qrParkingRepo: getIt<QrParkingRepo>(), errorHandlerService: getIt<ErrorHandlerService>(), cacheService: getIt<CacheService>()));
getIt.registerLazySingleton<AskDoctorViewModel>(() => AskDoctorViewModel(askDoctorRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton<ServicesPriceListViewModel>(() => ServicesPriceListViewModel(servicesPriceListRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton<DateRangCalenderModel>(() => DateRangCalenderModel(appState: getIt(), navigationService: getIt(), dialogService: getIt()));
getIt.registerLazySingleton<ServicesPriceListViewModel>(
() => ServicesPriceListViewModel(servicesPriceListRepo: getIt(), errorHandlerService: getIt()));
getIt.registerLazySingleton<DateRangCalenderModel>(
() => DateRangCalenderModel(appState: getIt(), navigationService: getIt(), dialogService: getIt()));
getIt.registerLazySingleton<RefundRequestViewModel>(() => RefundRequestViewModel(
appState: getIt(),
refundRequestRepo: getIt(),
errorHandlerService: getIt(),
));
}
}

@ -0,0 +1,90 @@
import 'dart:convert';
class RefundableInvoicesResponseModel {
final String? errorCode;
final String? message;
final List<RefundableInvoiceItem>? refundableInvoiceItems;
final int? statusCode;
RefundableInvoicesResponseModel({
this.errorCode,
this.message,
this.refundableInvoiceItems,
this.statusCode,
});
factory RefundableInvoicesResponseModel.fromJson(Map<String, dynamic> json) {
return RefundableInvoicesResponseModel(
errorCode: json['ErrorCode'] as String?,
message: json['Message'] as String?,
refundableInvoiceItems: json['RefundableInvoiceItems'] != null
? (json['RefundableInvoiceItems'] as List)
.map((item) => RefundableInvoiceItem.fromJson(item as Map<String, dynamic>))
.toList()
: null,
statusCode: json['StatusCode'] as int?,
);
}
}
class RefundableInvoiceItem {
final int? appointmentNo;
final int? clinicID;
final String? clinicName;
final int? doctorID;
final String? doctorName;
final String? invoiceDate;
final int? invoiceNo;
final String? nationalID;
final int? patientID;
final int? projectID;
RefundableInvoiceItem({
this.appointmentNo,
this.clinicID,
this.clinicName,
this.doctorID,
this.doctorName,
this.invoiceDate,
this.invoiceNo,
this.nationalID,
this.patientID,
this.projectID,
});
factory RefundableInvoiceItem.fromRawJson(String str) =>
RefundableInvoiceItem.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory RefundableInvoiceItem.fromJson(Map<String, dynamic> json) {
return RefundableInvoiceItem(
appointmentNo: json['AppointmentNo'] as int?,
clinicID: json['ClinicID'] as int?,
clinicName: json['ClinicName'] as String?,
doctorID: json['DoctorID'] as int?,
doctorName: json['DoctorName'] as String?,
invoiceDate: json['InvoiceDate'] as String?,
invoiceNo: json['InvoiceNo'] as int?,
nationalID: json['NationalID'] as String?,
patientID: json['PatientID'] as int?,
projectID: json['ProjectID'] as int?,
);
}
Map<String, dynamic> toJson() {
return {
'AppointmentNo': appointmentNo,
'ClinicID': clinicID,
'ClinicName': clinicName,
'DoctorID': doctorID,
'DoctorName': doctorName,
'InvoiceDate': invoiceDate,
'InvoiceNo': invoiceNo,
'NationalID': nationalID,
'PatientID': patientID,
'ProjectID': projectID,
};
}
}

@ -0,0 +1,81 @@
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/features/refund_request/models/resp_models/refundable_invoices_response_model.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
abstract class RefundRequestRepo {
Future<Either<Failure, GenericApiModel<List<RefundableInvoiceItem>>>>
getRefundableInvoices({required int projectID});
}
class RefundRequestRepoImp implements RefundRequestRepo {
final ApiClient apiClient;
final LoggerService loggerService;
RefundRequestRepoImp({required this.apiClient, required this.loggerService});
@override
Future<Either<Failure, GenericApiModel<List<RefundableInvoiceItem>>>>
getRefundableInvoices({required int projectID}) async {
// ApiClient auto-injects: PatientID, TokenID, LanguageID, PatientOutSA,
// PatientTypeID, IPAdress, generalid, VersionID, Channel
Map<String, dynamic> body = {
"ProjectID": projectID,
};
try {
GenericApiModel<List<RefundableInvoiceItem>>? apiResponse;
Failure? failure;
await apiClient.post(
ApiConsts.getRefundableInvoices,
body: body,
onFailure: (error, statusCode, {messageStatus, failureType}) {
failure = failureType;
},
onSuccess: (response, statusCode, {messageStatus, errorMessage}) {
try {
final refundableInvoicesObject =
response['RefundableInvoicesObject'];
if (refundableInvoicesObject != null) {
final invoiceItemsJson =
refundableInvoicesObject['RefundableInvoiceItems'];
final List<RefundableInvoiceItem> invoicesList =
invoiceItemsJson != null
? (invoiceItemsJson as List)
.map((item) => RefundableInvoiceItem.fromJson(
item as Map<String, dynamic>))
.toList()
: [];
apiResponse = GenericApiModel<List<RefundableInvoiceItem>>(
messageStatus: messageStatus,
statusCode: statusCode,
errorMessage: errorMessage,
data: invoicesList,
);
} else {
failure = DataParsingFailure("RefundableInvoicesObject is null");
}
} catch (e) {
loggerService.logError("getRefundableInvoices parsing error: $e");
failure = DataParsingFailure(e.toString());
}
},
);
if (failure != null) return Left(failure!);
if (apiResponse == null) return Left(ServerFailure("Unknown error"));
return Right(apiResponse!);
} catch (e) {
loggerService.logError("getRefundableInvoices exception: $e");
return Left(UnknownFailure(e.toString()));
}
}
}

@ -0,0 +1,194 @@
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/features/refund_request/models/resp_models/refundable_invoices_response_model.dart';
import 'package:hmg_patient_app_new/features/refund_request/refund_request_repo.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
enum RefundTabType { invoices, hmgWallet }
/// Lightweight model representing a refundable procedure line item.
class RefundableProcedure {
final int procedureId;
final String procedureName;
final String? procedureNameN;
final double patientShare;
bool isSelected;
RefundableProcedure({
required this.procedureId,
required this.procedureName,
this.procedureNameN,
required this.patientShare,
this.isSelected = false,
});
}
/// Lightweight model for an invoice dropdown item.
class RefundInvoiceItem {
final int invoiceNo;
final int appointmentNo;
final int projectId;
final String displayLabel;
const RefundInvoiceItem({
required this.invoiceNo,
required this.appointmentNo,
required this.projectId,
required this.displayLabel,
});
}
class RefundRequestViewModel extends ChangeNotifier {
final AppState appState;
final RefundRequestRepo refundRequestRepo;
final ErrorHandlerService errorHandlerService;
RefundRequestViewModel({
required this.appState,
required this.refundRequestRepo,
required this.errorHandlerService,
});
// Tab
RefundTabType selectedTab = RefundTabType.invoices;
void setTab(RefundTabType tab) {
selectedTab = tab;
notifyListeners();
}
// Step (0 = select invoice+hospital, 1 = select procedures)
int currentStep = 0;
void goToStep(int step) {
currentStep = step;
notifyListeners();
}
void nextStep() {
if (currentStep < 1) {
currentStep++;
notifyListeners();
}
}
void previousStep() {
if (currentStep > 0) {
currentStep--;
notifyListeners();
}
}
// Hospital selection
HospitalsModel? selectedHospital;
void setSelectedHospital(HospitalsModel? hospital) {
selectedHospital = hospital;
// Reset invoice and procedures whenever hospital changes
selectedInvoice = null;
procedures.clear();
refundableInvoicesList.clear();
notifyListeners();
// Fetch refundable invoices for the selected hospital's project
if (hospital != null && hospital.iD != null) {
final projectID = hospital.iD is int ? hospital.iD as int : int.tryParse(hospital.iD.toString());
if (projectID != null) {
getRefundableInvoices(projectID: projectID);
}
}
}
void clearHospital() {
selectedHospital = null;
selectedInvoice = null;
procedures.clear();
notifyListeners();
}
// Invoice selection
RefundInvoiceItem? selectedInvoice;
List<RefundableInvoiceItem> refundableInvoicesList = [];
bool isRefundableInvoicesLoading = false;
Future<void> getRefundableInvoices({
required int projectID,
Function(dynamic)? onSuccess,
Function(String)? onError,
}) async {
isRefundableInvoicesLoading = true;
refundableInvoicesList.clear();
notifyListeners();
final result = await refundRequestRepo.getRefundableInvoices(projectID: projectID);
result.fold(
(failure) {
isRefundableInvoicesLoading = false;
notifyListeners();
if (onError != null) {
onError(failure.message);
} else {
errorHandlerService.handleError(failure: failure);
}
},
(apiResponse) {
isRefundableInvoicesLoading = false;
if (apiResponse.messageStatus == 1 && apiResponse.data != null) {
refundableInvoicesList = apiResponse.data!;
notifyListeners();
if (onSuccess != null) onSuccess(apiResponse);
} else {
notifyListeners();
if (onError != null) {
onError(apiResponse.errorMessage ?? "Failed to load invoices");
}
}
},
);
}
void setSelectedInvoice(RefundInvoiceItem invoice) {
selectedInvoice = invoice;
procedures.clear();
notifyListeners();
}
void clearInvoice() {
selectedInvoice = null;
procedures.clear();
notifyListeners();
}
// Procedures
List<RefundableProcedure> procedures = [];
bool isProceduresLoading = false;
void setProcedures(List<RefundableProcedure> list) {
procedures = list;
isProceduresLoading = false;
notifyListeners();
}
void toggleProcedureSelection(RefundableProcedure procedure) {
procedure.isSelected = !procedure.isSelected;
notifyListeners();
}
List<RefundableProcedure> get selectedProcedures => procedures.where((p) => p.isSelected).toList();
// Calculation
double get totalRefundableAmount {
double total = 0.0;
for (final p in selectedProcedures) {
total += p.patientShare;
}
return total;
}
// Validation
bool get isStep1Valid => selectedHospital != null && selectedInvoice != null;
bool get isStep2Valid => selectedProcedures.isNotEmpty;
}

@ -1838,5 +1838,5 @@ abstract class LocaleKeys {
static const fileSizeExceedsLimit = 'fileSizeExceedsLimit';
static const completedPrescriptionOrder = 'completedPrescriptionOrder';
static const submitEReferral = 'submitEReferral';
static const requestRefund = 'requestRefund';
}

@ -10,17 +10,16 @@ import 'package:flutter/services.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/features/weather/weather_view_model.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/features/active_prescriptions/active_prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/features/ask_doctor/ask_doctor_view_model.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_view_model.dart';
import 'package:hmg_patient_app_new/features/active_prescriptions/active_prescriptions_view_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/contact_us/contact_us_view_model.dart';
import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.dart';
import 'package:hmg_patient_app_new/features/emergency_services/emergency_services_view_model.dart';
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart';
import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_view_model.dart';
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_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';
@ -39,22 +38,19 @@ import 'package:hmg_patient_app_new/features/prescriptions/prescriptions_view_mo
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_view_model.dart';
import 'package:hmg_patient_app_new/features/radiology/radiology_view_model.dart';
import 'package:hmg_patient_app_new/features/refund_request/refund_request_view_model.dart';
import 'package:hmg_patient_app_new/features/services_price_list/services_price_list_view_model.dart';
import 'package:hmg_patient_app_new/features/smartwatch_health_data/health_provider.dart';
import 'package:hmg_patient_app_new/features/symptoms_checker/symptoms_checker_view_model.dart';
import 'package:hmg_patient_app_new/features/todo_section/todo_section_view_model.dart';
import 'package:hmg_patient_app_new/features/translations/custom_asset_loader.dart';
import 'package:hmg_patient_app_new/features/translations/translation_service.dart';
import 'package:hmg_patient_app_new/features/water_monitor/water_monitor_view_model.dart';
import 'package:hmg_patient_app_new/features/weather/weather_view_model.dart';
import 'package:hmg_patient_app_new/presentation/health_calculators_and_converts/health_calculator_view_model.dart';
import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_view_model.dart';
import 'package:hmg_patient_app_new/routes/app_routes.dart';
import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart';
import 'package:hmg_patient_app_new/services/app_lifecycle_service.dart';
import 'package:hmg_patient_app_new/services/logger_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/theme/app_theme.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_calendar_model.dart';
import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart' show DateRangeSelectorRangeViewModel;
import 'package:provider/provider.dart';
@ -72,7 +68,6 @@ Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// flutter3_32 pub run easy_localization:generate -O ./lib/generated -f keys -o locale_keys.g.dart --source-dir ./assets/langs
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
@ -260,8 +255,12 @@ void main() async {
),
ChangeNotifierProvider<WeatherMonitorViewModel>(
create: (_) => getIt.get<WeatherMonitorViewModel>(),
), ChangeNotifierProvider<DateRangCalenderModel>(
),
ChangeNotifierProvider<DateRangCalenderModel>(
create: (_) => getIt.get<DateRangCalenderModel>(),
),
ChangeNotifierProvider<RefundRequestViewModel>(
create: (_) => getIt.get<RefundRequestViewModel>(),
)
], child: MyApp()),
), // Wrap your app

@ -11,8 +11,8 @@ import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_mode
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/habib_wallet/wallet_payment_confirm_page.dart';
import 'package:hmg_patient_app_new/presentation/habib_wallet/widgets/select_hospital_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
@ -44,7 +44,9 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
// Clear errors when entering recharge wallet page
WidgetsBinding.instance.addPostFrameCallback((_) {
habibWalletVM = context.read<HabibWalletViewModel>();
habibWalletVM.setDepositorDetails(appState.getAuthenticatedUser()!.patientId.toString(), "${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}",
habibWalletVM.setDepositorDetails(
appState.getAuthenticatedUser()!.patientId.toString(),
"${appState.getAuthenticatedUser()!.firstName} ${appState.getAuthenticatedUser()!.lastName}",
appState.getAuthenticatedUser()!.mobileNumber!);
habibWalletVM.setSelectedRechargeType(0);
habibWalletVM.getProjectsList();
@ -195,7 +197,8 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
children: [
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.my_account_icon, width: 40.h, height: 40.h, applyThemeColor: false),
Utils.buildSvgWithAssets(
icon: AppAssets.my_account_icon, width: 40.h, height: 40.h, applyThemeColor: false),
SizedBox(width: 8.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -215,7 +218,9 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
titleWidget: Consumer<HabibWalletViewModel>(builder: (context, habibWalletVM, child) {
return habibWalletVM.currentIndex != 0
? IconButton(
icon: Transform.flip(flipX: appState.isArabic(), child: Utils.buildSvgWithAssets(icon: AppAssets.arrow_back, width: 24.h, height: 24.h)),
icon: Transform.flip(
flipX: appState.isArabic(),
child: Utils.buildSvgWithAssets(icon: AppAssets.arrow_back, width: 24.h, height: 24.h)),
padding: EdgeInsets.zero,
onPressed: () => habibWalletVM.setCurrentIndex(0),
highlightColor: Colors.transparent,
@ -233,7 +238,8 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
children: [
Row(
children: [
Utils.buildSvgWithAssets(icon: AppAssets.select_hospital_icon, width: 40.h, height: 40.h, applyThemeColor: false),
Utils.buildSvgWithAssets(
icon: AppAssets.select_hospital_icon, width: 40.h, height: 40.h, applyThemeColor: false),
SizedBox(width: 8.h),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -241,7 +247,9 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
LocaleKeys.hospital.tr(context: context).toText12(color: AppColors.greyTextColor, isBold: true),
SizedBox(
width: MediaQuery.of(context).size.width * 0.55,
child: (habibWalletVM.selectedHospital != null ? habibWalletVM.selectedHospital!.name : LocaleKeys.selectHospital.tr(context: context))!
child: (habibWalletVM.selectedHospital != null
? habibWalletVM.selectedHospital!.name
: LocaleKeys.selectHospital.tr(context: context))!
.toText14(color: AppColors.textColor, isBold: true),
),
],
@ -252,7 +260,10 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
],
).onPress(() {
showCommonBottomSheetWithoutHeight(context,
title: LocaleKeys.selectHospital.tr(context: context), isDismissible: false, child: SelectHospitalBottomSheet(), callBackFunc: () {});
title: LocaleKeys.selectHospital.tr(context: context),
isDismissible: false,
child: SelectHospitalBottomSheet(),
callBackFunc: () {});
}),
// Show hospital error message if exists
if (habibWalletVM.hospitalError != null)
@ -277,7 +288,8 @@ class _RechargeWalletPageState extends State<RechargeWalletPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.email.tr(context: context).toText12(color: AppColors.greyTextColor, isBold: true),
"${appState.getAuthenticatedUser()!.emailAddress}".toText14(color: AppColors.textColor, isBold: true, letterSpacing: -0.2, isEnglishOnly: true),
"${appState.getAuthenticatedUser()!.emailAddress}"
.toText14(color: AppColors.textColor, isBold: true, letterSpacing: -0.2, isEnglishOnly: true),
],
),
],

File diff suppressed because one or more lines are too long

@ -40,9 +40,6 @@ import 'package:hmg_patient_app_new/presentation/appointments/widgets/ask_doctor
import 'package:hmg_patient_app_new/presentation/book_appointment/book_appointment_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_profile_page.dart';
import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.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/home/navigation_screen.dart';
import 'package:hmg_patient_app_new/presentation/insurance/insurance_approvals_page.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';
@ -62,6 +59,7 @@ import 'package:hmg_patient_app_new/presentation/my_invoices/my_invoices_list.da
import 'package:hmg_patient_app_new/presentation/prescriptions/prescriptions_list_page.dart';
import 'package:hmg_patient_app_new/presentation/radiology/radiology_orders_page.dart';
import 'package:hmg_patient_app_new/presentation/todo_section/todo_page.dart';
import 'package:hmg_patient_app_new/presentation/refund_request/refund_request_create_page.dart';
import 'package:hmg_patient_app_new/presentation/vital_sign/vital_sign_page.dart';
import 'package:hmg_patient_app_new/services/cache_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
@ -584,7 +582,6 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
)
: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.bgRedLightColor,
borderRadius: 12.r,
hasShadow: false,
),
@ -653,11 +650,7 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
isLargeText: true,
iconSize: 36.w,
).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
page: InsuranceApprovalsPage(),
),
);
Navigator.of(context).push(CustomPageRoute(page: InsuranceApprovalsPage()));
}),
MedicalFileCard(
label: LocaleKeys.myInvoicesList.tr(context: context),
@ -666,10 +659,20 @@ class _MedicalFilePageState extends State<MedicalFilePage> {
svgIcon: AppAssets.invoices_list_icon,
isLargeText: true,
iconSize: 36.w,
).onPress(() {
Navigator.of(context).push(CustomPageRoute(page: MyInvoicesList()));
}),
MedicalFileCard(
label: LocaleKeys.requestRefund.tr(context: context),
textColor: AppColors.blackColor,
backgroundColor: AppColors.whiteColor,
svgIcon: AppAssets.ancillary_orders_list_icon,
isLargeText: true,
iconSize: 36.w,
).onPress(() {
Navigator.of(context).push(
CustomPageRoute(
page: MyInvoicesList(),
page: const RefundRequestCreatePage(initialTabIndex: 0),
),
);
}),

@ -0,0 +1,442 @@
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/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/habib_wallet/habib_wallet_view_model.dart';
import 'package:hmg_patient_app_new/features/refund_request/refund_request_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/refund_request/widgets/select_hospital_bottom_sheet_refund.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart';
import 'package:hmg_patient_app_new/widgets/stepper/stepper_widget.dart';
import 'package:provider/provider.dart';
class RefundRequestCreatePage extends StatefulWidget {
/// 0 = Invoices (default), 1 = HMG Wallet
final int initialTabIndex;
const RefundRequestCreatePage({super.key, this.initialTabIndex = 0});
@override
State<RefundRequestCreatePage> createState() => _RefundRequestCreatePageState();
}
class _RefundRequestCreatePageState extends State<RefundRequestCreatePage> {
late RefundRequestViewModel _vm;
late HabibWalletViewModel _habibWalletVM;
late AppState _appState;
// TODO: Replace with actual procedure list fetched from API per invoice
List<RefundableProcedure> _mockProceduresForInvoice(int invoiceNo) => [
RefundableProcedure(procedureId: 101, procedureName: 'Consultation', procedureNameN: 'استشارة', patientShare: 120.0),
RefundableProcedure(procedureId: 102, procedureName: 'Blood Test CBC', procedureNameN: 'تحليل دم شامل', patientShare: 85.50),
RefundableProcedure(procedureId: 103, procedureName: 'X-Ray Chest', procedureNameN: 'أشعة سينية صدر', patientShare: 200.0),
RefundableProcedure(procedureId: 104, procedureName: 'ECG', procedureNameN: 'تخطيط قلب', patientShare: 150.0),
];
@override
void initState() {
super.initState();
_appState = getIt.get<AppState>();
WidgetsBinding.instance.addPostFrameCallback((_) {
// Load hospital list the same way RechargeWalletPage does
_habibWalletVM.getProjectsList();
});
}
// Stepper
Widget _buildStepper(RefundRequestViewModel vm) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 24.w),
child: LayoutBuilder(
builder: (context, constraints) {
// StepperWidget appends SizedBox(width: 8.h) after itself
final itemWidth = (constraints.maxWidth - 2 * 8.h) / 2;
return Row(
children: List.generate(2, (index) {
final isActive = index <= vm.currentStep;
final isThumb = index == vm.currentStep;
return StepperWidget(
itemWidth,
isActive ? AppColors.primaryRedColor : AppColors.greyColor,
isThumb,
4.h,
);
}),
);
},
),
);
}
// Step 1 exactly mirrors RechargeWalletPage hospital row
Widget _buildStep1Content(RefundRequestViewModel vm) {
final isArabic = _appState.isArabic();
return Consumer<RefundRequestViewModel>(
builder: (context, refundVM, _) {
return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.r),
child: Padding(
padding: EdgeInsets.all(16.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Utils.buildSvgWithAssets(
icon: AppAssets.select_hospital_icon,
width: 40.h,
height: 40.h,
applyThemeColor: false,
),
SizedBox(width: 8.h),
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
LocaleKeys.hospital.tr(context: context).toText12(color: AppColors.greyTextColor, isBold: true),
(refundVM.selectedHospital != null
? ((isArabic
? (refundVM.selectedHospital!.nameN?.toString() ?? refundVM.selectedHospital!.name)
: refundVM.selectedHospital!.name) ??
LocaleKeys.selectHospital.tr(context: context))
: LocaleKeys.selectHospital.tr(context: context))
.toText14(color: AppColors.textColor, isBold: true),
]),
],
),
Utils.buildSvgWithAssets(
icon: AppAssets.arrow_down,
width: 25.h,
height: 25.h,
),
],
).onPress(() {
showCommonBottomSheetWithoutHeight(
context,
title: LocaleKeys.selectHospital.tr(context: context),
isDismissible: false,
child: SelectHospitalBottomSheetRefund(),
callBackFunc: () {},
);
}),
),
);
},
);
}
// Step 2 procedure checkboxes
Widget _buildProcedureCard(RefundableProcedure procedure, int index) {
final isArabic = _appState.isArabic();
final name = isArabic && procedure.procedureNameN != null ? procedure.procedureNameN! : procedure.procedureName;
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 400),
child: SlideAnimation(
verticalOffset: 50.0,
child: FadeInAnimation(
child: AnimatedContainer(
duration: const Duration(milliseconds: 250),
curve: Curves.easeInOut,
margin: EdgeInsets.only(bottom: 12.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: procedure.isSelected ? AppColors.primaryRedColor.withAlpha(12) : AppColors.whiteColor,
borderRadius: 16.h,
hasShadow: true,
),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () => _vm.toggleProcedureSelection(procedure),
borderRadius: BorderRadius.circular(16.h),
child: Padding(
padding: EdgeInsets.all(14.h),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Checkbox(
value: procedure.isSelected,
onChanged: (_) => _vm.toggleProcedureSelection(procedure),
activeColor: AppColors.primaryRedColor,
side: BorderSide(color: AppColors.checkBoxBorderColor, width: 1.5),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity.compact,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4.r),
),
),
SizedBox(width: 8.w),
Expanded(child: name.toText14(isBold: true)),
SizedBox(width: 8.w),
Utils.getPaymentAmountWithSymbol(
procedure.patientShare.toStringAsFixed(2).toText14(
isBold: true,
isEnglishOnly: true,
color: AppColors.primaryRedColor,
),
AppColors.textColorLight,
13,
isSaudiCurrency: true,
),
],
),
),
),
),
),
),
),
);
}
Widget _buildStep2Content(RefundRequestViewModel vm) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 24.w),
child: Text(
'Select Procedures',
style: TextStyle(
fontSize: 20.f,
fontWeight: FontWeight.w600,
color: AppColors.blackColor,
letterSpacing: -0.5,
),
),
),
SizedBox(height: 24.h),
if (vm.isProceduresLoading)
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: EdgeInsets.symmetric(horizontal: 24.w),
itemCount: 4,
itemBuilder: (_, index) => Container(
height: 56.h,
margin: EdgeInsets.only(bottom: 12.h),
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 16.h,
),
).toShimmer2(isShow: true, radius: 16.r),
)
else if (vm.procedures.isEmpty)
Center(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 24.h),
child: 'No procedures available for refund'.toText14(color: AppColors.greyTextColor),
),
)
else
AnimationLimiter(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.w),
child: Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.bgScaffoldColor,
borderRadius: 24.h,
hasShadow: false,
),
padding: EdgeInsets.all(12.w),
child: Column(
children: List.generate(
vm.procedures.length,
(index) => _buildProcedureCard(vm.procedures[index], index),
),
),
),
),
),
],
);
}
// Bottom bar
Widget _buildBottomBar(RefundRequestViewModel vm) {
final isStep2 = vm.currentStep == 1;
final isWallet = vm.selectedTab == RefundTabType.hmgWallet;
return Container(
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.r,
hasShadow: true,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (isStep2 && !isWallet && vm.selectedProcedures.isNotEmpty) ...[
Padding(
padding: EdgeInsets.fromLTRB(24.w, 16.h, 24.w, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
'Total Refundable Amount'.toText12(
color: AppColors.textColorLight,
isBold: true,
),
Utils.getPaymentAmountWithSymbol(
vm.totalRefundableAmount.toStringAsFixed(2).toText18(
isBold: true,
isEnglishOnly: true,
color: AppColors.primaryRedColor,
),
AppColors.textColorLight,
14,
isSaudiCurrency: true,
),
],
),
),
],
CustomButton(
text: isStep2 ? LocaleKeys.submit.tr(context: context) : LocaleKeys.next.tr(context: context),
onPressed: () {
if (!isStep2) {
if (isWallet || vm.isStep1Valid) vm.nextStep();
} else {
// TODO: Submit API call
}
},
isDisabled: (!isWallet && !isStep2 && !vm.isStep1Valid) || (isStep2 && !isWallet && !vm.isStep2Valid),
).paddingSymmetrical(24.h, 24.h),
],
),
);
}
// HMG Wallet placeholder
Widget _buildHmgWalletContent() {
return KeyedSubtree(
key: const ValueKey('hmgWallet'),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.w),
child: Container(
width: double.infinity,
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
color: AppColors.whiteColor,
borderRadius: 24.h,
hasShadow: true,
),
padding: EdgeInsets.all(24.w),
child: Column(
children: [
Utils.buildSvgWithAssets(
icon: AppAssets.wallet,
iconColor: AppColors.primaryRedColor,
width: 48.h,
height: 48.h,
),
SizedBox(height: 16.h),
'HMG Wallet Refund'.toText16(isBold: true),
SizedBox(height: 8.h),
'Refund requests to HMG Wallet will be processed within 1-3 business days.'.toText14(color: AppColors.greyTextColor, isCenter: true),
],
),
),
),
);
}
// Build
@override
Widget build(BuildContext context) {
_habibWalletVM = context.read<HabibWalletViewModel>();
return Consumer<RefundRequestViewModel>(
builder: (context, vm, _) {
_vm = vm;
return Scaffold(
backgroundColor: AppColors.bgScaffoldColor,
body: Column(
children: [
Expanded(
child: CollapsingListView(
title: LocaleKeys.requestRefund.tr(context: context),
history: () async {
// TODO: Navigate to refund history page
},
child: SingleChildScrollView(
padding: EdgeInsets.only(bottom: 32.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Tab bar
Padding(
padding: EdgeInsets.symmetric(horizontal: 24.w),
child: CustomTabBar(
initialIndex: widget.initialTabIndex,
activeTextColor: AppColors.primaryRedColor,
activeBackgroundColor: AppColors.primaryRedColor.withAlpha(25),
tabs: [
CustomTabBarModel(null, 'Invoices'),
CustomTabBarModel(null, 'HMG Wallet'),
],
onTabChange: (index) {
vm.setTab(index == 0 ? RefundTabType.invoices : RefundTabType.hmgWallet);
vm.goToStep(0);
},
),
),
SizedBox(height: 24.h),
// Stepper (invoices tab only)
if (vm.selectedTab == RefundTabType.invoices) ...[
_buildStepper(vm),
SizedBox(height: 24.h),
],
// Content
AnimatedSwitcher(
duration: const Duration(milliseconds: 350),
transitionBuilder: (child, animation) => FadeTransition(
opacity: animation,
child: SlideTransition(
position: Tween<Offset>(
begin: const Offset(0.05, 0),
end: Offset.zero,
).animate(animation),
child: child,
),
),
child: vm.selectedTab == RefundTabType.hmgWallet
? _buildHmgWalletContent()
: vm.currentStep == 0
? KeyedSubtree(
key: const ValueKey('step1'),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.w),
child: _buildStep1Content(vm),
),
)
: KeyedSubtree(
key: const ValueKey('step2'),
child: _buildStep2Content(vm),
),
),
],
),
),
),
),
_buildBottomBar(vm),
],
),
);
},
);
}
}

@ -0,0 +1,223 @@
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/location_util.dart';
import 'package:hmg_patient_app_new/core/utils/doctor_response_mapper.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/habib_wallet/habib_wallet_view_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/features/refund_request/refund_request_view_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/presentation/habib_wallet/widgets/hospital_list_item.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
class SelectHospitalBottomSheetRefund extends StatefulWidget {
const SelectHospitalBottomSheetRefund({super.key});
@override
State<SelectHospitalBottomSheetRefund> createState() =>
_SelectHospitalBottomSheetRefundState();
}
class _SelectHospitalBottomSheetRefundState
extends State<SelectHospitalBottomSheetRefund> {
late RefundRequestViewModel refundVM;
late HabibWalletViewModel habibWalletVM;
bool sortByLocation = false;
bool isLoading = false;
List<HospitalsModel> displayList = [];
@override
void initState() {
super.initState();
final appState = getIt.get<AppState>();
sortByLocation = (appState.userLat != 0.0) && (appState.userLong != 0.0);
WidgetsBinding.instance.addPostFrameCallback((_) {
_updateDisplayList();
});
}
void _updateDisplayList() {
final appState = getIt.get<AppState>();
// Reuse the same hospital list already loaded in HabibWalletViewModel
final hospitals = List<HospitalsModel>.from(habibWalletVM.advancePaymentHospitals);
if (sortByLocation && appState.userLat != 0.0 && appState.userLong != 0.0) {
hospitals.sort((a, b) {
final distA = (a.latitude != null && a.longitude != null)
? DoctorMapper.calculateDistance(appState.userLat, appState.userLong,
double.parse(a.latitude!), double.parse(a.longitude!))
: double.infinity;
final distB = (b.latitude != null && b.longitude != null)
? DoctorMapper.calculateDistance(appState.userLat, appState.userLong,
double.parse(b.latitude!), double.parse(b.longitude!))
: double.infinity;
return distA.compareTo(distB);
});
}
setState(() {
displayList = hospitals;
isLoading = false;
});
}
void _refreshHospitalListAfterApi() {
void listener() {
if (habibWalletVM.advancePaymentHospitals.isNotEmpty) {
habibWalletVM.removeListener(listener);
_updateDisplayList();
}
}
habibWalletVM.addListener(listener);
habibWalletVM.getProjectsList();
}
void _handleSortByLocationToggle(bool value) {
if (value) {
final locationUtils = getIt.get<LocationUtils>();
locationUtils.getLocation(
isShowConfirmDialog: true,
onSuccess: (latLng) {
setState(() {
sortByLocation = true;
isLoading = true;
});
_refreshHospitalListAfterApi();
},
onFailure: () {
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: context),
context,
child: Utils.getWarningWidget(
loadingText: LocaleKeys.giveLocationPermissionForNearestList
.tr(context: context),
isShowActionButtons: true,
onCancelTap: () => Navigator.of(context).pop(),
onConfirmTap: () async {
Navigator.of(context).pop();
openAppSettings();
},
),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
setState(() => sortByLocation = false);
},
onLocationDeniedForever: () {
showCommonBottomSheetWithoutHeight(
title: LocaleKeys.notice.tr(context: context),
context,
child: Utils.getWarningWidget(
loadingText: LocaleKeys.giveLocationPermissionForNearestList
.tr(context: context),
isShowActionButtons: true,
onCancelTap: () => Navigator.of(context).pop(),
onConfirmTap: () async {
Navigator.of(context).pop();
openAppSettings();
},
),
callBackFunc: () {},
isFullScreen: false,
isCloseButtonVisible: true,
);
setState(() => sortByLocation = false);
},
);
} else {
final appState = getIt.get<AppState>();
appState.resetLocation();
setState(() {
sortByLocation = false;
isLoading = true;
});
_refreshHospitalListAfterApi();
}
}
@override
Widget build(BuildContext context) {
refundVM = context.read<RefundRequestViewModel>();
habibWalletVM = context.read<HabibWalletViewModel>();
if (displayList.isEmpty && habibWalletVM.advancePaymentHospitals.isNotEmpty) {
displayList = List.from(habibWalletVM.advancePaymentHospitals);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.selectHospitalForAdvancePayment
.tr(context: context)
.toText16(color: AppColors.greyTextColor, isBold: true),
SizedBox(height: 16.h),
Padding(
padding: EdgeInsets.symmetric(horizontal: 4.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Utils.buildSvgWithAssets(
icon: AppAssets.location,
iconColor: AppColors.greyTextColor,
width: 18.h,
height: 18.h),
SizedBox(width: 8.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.sortByLocation.tr(context: context).toText14(isBold: true),
LocaleKeys.sortByNearestLocation
.tr(context: context)
.toText11(color: AppColors.textColorLight, isBold: true),
],
),
],
),
Switch(
value: sortByLocation,
onChanged: _handleSortByLocationToggle,
activeThumbColor: AppColors.successColor,
activeTrackColor: AppColors.successColor.withValues(alpha: 0.15),
),
],
),
),
SizedBox(height: 8.h),
isLoading
? SizedBox(
height: MediaQuery.sizeOf(context).height * .4,
child: Center(child: Utils.getLoadingWidget()),
)
: SizedBox(
height: MediaQuery.sizeOf(context).height * .4,
child: ListView.separated(
itemCount: displayList.length,
separatorBuilder: (_, __) => SizedBox(height: 16.h),
itemBuilder: (_, index) {
return HospitalListItemAdvancePayment(
hospitalModel: displayList[index],
isLocationEnabled: sortByLocation,
).onPress(() {
refundVM.setSelectedHospital(displayList[index]);
Navigator.of(context).pop();
});
},
),
),
],
);
}
}

@ -41,7 +41,8 @@ import '../core/dependencies.dart';
import '../features/monthly_reports/monthly_reports_repo.dart';
import '../features/monthly_reports/monthly_reports_view_model.dart';
import '../features/qr_parking/qr_parking_view_model.dart';
import '../presentation/parking/paking_page.dart';
import 'package:hmg_patient_app_new/presentation/parking/paking_page.dart';
import 'package:hmg_patient_app_new/presentation/refund_request/refund_request_create_page.dart';
import '../services/error_handler_service.dart';
class AppRoutes {
@ -101,6 +102,9 @@ class AppRoutes {
// Weather
static const String familyFilesPage = '/familyFilesPage';
// Refund Request
static const String refundRequestCreatePage = '/refundRequestCreatePage';
static Map<String, WidgetBuilder> get routes => {
initialRoute: (context) => SplashPage(),
loginScreen: (context) => LoginScreen(),
@ -160,6 +164,10 @@ class AppRoutes {
qrParking: (context) => ChangeNotifierProvider<QrParkingViewModel>(
create: (_) => getIt<QrParkingViewModel>(),
child: const ParkingPage(),
)
),
refundRequestCreatePage: (context) {
final args = ModalRoute.of(context)?.settings.arguments as int?;
return RefundRequestCreatePage(initialTabIndex: args ?? 0);
},
};
}

@ -1042,13 +1042,13 @@ packages:
source: hosted
version: "1.2.1"
image_picker_android:
dependency: transitive
dependency: "direct main"
description:
name: image_picker_android
sha256: "5e9bf126c37c117cf8094215373c6d561117a3cfb50ebc5add1a61dc6e224677"
sha256: d5b3e1774af29c9ab00103afb0d4614070f924d2e0057ac867ec98800114793f
url: "https://pub.dev"
source: hosted
version: "0.8.13+10"
version: "0.8.13+17"
image_picker_for_web:
dependency: transitive
description:
@ -1082,7 +1082,7 @@ packages:
source: hosted
version: "0.2.2+1"
image_picker_platform_interface:
dependency: transitive
dependency: "direct main"
description:
name: image_picker_platform_interface
sha256: "567e056716333a1647c64bb6bd873cff7622233a5c3f694be28a583d4715690c"

Loading…
Cancel
Save