diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/100.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/100.png new file mode 100644 index 0000000..c58db45 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/100.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/1024.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/1024.png new file mode 100644 index 0000000..4598286 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/1024.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/114.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/114.png new file mode 100644 index 0000000..c32a2d5 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/114.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/120.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/120.png new file mode 100644 index 0000000..96ebea5 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/120.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/144.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/144.png new file mode 100644 index 0000000..bc29e15 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/144.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/152.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/152.png new file mode 100644 index 0000000..8412a82 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/152.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/167.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/167.png new file mode 100644 index 0000000..8d4dba1 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/167.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/180.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/180.png new file mode 100644 index 0000000..44b2a86 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/180.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/20.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/20.png new file mode 100644 index 0000000..26b9d99 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/20.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/29.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/29.png new file mode 100644 index 0000000..965753e Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/29.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/40.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/40.png new file mode 100644 index 0000000..8f553ae Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/40.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/50.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/50.png new file mode 100644 index 0000000..d100f81 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/50.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/57.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/57.png new file mode 100644 index 0000000..744aa3b Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/57.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/58.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/58.png new file mode 100644 index 0000000..4487359 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/58.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/60.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/60.png new file mode 100644 index 0000000..60de135 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/60.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/72.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/72.png new file mode 100644 index 0000000..7586d12 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/72.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/76.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/76.png new file mode 100644 index 0000000..f569188 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/76.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/80.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/80.png new file mode 100644 index 0000000..340d82b Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/80.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/87.png b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/87.png new file mode 100644 index 0000000..4e75166 Binary files /dev/null and b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/87.png differ diff --git a/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..65b74d7 --- /dev/null +++ b/AppIcons_NewApp/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +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/AppIcons_NewApp/appstore.png b/AppIcons_NewApp/appstore.png new file mode 100644 index 0000000..4598286 Binary files /dev/null and b/AppIcons_NewApp/appstore.png differ diff --git a/AppIcons_NewApp/playstore.png b/AppIcons_NewApp/playstore.png new file mode 100644 index 0000000..a1da25a Binary files /dev/null and b/AppIcons_NewApp/playstore.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4..0000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_local.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_local.png index 348b511..06095ae 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_local.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_local.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b7..0000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_local.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_local.png index 410b1b1..cb15fb6 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_local.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_local.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 09d4391..0000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_local.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_local.png index bb9943a..b5d6eb9 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_local.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_local.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d..0000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_local.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_local.png index 0b9d935..3774c26 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_local.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_local.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372e..0000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_local.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_local.png index aaa9808..a211290 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_local.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_local.png differ diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 76e10ea..69a3357 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -488,7 +488,7 @@ "services2": "الخدمات", "cantSeeProfile": "لرؤية ملفك الطبي، يرجى تسجيل الدخول أو التسجيل الآن", "loginRegisterNow": "تسجيل الدخول أو التسجيل الآن", - "hmgPharmacy": "صيدلية HMG", + "hmgPharmacy": "صيدلية مجموعة الحبيب الطبية", "ecommerceSolution": "حلول التجارة الإلكترونية", "comprehensive": "شامل", "onlineConsulting": "استشارات عبر الإنترنت", @@ -666,7 +666,7 @@ "findUs": "اعثر علينا", "liveChat": "دردشة مباشرة", "service": "خدمة", - "hmgServiceLabel": "خدمة HMG", + "hmgServiceLabel": "خدمة مجموعة الحبيب الطبية", "healthWeatherIndicators": "مؤشرات الطقس الصحية", "healthTipsBasedOnCurrentWeather": "نصائح صحية بناءً على الطقس الحالي", "moreDetails": "المزيد من التفاصيل", @@ -717,10 +717,10 @@ "bloodDonationInfo": "من خلال هذه الخدمة، يمكنك تسجيل اسمك كمتبرع بالدم ��يث سيتواصل معك بنك الدم في مجموعة الحبيب الطبية في حالة الحاجة إلى فصيلة الدم.", "bloodInstruction": "أدخل المعلومات المطلوبة، من أجل التسجيل في خدمة التبرع بالدم", "viewTerms": "لعرض الشروط والأحكام", - "wantConnectHmgNetwork": "عزيزي العميل، لا يوجد وصول إلى الإنترنت، هل ترغب في الاتصال بشبكة HMG لاستخدام تطبيقنا، تأكد من أنك في نطاق شبكة HMG", - "failedToAccessHmgServices": "متصل بشبكة HMG،\n\nلكن فشل في الوصول إلى خدمات HMG", + "wantConnectHmgNetwork": "عزيزي العميل، لا يوجد وصول إلى الإنترنت، هل ترغب في الاتصال بشبكة مجموعة الحبيب الطبية لاستخدام تطبيقنا، تأكد من أنك في نطاق شبكة مجموعة الحبيب الطبية", + "failedToAccessHmgServices": "متصل بشبكة مجموعة الحبيب الطبية،\n\nلكن فشل في الوصول إلى خدمات مجموعة الحبيب الطبية", "offerAndPackages": "عروض وباقات", - "offerAndPackagesDetails": "تتيح لك هذه الخدمة عرض جميع عروض HMG:", + "offerAndPackagesDetails": "تتيح لك هذه الخدمة عرض جميع عروض مجموعة الحبيب الطبية:", "invoiceNo": "رقم الفاتورة", "invoiceDate": "تاريخ الفاتورة", "specialResult": "نتيجة خاصة", @@ -853,8 +853,8 @@ "onboardingBody1": "ببضع نقرات فقط يمكنك استشارة الطبيب الذي تختاره.", "onboardingHeading2": "الوصول إلى السجل الطبي بين يديك", "onboardingBody2": "تتبع تاريخك الطبي بما في ذلك الفحوصات المخبرية، الوصفات الطبية، التأمين، وغيرها.", - "hmgHospitals": "مستشفيات HMG", - "hmcMedicalClinic": "مراكز HMC الطبية", + "hmgHospitals": "مستشفيات مجموعة الحبيب الطبية", + "hmcMedicalClinic": "مراكز مجموعة الحبيب الطبية", "applyFilter": "تطبيق الفلتر", "facilityAndLocation": "المرفق والموقع", "regionAndLocation": "المنطقة والمواقع", @@ -1581,5 +1581,6 @@ "reschedulingAppo": "إعادة جدولة الموعد، يرجى الانتظار...", "invalidEligibility": "لا يمكنك إجراء الدفع عبر الإنترنت لأنك غير مؤهل لاستخدام الخدمة المقدمة.", "invalidInsurance": "لا يمكنك إجراء الدفع عبر الإنترنت لأنه ليس لديك تأمين صالح.", - "continueCash": "تواصل نقدا" + "continueCash": "تواصل نقدا", + "hmgPolicies": "سياسات مجموعة الحبيب الطبية" } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index bf73d6d..8910883 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1572,5 +1572,6 @@ "reschedulingAppo": "Rescheduling Appointment, Please wait...", "invalidEligibility": "You cannot make online payment because you are not eligible to use the provided service.", "invalidInsurance": "You cannot make online payment because you do not have a valid insurance.", - "continueCash": "Continue as cash" + "continueCash": "Continue as cash", + "hmgPolicies": "HMG Policies" } diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 970b1e4..e706a9d 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -194,12 +194,14 @@ class ApiClientImp implements ApiClient { body['TokenID'] = "@dm!n"; } - // body['TokenID'] = "@dm!n"; - // body['PatientID'] = 4773715; + body['TokenID'] = "@dm!n"; + body['PatientID'] = 4773781; // body['PatientTypeID'] = 1; // body['PatientOutSA'] = 0; // body['SessionID'] = "45786230487560q"; + //VIP Patient: 1181868 + // body['IdentificationNo'] = "2235558844"; // body['MobileNo'] = "966533147722"; // body['PatientID'] = 809289; diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index a57169d..708324e 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -229,7 +229,7 @@ class ApiConsts { static String getAiOverViewLabOrder = "Services/Patients.svc/REST/HMGAI_Lab_Analyzer_API"; // ************ static values for Api **************** - static final double appVersionID = 19.7; + static final double appVersionID = 19.8; // static final double appVersionID = 50.7; static final int appChannelId = 3; static final String appIpAddress = "10.20.10.20"; @@ -916,6 +916,8 @@ var GET_PRESCRIPTION_INSTRUCTIONS_PDF = 'Services/ChatBot_Service.svc/REST/Chatb const DASHBOARD = 'Services/Patients.svc/REST/PatientDashboard'; +const SEND_PATIENT_IMMEDIATE_UPDATE_INSURANCE_REQUEST = 'Services/OUTPs.svc/REST/PatientCompanyUpdate'; + class ApiKeyConstants { static final String googleMapsApiKey = 'AIzaSyB6TERnxIr0yJ3qG4ULBZbu0sAD4tGqtng'; } diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index 70f10bb..58754dc 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -161,15 +161,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: const Color(0xff000000).withOpacity(.05), + // blurRadius: 32, + // offset: const Offset(0, 0), + // ) + // ] + // : + [], ); } } diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart index c6c5faf..3132dc8 100644 --- a/lib/features/book_appointments/book_appointments_view_model.dart +++ b/lib/features/book_appointments/book_appointments_view_model.dart @@ -464,7 +464,11 @@ class BookAppointmentsViewModel extends ChangeNotifier { final result = await bookAppointmentsRepo.getLiveCareScheduleClinics(_appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!); result.fold( - (failure) async => await errorHandlerService.handleError(failure: failure), + // (failure) async => await errorHandlerService.handleError(failure: failure), + (failure) async { + isClinicsListLoading = false; + notifyListeners(); + }, (apiResponse) { if (apiResponse.messageStatus == 2) { // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); diff --git a/lib/features/emergency_services/emergency_services_repo.dart b/lib/features/emergency_services/emergency_services_repo.dart index c63f0ee..f8eb896 100644 --- a/lib/features/emergency_services/emergency_services_repo.dart +++ b/lib/features/emergency_services/emergency_services_repo.dart @@ -183,7 +183,7 @@ class EmergencyServicesRepoImp implements EmergencyServicesRepo { @override Future>>> getProjectList() async { - Map request = {}; + Map request = {'IsOnlineCheckIn': false, 'IsAdvancePayment': false, 'IsForER': true}; try { GenericApiModel>? apiResponse; diff --git a/lib/features/immediate_livecare/immediate_livecare_repo.dart b/lib/features/immediate_livecare/immediate_livecare_repo.dart index eee4adb..cbce4ea 100644 --- a/lib/features/immediate_livecare/immediate_livecare_repo.dart +++ b/lib/features/immediate_livecare/immediate_livecare_repo.dart @@ -89,7 +89,7 @@ class ImmediateLiveCareRepoImp implements ImmediateLiveCareRepo { body: mapDevice, onFailure: (error, statusCode, {messageStatus, failureType}) { failure = failureType; - onError!(error); + // onError!(error); }, onSuccess: (response, statusCode, {messageStatus, errorMessage}) { try { @@ -142,7 +142,7 @@ class ImmediateLiveCareRepoImp implements ImmediateLiveCareRepo { body: mapDevice, onFailure: (error, statusCode, {messageStatus, failureType}) { failure = failureType; - onError!(error); + // onError!(error); }, onSuccess: (response, statusCode, {messageStatus, errorMessage}) { try { diff --git a/lib/features/immediate_livecare/immediate_livecare_view_model.dart b/lib/features/immediate_livecare/immediate_livecare_view_model.dart index 90bf9a0..46f5a65 100644 --- a/lib/features/immediate_livecare/immediate_livecare_view_model.dart +++ b/lib/features/immediate_livecare/immediate_livecare_view_model.dart @@ -174,13 +174,21 @@ class ImmediateLiveCareViewModel extends ChangeNotifier { }, onConfirmTap: () async { Navigator.pop(GetIt.instance().navigatorKey.currentContext!); - Navigator.pop(GetIt.instance().navigatorKey.currentContext!); - Navigator.push( - GetIt.instance().navigatorKey.currentContext!, - CustomPageRoute( - page: InsuranceHomePage(), - ), - ); + + //Call the API to attempt updating patient insurance + LoaderBottomSheet.showLoader(); + myAppointmentsViewModel.sendPatientUpdateRequest(onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + getLiveCareImmediateAppointmentFees(); + }, onError: (err) { + LoaderBottomSheet.hideLoader(); + Navigator.push( + GetIt.instance().navigatorKey.currentContext!, + CustomPageRoute( + page: InsuranceHomePage(), + ), + ); + }); }), ), callBackFunc: () { // Navigator.pop(GetIt.instance().navigatorKey.currentContext!); diff --git a/lib/features/insurance/models/resp_models/patient_insurance_approval_response_model.dart b/lib/features/insurance/models/resp_models/patient_insurance_approval_response_model.dart index f272f2d..303b6ed 100644 --- a/lib/features/insurance/models/resp_models/patient_insurance_approval_response_model.dart +++ b/lib/features/insurance/models/resp_models/patient_insurance_approval_response_model.dart @@ -52,7 +52,7 @@ class InsuranceApprovalResponseModel { String? eApprovalRemarks; bool? isEmailSentOnDelayApproval; int? eAuthorizationID; - InsuranceApprovalDetails? apporvalDetails; + List? apporvalDetails = []; String? approvalStatusDescption; String? clinicName; String? clinicNameN; @@ -217,7 +217,9 @@ class InsuranceApprovalResponseModel { isEmailSentOnDelayApproval = json['IsEmailSentOnDelayApproval']; eAuthorizationID = json['EAuthorizationID']; if (json['ApporvalDetails'] != null && json['ApporvalDetails'].length != 0) { - apporvalDetails = InsuranceApprovalDetails.fromJson(json['ApporvalDetails'][0]); + json['ApporvalDetails'].forEach((v) { + apporvalDetails!.add(InsuranceApprovalDetails.fromJson(v)); + }); } approvalStatusDescption = json['ApprovalStatusDescption']; clinicName = json['ClinicName']; @@ -302,9 +304,9 @@ class InsuranceApprovalResponseModel { data['EApprovalRemarks'] = this.eApprovalRemarks; data['IsEmailSentOnDelayApproval'] = this.isEmailSentOnDelayApproval; data['EAuthorizationID'] = this.eAuthorizationID; - if (this.apporvalDetails != null) { - data['ApporvalDetails'] = this.apporvalDetails!.toJson; - } + // if (this.apporvalDetails != null) { + // data['ApporvalDetails'] = this.apporvalDetails!.toJson; + // } data['ApprovalStatusDescption'] = this.approvalStatusDescption; data['ClinicName'] = this.clinicName; data['ClinicNameN'] = this.clinicNameN; diff --git a/lib/features/lab/lab_repo.dart b/lib/features/lab/lab_repo.dart index a4cdcf1..285c732 100644 --- a/lib/features/lab/lab_repo.dart +++ b/lib/features/lab/lab_repo.dart @@ -232,7 +232,7 @@ class LabRepoImp implements LabRepo { "DoctorID": labOrder.doctorID!, "OrderNo": labOrder.orderNo!, "InvoiceType": labOrder.invoiceType!, - "SetupID": labOrder.setupID!, + "SetupID": labOrder.setupID ?? "", "IsDownload": true, 'ClinicName': labOrder.clinicDescription, 'DateofBirth': Utils.appState.getAuthenticatedUser()!.dateofBirth, diff --git a/lib/features/lab/lab_view_model.dart b/lib/features/lab/lab_view_model.dart index efb1c06..cd062b9 100644 --- a/lib/features/lab/lab_view_model.dart +++ b/lib/features/lab/lab_view_model.dart @@ -205,14 +205,36 @@ class LabViewModel extends ChangeNotifier { } filterLabReports(String query) { + final clinicMap = >{}; + final hospitalMap = >{}; if (query.isEmpty) { - filteredLabOrders = List.from(patientLabOrders); // reset + // filteredLabOrders = List.from(patientLabOrders); // reset + 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; } else { filteredLabOrders = patientLabOrders.where((order) { final descriptions = order.testDetails?.map((d) => d.description?.toLowerCase()).toList() ?? []; return descriptions.any((desc) => desc != null && desc.contains(query.toLowerCase())); }).toList(); - patientLabOrders = filteredLabOrders; + // patientLabOrders = filteredLabOrders; + for (var order in filteredLabOrders) { + 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; } notifyListeners(); } diff --git a/lib/features/lab/models/resp_models/lab_result.dart b/lib/features/lab/models/resp_models/lab_result.dart index 2314684..2808dce 100644 --- a/lib/features/lab/models/resp_models/lab_result.dart +++ b/lib/features/lab/models/resp_models/lab_result.dart @@ -27,6 +27,7 @@ class LabResult { num? resultTypeID; String? packageShortDescription; int? testId; + String? testShortDescription; LabResult( {this.description, @@ -54,6 +55,7 @@ class LabResult { this.criticalLow, this.referenceLow, this.testId, + this.testShortDescription, }); LabResult.fromJson(Map json) { @@ -85,6 +87,7 @@ class LabResult { packageShortDescription = json['PackageShortDescription']; resultTypeID = json['ResultTypeID']; testId = json['TestID']; + testShortDescription = json['TestShortDescription']; } Map toJson() { @@ -114,6 +117,7 @@ class LabResult { data['CriticalLow'] = this.criticalLow; data['ReferenceLow'] = this.referenceLow; data['TestID'] = this.testId; + data['TestShortDescription'] = this.testShortDescription; return data; } diff --git a/lib/features/medical_file/medical_file_view_model.dart b/lib/features/medical_file/medical_file_view_model.dart index 9e50075..b93bb62 100644 --- a/lib/features/medical_file/medical_file_view_model.dart +++ b/lib/features/medical_file/medical_file_view_model.dart @@ -41,7 +41,7 @@ class MedicalFileViewModel extends ChangeNotifier { List patientSickLeavesViewList = []; bool isSickLeavesSortByClinic = true; - bool isSickLeavesDataNeedsReloading = true; + // bool isSickLeavesDataNeedsReloading = true; List patientAllergiesList = []; @@ -164,7 +164,7 @@ class MedicalFileViewModel extends ChangeNotifier { } setIsPatientSickLeaveListLoading(bool val) { - if (val && isSickLeavesDataNeedsReloading) { + // if (val && isSickLeavesDataNeedsReloading) { patientSickLeaveList.clear(); patientSickLeavesByClinic.clear(); patientSickLeavesByHospital.clear(); @@ -172,7 +172,7 @@ class MedicalFileViewModel extends ChangeNotifier { patientSickLeavePDFBase64 = ""; isSickLeavesSortByClinic = true; isPatientSickLeaveListLoading = val; - } + // } notifyListeners(); } @@ -268,11 +268,13 @@ class MedicalFileViewModel extends ChangeNotifier { } Future getPatientSickLeaveList({Function(dynamic)? onSuccess, Function(String)? onError}) async { - if (!isSickLeavesDataNeedsReloading) { - return; - } + // if (!isSickLeavesDataNeedsReloading) { + // return; + // } patientSickLeaveList.clear(); + notifyListeners(); + final result = await medicalFileRepo.getPatientSickLeavesList(); result.fold( @@ -314,7 +316,7 @@ class MedicalFileViewModel extends ChangeNotifier { } } patientSickLeavesViewList = patientSickLeavesByClinic; - isSickLeavesDataNeedsReloading = false; + // isSickLeavesDataNeedsReloading = false; notifyListeners(); if (onSuccess != null) { @@ -353,6 +355,11 @@ class MedicalFileViewModel extends ChangeNotifier { Future getPatientMedicalReportList({Function(dynamic)? onSuccess, Function(String)? onError}) async { patientMedicalReportList.clear(); + patientMedicalReportRequestedList.clear(); + patientMedicalReportReadyList.clear(); + patientMedicalReportCancelledList.clear(); + notifyListeners(); + final result = await medicalFileRepo.getPatientMedicalReportsList(); result.fold( diff --git a/lib/features/my_appointments/my_appointments_repo.dart b/lib/features/my_appointments/my_appointments_repo.dart index 0c76c9f..567714c 100644 --- a/lib/features/my_appointments/my_appointments_repo.dart +++ b/lib/features/my_appointments/my_appointments_repo.dart @@ -20,7 +20,8 @@ import 'models/req_model/appointment_rate_req_model.dart'; import 'models/resp_models/appointment_details_resp_model.dart'; abstract class MyAppointmentsRepo { - Future>>> getPatientAppointments({required bool isActiveAppointment, required bool isArrivedAppointments, bool isForEyeMeasurement = false}); + Future>>> getPatientAppointments( + {required bool isActiveAppointment, required bool isArrivedAppointments, bool isForEyeMeasurement = false}); Future>> getPatientShareAppointment( {required int projectID, required int clinicID, required String appointmentNo, required bool isLiveCareAppointment}); @@ -67,14 +68,16 @@ abstract class MyAppointmentsRepo { Future>> getAppointmentDetails(int appointmentID, int projectID); - Future>> sendAppointmentRate(int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note); - Future>> sendDoctorRate(int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note, String appoDate, String docName, String projectName, String clinicName); + Future>> sendDoctorRate( + int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note, String appoDate, String docName, String projectName, String clinicName); Future>>> getPatientAppointmentQueueDetails({required int appointmentNo, required int patientID}); Future>> convertPatientToCash({required int projectID}); + + Future>> sendPatientUpdateRequest(); } class MyAppointmentsRepoImp implements MyAppointmentsRepo { @@ -194,9 +197,7 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { "AppointmentNo": appointmentNo, "PaymentMethodName": paymentMethodName, "PaymentAmount": payedAmount == 0 ? "0" : payedAmount.toString(), - "PaymentDate": payedAmount == 0 ? "" : "/Date(${DateTime - .now() - .millisecondsSinceEpoch})/", + "PaymentDate": payedAmount == 0 ? "" : "/Date(${DateTime.now().millisecondsSinceEpoch})/", "PaymentReferenceNumber": payedAmount == 0 ? "" : paymentReference, "ProjectID": projectID, "PatientID": patientID, @@ -865,10 +866,8 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { } } - @override - Future>> sendAppointmentRate(int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note) async { - + Future>> sendAppointmentRate(int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note) async { AppointmentRate appointmentRate = AppointmentRate(); appointmentRate.rate = rate; appointmentRate.appointmentNo = appointmentNo; @@ -879,7 +878,6 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { appointmentRate.createdBy = 2; appointmentRate.editedBy = 2; - try { GenericApiModel? apiResponse; Failure? failure; @@ -908,7 +906,8 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { } @override - Future>> sendDoctorRate(int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note, String appoDate, String docName, String projectName, String clinicName) async { + Future>> sendDoctorRate( + int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note, String appoDate, String docName, String projectName, String clinicName) async { Map request; request = { @@ -991,4 +990,35 @@ class MyAppointmentsRepoImp implements MyAppointmentsRepo { return Left(UnknownFailure(e.toString())); } } -} \ No newline at end of file + + @override + Future> sendPatientUpdateRequest() async { + Map request = {}; + + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post(SEND_PATIENT_IMMEDIATE_UPDATE_INSURANCE_REQUEST, onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + final list = (response['MessageStatus'] == 1); + + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: list, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, body: request); + 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/my_appointments/my_appointments_view_model.dart b/lib/features/my_appointments/my_appointments_view_model.dart index 35bf29b..f887680 100644 --- a/lib/features/my_appointments/my_appointments_view_model.dart +++ b/lib/features/my_appointments/my_appointments_view_model.dart @@ -54,9 +54,6 @@ class MyAppointmentsViewModel extends ChangeNotifier { List patientQueueDetailsList = []; late PatientQueueDetails currentPatientQueueDetails; - - - List patientAppointmentsHistoryList = []; List filteredAppointmentList = []; @@ -344,10 +341,8 @@ class MyAppointmentsViewModel extends ChangeNotifier { notifyListeners(); } - Future getPatientShareAppointment(int projectID, int clinicID, String appointmentNo, bool isLiveCareAppointment, - {Function(dynamic)? onSuccess, Function(String)? onError}) async { - final result = await myAppointmentsRepo.getPatientShareAppointment( - projectID: projectID, clinicID: clinicID, appointmentNo: appointmentNo, isLiveCareAppointment: isLiveCareAppointment); + Future getPatientShareAppointment(int projectID, int clinicID, String appointmentNo, bool isLiveCareAppointment, {Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await myAppointmentsRepo.getPatientShareAppointment(projectID: projectID, clinicID: clinicID, appointmentNo: appointmentNo, isLiveCareAppointment: isLiveCareAppointment); result.fold( (failure) async { @@ -421,13 +416,23 @@ class MyAppointmentsViewModel extends ChangeNotifier { }, onConfirmTap: () async { Navigator.pop(GetIt.instance().navigatorKey.currentContext!); - Navigator.pop(GetIt.instance().navigatorKey.currentContext!); - Navigator.push( - GetIt.instance().navigatorKey.currentContext!, - CustomPageRoute( - page: InsuranceHomePage(), - ), - ); + + //Call the API to attempt updating patient insurance + LoaderBottomSheet.showLoader(); + sendPatientUpdateRequest(onSuccess: (val) { + LoaderBottomSheet.hideLoader(); + setIsPatientAppointmentShareLoading(true); + getPatientShareAppointment(projectID, clinicID, appointmentNo, isLiveCareAppointment); + }, onError: (err) { + LoaderBottomSheet.hideLoader(); + Navigator.pop(GetIt.instance().navigatorKey.currentContext!); + Navigator.push( + GetIt.instance().navigatorKey.currentContext!, + CustomPageRoute( + page: InsuranceHomePage(), + ), + ); + }); }), ), callBackFunc: () { // Navigator.pop(GetIt.instance().navigatorKey.currentContext!); @@ -443,6 +448,27 @@ class MyAppointmentsViewModel extends ChangeNotifier { ); } + Future sendPatientUpdateRequest({Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await myAppointmentsRepo.sendPatientUpdateRequest(); + + result.fold( + // (failure) async => await errorHandlerService.handleError(failure: failure), + (failure) async { + onError!(failure.message); + }, + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } + Future convertPatientToCash({required int projectID, Function(dynamic)? onSuccess, Function(String)? onError}) async { final result = await myAppointmentsRepo.convertPatientToCash(projectID: projectID); @@ -465,13 +491,8 @@ class MyAppointmentsViewModel extends ChangeNotifier { } Future addAdvanceNumberRequest( - {required String advanceNumber, - required String paymentReference, - required String appointmentNo, - Function(dynamic)? onSuccess, - Function(String)? onError}) async { - final result = - await myAppointmentsRepo.addAdvanceNumberRequest(advanceNumber: advanceNumber, paymentReference: paymentReference, appointmentNo: appointmentNo); + {required String advanceNumber, required String paymentReference, required String appointmentNo, Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await myAppointmentsRepo.addAdvanceNumberRequest(advanceNumber: advanceNumber, paymentReference: paymentReference, appointmentNo: appointmentNo); result.fold( (failure) async => await errorHandlerService.handleError(failure: failure), @@ -489,14 +510,8 @@ class MyAppointmentsViewModel extends ChangeNotifier { } Future generateAppointmentQR( - {required int clinicID, - required int projectID, - required String appointmentNo, - required int isFollowUp, - Function(dynamic)? onSuccess, - Function(String)? onError}) async { - final result = - await myAppointmentsRepo.generateAppointmentQR(clinicID: clinicID, projectID: projectID, appointmentNo: appointmentNo, isFollowUp: isFollowUp); + {required int clinicID, required int projectID, required String appointmentNo, required int isFollowUp, Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await myAppointmentsRepo.generateAppointmentQR(clinicID: clinicID, projectID: projectID, appointmentNo: appointmentNo, isFollowUp: isFollowUp); result.fold( (failure) async => await errorHandlerService.handleError(failure: failure), @@ -513,14 +528,13 @@ class MyAppointmentsViewModel extends ChangeNotifier { ); } - Future cancelAppointment( - {required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async { + Future cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async { final result = await myAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel); result.fold( // (failure) async => await errorHandlerService.handleError(failure: failure), (failure) async { - if(onError != null) { + if (onError != null) { onError(failure.message); } }, @@ -538,8 +552,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { ); } - Future confirmAppointment( - {required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async { + Future confirmAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async { final result = await myAppointmentsRepo.confirmAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel); result.fold( @@ -600,8 +613,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { required int checkInType, Function(dynamic)? onSuccess, Function(String)? onError}) async { - final result = await myAppointmentsRepo.sendCheckInNfcRequest( - patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, scannedCode: scannedCode, checkInType: checkInType); + final result = await myAppointmentsRepo.sendCheckInNfcRequest(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, scannedCode: scannedCode, checkInType: checkInType); result.fold( (failure) async => await errorHandlerService.handleError(failure: failure), @@ -647,12 +659,8 @@ class MyAppointmentsViewModel extends ChangeNotifier { } Future insertLiveCareVIDARequest( - {required clientRequestID, - required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, - Function(dynamic)? onSuccess, - Function(String)? onError}) async { - final result = await myAppointmentsRepo.insertLiveCareVIDARequest( - clientRequestID: clientRequestID, patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel); + {required clientRequestID, required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await myAppointmentsRepo.insertLiveCareVIDARequest(clientRequestID: clientRequestID, patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel); result.fold( (failure) async => await errorHandlerService.handleError(failure: failure), @@ -928,5 +936,4 @@ class MyAppointmentsViewModel extends ChangeNotifier { }, ); } - } diff --git a/lib/features/my_invoices/models/get_invoices_list_response_model.dart b/lib/features/my_invoices/models/get_invoices_list_response_model.dart index e8056d9..fe59c04 100644 --- a/lib/features/my_invoices/models/get_invoices_list_response_model.dart +++ b/lib/features/my_invoices/models/get_invoices_list_response_model.dart @@ -13,10 +13,10 @@ class GetInvoicesListResponseModel { String? doctorName; String? doctorNameN; String? clinicName; - double? decimalDoctorRate; + num? decimalDoctorRate; String? doctorImageURL; - int? doctorRate; - int? patientNumber; + num? doctorRate; + num? patientNumber; String? projectName; GetInvoicesListResponseModel( diff --git a/lib/features/radiology/radiology_view_model.dart b/lib/features/radiology/radiology_view_model.dart index c8150c1..ee5c970 100644 --- a/lib/features/radiology/radiology_view_model.dart +++ b/lib/features/radiology/radiology_view_model.dart @@ -67,6 +67,19 @@ class RadiologyViewModel extends ChangeNotifier { patientRadiologyOrders = apiResponse.data!; 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; + isRadiologyOrdersLoading = false; filterSuggestions(); notifyListeners(); @@ -168,9 +181,31 @@ class RadiologyViewModel extends ChangeNotifier { filterRadiologyReports(String query) { if (query.isEmpty) { patientRadiologyOrders = tempRadiologyOrders; // reset + 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; } else { - filteredRadiologyOrders = filteredRadiologyOrders.where((desc) => desc.description!.toLowerCase().contains(query.toLowerCase())).toList(); - patientRadiologyOrders = filteredRadiologyOrders; + filteredRadiologyOrders = filteredRadiologyOrders.where((desc) => (desc.description ?? "").toLowerCase().contains(query.toLowerCase())).toList(); + + final clinicMap = >{}; + final hospitalMap = >{}; + for (var order in filteredRadiologyOrders) { + 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; } notifyListeners(); } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 3940f9e..f546be4 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1573,5 +1573,6 @@ abstract class LocaleKeys { static const invalidEligibility = 'invalidEligibility'; static const invalidInsurance = 'invalidInsurance'; static const continueCash = 'continueCash'; + static const hmgPolicies = 'hmgPolicies'; } diff --git a/lib/presentation/book_appointment/livecare/select_immediate_livecare_clinic_page.dart b/lib/presentation/book_appointment/livecare/select_immediate_livecare_clinic_page.dart index 594bff0..a83dfa0 100644 --- a/lib/presentation/book_appointment/livecare/select_immediate_livecare_clinic_page.dart +++ b/lib/presentation/book_appointment/livecare/select_immediate_livecare_clinic_page.dart @@ -116,7 +116,7 @@ class _SelectImmediateLiveCareClinicPageState extends State { padding: EdgeInsets.only(top: 24.h), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), - itemCount: bookAppointmentsVM.isClinicsListLoading ? 5 : bookAppointmentsVM.liveCareClinicsList.length, + itemCount: bookAppointmentsVM.isClinicsListLoading + ? 5 + : bookAppointmentsVM.liveCareClinicsList.isNotEmpty + ? bookAppointmentsVM.liveCareClinicsList.length + : 1, + + // bookAppointmentsVM.isClinicsListLoading ? 5 : bookAppointmentsVM.liveCareClinicsList.length, + itemBuilder: (context, index) { return bookAppointmentsVM.isClinicsListLoading ? ClinicCard( @@ -163,14 +170,16 @@ class _SelectClinicPageState extends State { duration: Duration(milliseconds: 300), curve: Curves.easeInOut, decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), - child: ClinicCard( - bookAppointmentsVM: bookAppointmentsVM, - liveCareClinicsResponseModel: bookAppointmentsVM.liveCareClinicsList[index], - clinicsListResponseModel: GetClinicsListResponseModel(), - isLoading: bookAppointmentsVM.isClinicsListLoading, - ).onPress(() { - onLiveCareClinicSelected(bookAppointmentsVM.liveCareClinicsList[index]); - }), + child: bookAppointmentsVM.liveCareClinicsList.isNotEmpty + ? ClinicCard( + bookAppointmentsVM: bookAppointmentsVM, + liveCareClinicsResponseModel: bookAppointmentsVM.liveCareClinicsList[index], + clinicsListResponseModel: GetClinicsListResponseModel(), + isLoading: bookAppointmentsVM.isClinicsListLoading, + ).onPress(() { + onLiveCareClinicSelected(bookAppointmentsVM.liveCareClinicsList[index]); + }) + : Utils.getNoDataWidget(context), ), ), ), diff --git a/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_home.dart b/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_home.dart index bbaa5f5..7f206c1 100644 --- a/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_home.dart +++ b/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_home.dart @@ -7,6 +7,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/emergency_services/emergency_services_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/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; @@ -24,11 +25,13 @@ class ErOnlineCheckinHome extends StatelessWidget { ErOnlineCheckinHome({super.key}); late EmergencyServicesViewModel emergencyServicesViewModel; + late MyAppointmentsViewModel myAppointmentsViewModel; bool _supportsNFC = false; @override Widget build(BuildContext context) { emergencyServicesViewModel = Provider.of(context, listen: false); + myAppointmentsViewModel = Provider.of(context, listen: false); FlutterNfcKit.nfcAvailability.then((value) { _supportsNFC = (value == NFCAvailability.available); }); @@ -81,6 +84,9 @@ class ErOnlineCheckinHome extends StatelessWidget { await emergencyServicesViewModel.autoGenerateInvoiceERClinic( projectID: value, onSuccess: (value) { + myAppointmentsViewModel.setIsAppointmentDataToBeLoaded(true); + myAppointmentsViewModel.initAppointmentsViewModel(); + myAppointmentsViewModel.getPatientAppointments(true, false); LoaderBottomSheet.hideLoader(); showCommonBottomSheetWithoutHeight(context, title: LocaleKeys.onlineCheckIn.tr(), diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index f0bf08f..4458b75 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -692,6 +692,8 @@ class ServicesPage extends StatelessWidget { ) ], ), + SizedBox(height: 24.h), + LocaleKeys.hmgPolicies.tr().toText18(weight: FontWeight.bold), SizedBox(height: 16.h), Row( children: [ diff --git a/lib/presentation/insurance/insurance_approval_details_page.dart b/lib/presentation/insurance/insurance_approval_details_page.dart index a6d8157..a074a8d 100644 --- a/lib/presentation/insurance/insurance_approval_details_page.dart +++ b/lib/presentation/insurance/insurance_approval_details_page.dart @@ -1,5 +1,6 @@ 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_export.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; @@ -122,35 +123,69 @@ class InsuranceApprovalDetailsPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ "Approval Details".toText16(isBold: true), - SizedBox(height: 16.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocaleKeys.procedureName.tr(context: context).toText14(isBold: true), - Expanded( - child: (insuranceApprovalResponseModel.apporvalDetails!.procedureName ?? "") - .toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor, textAlignment: TextAlign.end, maxLine: 2), - ), - ], - ), - SizedBox(height: 8.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - "${LocaleKeys.status.tr(context: context)}: ".toText14(isBold: true), - insuranceApprovalResponseModel.apporvalDetails!.status!.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), - ], - ), - SizedBox(height: 8.h), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - "${LocaleKeys.usageStatus.tr(context: context)}: ".toText14(isBold: true), - (insuranceApprovalResponseModel.apporvalDetails!.isInvoicedDesc ?? "").toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), - ], - ), - ], - ) : SizedBox.shrink(), + ListView.separated( + padding: EdgeInsets.only(top: 16.h), + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: insuranceApprovalResponseModel.apporvalDetails!.length, + itemBuilder: (context, 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, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocaleKeys.procedureName.tr(context: context).toText14(isBold: true), + Expanded( + child: (insuranceApprovalResponseModel.apporvalDetails![index]!.procedureName ?? "") + .toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor, textAlignment: TextAlign.end, maxLine: 2), + ), + ], + ), + SizedBox(height: 8.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "${LocaleKeys.status.tr(context: context)}: ".toText14(isBold: true), + insuranceApprovalResponseModel.apporvalDetails![index]!.status!.toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + ], + ), + SizedBox(height: 8.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "${LocaleKeys.usageStatus.tr(context: context)}: ".toText14(isBold: true), + (insuranceApprovalResponseModel.apporvalDetails![index]!.isInvoicedDesc ?? "").toText12(fontWeight: FontWeight.w500, color: AppColors.greyTextColor), + ], + ), + ], + ), + ), + ), + ), + ); + }, + separatorBuilder: (BuildContext cxt, int index) => Column( + children: [ + SizedBox(height: 16.h), + Divider(height: 1, color: AppColors.greyColor), + SizedBox(height: 16.h), + ], + ), + ), + ], + ) + : SizedBox.shrink(), ), ) ], diff --git a/lib/presentation/lab/lab_orders_page.dart b/lib/presentation/lab/lab_orders_page.dart index 4016aff..0bcbc36 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 { final lavVM = Provider.of(context, listen: false); if (lavVM.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: lavVM.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; lavVM.filterLabReports(value); } } }, child: Consumer( builder: (context, model, child) { return SingleChildScrollView( physics: 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: () { model.setIsSortByClinic(true); }, backgroundColor: model.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, borderColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), SizedBox(width: 8.h), CustomButton( text: LocaleKeys.byHospital.tr(context: context), onPressed: () { model.setIsSortByClinic(false); }, backgroundColor: model.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, borderColor: model.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, textColor: model.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ], ), ), SizedBox(height: 8.h), selectedFilterText!.isNotEmpty ? CustomChipWidget( chipText: selectedFilterText!, chipType: ChipTypeEnum.alert, isSelected: true, ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available model.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (model.patientLabOrdersViewList.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: model.patientLabOrdersViewList.length, itemBuilder: (context, index) { final group = model.patientLabOrdersViewList[index]; final isExpanded = expandedIndex == index; return AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 500), child: SlideAnimation( verticalOffset: 100.0, child: FadeInAnimation( child: AnimatedContainer( duration: Duration(milliseconds: 300), curve: Curves.easeInOut, margin: EdgeInsets.symmetric(vertical: 8.h), decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true), child: InkWell( onTap: () { setState(() { expandedIndex = isExpanded ? null : index; }); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.all(16.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ AppCustomChipWidget(labelText: "${group.length} ${LocaleKeys.results.tr(context: context)}"), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), Text( model.isSortByClinic ? (group.first.clinicDescription ?? 'Unknown') : (group.first.projectName ?? 'Unknown'), style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), overflow: TextOverflow.ellipsis, ), ], ), ), AnimatedSwitcher( duration: Duration(milliseconds: 500), switchInCurve: Curves.easeIn, switchOutCurve: Curves.easeOut, transitionBuilder: (Widget child, Animation animation) { return FadeTransition( opacity: animation, child: SizeTransition( sizeFactor: animation, axisAlignment: 0.0, child: child, ), ); }, child: isExpanded ? Container( key: ValueKey(index), padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 0.h), child: 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: model.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: () { model.currentlySelectedPatientOrder = order; labProvider.getPatientLabResultByHospital(order); labProvider.getPatientSpecialResult(order); Navigator.of(context).push( CustomPageRoute(page: LabResultByClinic(labOrder: order)), ); }, backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, textColor: AppColors.primaryRedColor, fontSize: 14, fontWeight: FontWeight.w500, borderRadius: 12, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ) ], ), // SizedBox(height: 12.h), // Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), // SizedBox(height: 12.h), ], ).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 (model.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: model.indexedCharacterForUniqueTest, details: model.uniqueTestsList, labViewModel: model, rangeViewModel: rangeViewModel, appState: _appState, ) ], )); }, ), ); } Color getLabOrderStatusColor(num status) { switch (status) { case 44: return AppColors.warningColorYellow; case 45: return AppColors.warningColorYellow; case 16: return AppColors.successColor; case 17: return AppColors.successColor; default: return AppColors.greyColor; } } String getLabOrderStatusText(num status) { switch (status) { case 44: return LocaleKeys.resultsPending.tr(context: context); case 45: return LocaleKeys.resultsPending.tr(context: context); case 16: return LocaleKeys.resultsAvailable.tr(context: context); case 17: return LocaleKeys.resultsAvailable.tr(context: context); default: return ""; } } getLabSuggestions(LabViewModel model) { if (model.patientLabOrders.isEmpty) { return []; } return model.patientLabOrders.map((m) => m.testDetails).toList(); } } \ No newline at end of file +import 'dart:async'; import '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, 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 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 ba97731..cf6ce97 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 @@ -22,7 +22,7 @@ class LabOrderResultItem extends StatelessWidget { final bool isExpanded; final Color iconColor; - const LabOrderResultItem({super.key, required this.onTap, this.tests, required this.index, this.isLoading = false, this.isExpanded = false,required this.iconColor, required this.severityText}); + const LabOrderResultItem({super.key, required this.onTap, this.tests, required this.index, this.isLoading = false, this.isExpanded = false, required this.iconColor, required this.severityText}); @override build(BuildContext context) { @@ -42,7 +42,10 @@ class LabOrderResultItem extends StatelessWidget { padding: EdgeInsets.only(bottom: 8.h), child: '${tests!.description}'.toText14(weight: FontWeight.w500), ), - (tests!.packageShortDescription ?? "").toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), + // (tests!.packageShortDescription ?? "").toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), + + ((tests!.testShortDescription != null && tests!.testShortDescription!.isNotEmpty) ? tests!.testShortDescription : tests!.packageShortDescription)! + .toText12(fontWeight: FontWeight.w500, color: AppColors.textColorLight), SizedBox(height: 12.h), Directionality( textDirection: ui.TextDirection.ltr, @@ -65,28 +68,30 @@ class LabOrderResultItem extends StatelessWidget { ), ), ), - SizedBox(width: 4.h,), + SizedBox( + width: 4.h, + ), Visibility( // visible: tests?.checkIfGraphShouldBeDisplayed() == true, visible: true, child: Expanded( flex: 2, - child: Visibility( - visible: tests?.referanceRange != null, - child: Text( - "(${LocaleKeys.referenceRange.tr(context: context)}: ${tests?.referanceRange})", - style: TextStyle( - fontSize: 12.f, - fontWeight: FontWeight.w500, - fontFamily: 'Poppins', - color: AppColors.greyTextColor, + child: Visibility( + visible: tests?.referanceRange != null, + child: Text( + "(${LocaleKeys.referenceRange.tr(context: context)}: ${tests?.referanceRange})", + style: TextStyle( + fontSize: 12.f, + fontWeight: FontWeight.w500, + fontFamily: 'Poppins', + color: AppColors.greyTextColor, + ), + // overflow: TextOverflow.ellipsis, + // maxLines: 2, + softWrap: true, ), - // overflow: TextOverflow.ellipsis, - // maxLines: 2, - softWrap: true, ), ), - ), ) ], ), @@ -102,14 +107,8 @@ class LabOrderResultItem extends StatelessWidget { spacing: 6.h, crossAxisAlignment: CrossAxisAlignment.start, children: [ - severityText.tr().toText10( - weight: FontWeight.w500, - color: AppColors.greyTextColor), - Utils.buildSvgWithAssets( - icon: AppAssets.lab_result_indicator, - width: 21, - height: 23, - iconColor: iconColor), + severityText.tr().toText10(weight: FontWeight.w500, color: AppColors.greyTextColor), + Utils.buildSvgWithAssets(icon: AppAssets.lab_result_indicator, width: 21, height: 23, iconColor: iconColor), ], ), ), @@ -119,7 +118,7 @@ class LabOrderResultItem extends StatelessWidget { iconSize: 16.h, text: LocaleKeys.viewReport.tr(context: context), onPressed: () { - onTap(); + onTap(); }, backgroundColor: AppColors.secondaryLightRedColor, borderColor: AppColors.secondaryLightRedColor, diff --git a/lib/presentation/medical_report/medical_reports_page.dart b/lib/presentation/medical_report/medical_reports_page.dart index 87420fd..02a9bde 100644 --- a/lib/presentation/medical_report/medical_reports_page.dart +++ b/lib/presentation/medical_report/medical_reports_page.dart @@ -17,6 +17,7 @@ import 'package:hmg_patient_app_new/presentation/medical_report/widgets/patient_ 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/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; @@ -251,46 +252,21 @@ class _MedicalReportsPageState extends State { ], ), SizedBox(height: 8.h), - Row( + Wrap( + alignment: WrapAlignment.start, + direction: Axis.horizontal, + spacing: 6.h, + runSpacing: 6.h, children: [ - CustomButton( - text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(report.appointmentDate), 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, + AppCustomChipWidget( + labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(report.appointmentDate), false), ), - SizedBox(width: 8.h), - CustomButton( - text: medicalFileVM.isMedicalReportsSortByClinic ? report.projectName! : report.clinicDescription!, - 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: report.statusDesc!, - 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, + AppCustomChipWidget( + labelText: medicalFileVM.isMedicalReportsSortByClinic ? report.projectName! : report.clinicDescription!, ), + report.statusDesc != null ? AppCustomChipWidget( + labelText: report.statusDesc ?? "test", + ) : SizedBox.shrink(), ], ), SizedBox(height: 8.h), diff --git a/lib/presentation/prescriptions/prescription_item_view.dart b/lib/presentation/prescriptions/prescription_item_view.dart index 03a343f..1369d4a 100644 --- a/lib/presentation/prescriptions/prescription_item_view.dart +++ b/lib/presentation/prescriptions/prescription_item_view.dart @@ -84,76 +84,77 @@ class PrescriptionItemView extends StatelessWidget { SizedBox(height: 14.h), Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), SizedBox(height: 14.h), - Row( - mainAxisSize: MainAxisSize.max, - children: [ - Utils.buildSvgWithAssets(icon: AppAssets.prescription_reminder_icon, width: 35.h, height: 35.h).toShimmer2(isShow: isLoading), - SizedBox(width: 8.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.setReminder.tr(context: context).toText13(isBold: true), - "Notify me before the consumption time".toText10(color: AppColors.textColorLight), - ], - ).toShimmer2(isShow: isLoading).expanded, - Switch( - activeColor: AppColors.successColor, - activeTrackColor: AppColors.successColor.withValues(alpha: .15), - value: isLoading ? false : 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()); + Visibility( + visible: (!isLoading && prescriptionVM.prescriptionDetailsList[index].frequencyNumber != 0), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Utils.buildSvgWithAssets(icon: AppAssets.prescription_reminder_icon, width: 35.h, height: 35.h).toShimmer2(isShow: isLoading), + SizedBox(width: 8.h), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.setReminder.tr(context: context).toText13(isBold: true), + "Notify me before the consumption time".toText10(color: AppColors.textColorLight), + ], + ).toShimmer2(isShow: isLoading).expanded, + Switch( + activeColor: AppColors.successColor, + activeTrackColor: AppColors.successColor.withValues(alpha: .15), + value: isLoading ? false : prescriptionVM.prescriptionDetailsList[index].hasReminder!, + onChanged: (newValue) async { + CalenderUtilsNew calender = CalenderUtilsNew.instance; - prescriptionVM.setPrescriptionItemReminder(newValue, prescriptionVM.prescriptionDetailsList[index]); - LoaderBottomSheet.hideLoader(); - return; - } + if (prescriptionVM.prescriptionDetailsList[index].hasReminder ?? false) { + LoaderBottomSheet.showLoader(loadingText: "Removing Reminders"); + bool resultValue = await calender.checkAndRemoveMultipleItems(id: prescriptionVM.prescriptionDetailsList[index].itemID.toString()); - 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: () { + prescriptionVM.setPrescriptionItemReminder(newValue, prescriptionVM.prescriptionDetailsList[index]); + LoaderBottomSheet.hideLoader(); + return; + } - }, - isMultiAllowed: true, - onMultiDateSuccess: (int selectedIndex) async{ - bool isEventAdded = await calender.createMultipleEvents( + 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(), + 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), - ], - ).paddingSymmetrical(16.h, 0.h), + 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), + ], + ).paddingSymmetrical(16.h, 0.h), + ), SizedBox(height: 14.h), // Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), // Row( diff --git a/lib/presentation/radiology/radiology_orders_page.dart b/lib/presentation/radiology/radiology_orders_page.dart index 2f42436..a07face 100644 --- a/lib/presentation/radiology/radiology_orders_page.dart +++ b/lib/presentation/radiology/radiology_orders_page.dart @@ -86,19 +86,6 @@ class _RadiologyOrdersPageState extends State { child: Consumer( builder: (context, model, child) { // Build grouping lists if we have data and none constructed yet - if (!model.isRadiologyOrdersLoading && model.patientRadiologyOrders.isNotEmpty && model.patientRadiologyOrdersViewList.isEmpty) { - final clinicMap = >{}; - final hospitalMap = >{}; - for (var order in model.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); - } - model.patientRadiologyOrdersByClinic = clinicMap.values.toList(); - model.patientRadiologyOrdersByHospital = hospitalMap.values.toList(); - model.patientRadiologyOrdersViewList = model.isSortByClinic ? model.patientRadiologyOrdersByClinic : model.patientRadiologyOrdersByHospital; - } return Padding( padding: EdgeInsets.symmetric(horizontal: 24.h), @@ -140,13 +127,12 @@ class _RadiologyOrdersPageState extends State { ), ], ), - SizedBox(height: 8.h), selectedFilterText.isNotEmpty ? AppCustomChipWidget( padding: EdgeInsets.symmetric(horizontal: 5.h), labelText: selectedFilterText, - deleteIcon: 'assets/images/svg/cross_circle.svg', + deleteIcon: AppAssets.close_bottom_sheet_icon, backgroundColor: AppColors.alertColor, textColor: AppColors.whiteColor, deleteIconColor: AppColors.whiteColor,