diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index d0321ace..905aa11a 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -1959,12 +1959,59 @@ "refund": "استرداد", "parkingQR": "رمز الاستجابة السريعة لوقوف السيارات", "parkingQRDesc": "امسح رمز الاستجابة السريعة (QR Code) أدناه عند بوابة الخروج من موقف السيارات:", - "livecareUpdateInsuranceSent": "تم استلام طلب تحديث بيانات التأمين الخاص بك، ويجري العمل عليه حالياً. سنقوم بإشعارك فور اكتمال التحديث.", - "livecareUpdateInsurance": "سيتم تحويل طلب تحديث بيانات التأمين إلى فريق LiveCare المختص لاستكمال الإجراءات. هل تود المتابعة؟", - "schedule": "جدول", - "doctorSchedule": "جدول الطبيب", - "weeklyShift": "الفترات الأسبوعية", - "dayOff": "إجازة", - "notAvailable": "غير متاح", - "hide": "إخفاء" + "livecareUpdateInsuranceSent": "تم استلام طلب تحديث بيانات التأمين الخاص بك، ويجري العمل عليه حالياً. سنقوم بإشعارك فور اكتمال التحديث.", + "livecareUpdateInsurance": "سيتم تحويل طلب تحديث بيانات التأمين إلى فريق LiveCare المختص لاستكمال الإجراءات. هل تود المتابعة؟", + "schedule": "جدول", + "doctorSchedule": "جدول الطبيب", + "weeklyShift": "الفترات الأسبوعية", + "dayOff": "إجازة", + "notAvailable": "غير متاح", + "hide": "إخفاء", + "admissionNo": "رقم القبول:", + "admissionReqNo": "رقم طلب القبول:", + "dischargeDate": "تاريخ التفريغ", + "selectAdmissionText": "يرجى تحديد أحد حالات القبول من الأسفل لعرض التقارير الطبية:", + "onlyAdmitted": "هذه الخدمة متاحة فقط للمرضى المقبولين", + "assistYou": "كيف يمكننا مساعدتك؟", + "receive": "تجهيز", + "PRO": "علاقات المرضى", + "patientRelationOffice": "علاقات المرضى", + "roomNo": "رقم الغرفة", + "InPatientServicesHeader": "خدمات التنويم", + "admissionGeneral": "اقرار", + "consent": "التنويم", + "generalInstructionsTitle": "تعليمات", + "generalInstructionsSubTitle": "التنويم العامة", + "generalConsentTitle": "الموافقة العامة", + "medicalInstructionsTitle": "التعليمات الطبية قبل التنويم", + "mealPlanTitle": "خدمات", + "mealPlanSubTitle": "الوجبات", + "birthNotificationTitle": "خدمات تبليغ الولادة", + "admissionNoticeTitle": "إشعار تنويم", + "mothersMRN": "رقم ملف الأم", + "mothersName": "اسم الأم", + "fathersNameEN": "اسم الاب انجليزي", + "fathersNameAR": "اسم الاب عربي", + "babysNameEN": "اسم المولود انجليزي", + "babysNameAR": "اسم المولود عربي", + "contactNumber": "رقم الاتصال", + "scanID": "معرف المسح", + "birthNotificationNotes1": "للسعوديين : إرفاق صورة من بطاقة الأحوال لكلا الزوجين وفي حال عدم توفر بطاقة الزوجة ترفق عنها بطاقة العائلة", + "birthNotificationNotes2": "لغير السعوديين : إرفاق صورة الإقامة آأو جواز السفر", + "birthNotificationNotes3": "للمواطنين الغير حاملين لبطاقة الأحوال : إرفاق صورة من عقد الزواج برقم الحاسب", + "placeOrder": "مكان الامر", + "isFasting": "هل أنت صائم؟", + "noGeneralInstructions": "ليس لديك أي تعليمات عامة في الوقت الحالي.", + "noMedicalInstructions": "ليس لديك أي تعليمات طبية في الوقت الحالي.", + "medicalInstructions": "تعليمات طبية", + "generalInstructions": "تعليمات عامة", + "copyLink": "نسخ الوصلة:", + "paymentLinkCopied": "تم نسخ رابط الدفع إلى الحافظة الخاصة بك!", + "copyLinkTxt": "أو يمكنك نسخ رابط الدفع من الأسفل وإرساله إلى شخص يمكنه الدفع نيابة عنك:", + "proErrorMessage": "عزيزي المريض ، طاقم العمل لدينا خارج المكتب حاليًا ، يرجى ملاحظة أن ساعات العمل لدينا من 7:00 صباحًا إلى 10:00 مساءً ، ويسعدنا مساعدتك خلال هذا الوقت ، أو يمكنك الاتصال بـ <أدخل الرقم هنا>", + "InPatient": "مريض منوم", + "admissionReq": "طلب القبول", + "admissionDate": "تاريخ القبول", + "admissionRequestDate": "تاريخ القبول المتوقع" + } diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index ae344b01..2b72c5ef 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -1949,14 +1949,60 @@ "invoiceHistory": "Invoice History", "parkingQR": "Parking QR Code", "parkingQRDesc": "Scan the below QR Code at the exit parking gate:", - "livecareUpdateInsuranceSent": "Your insurance update request is being processed. You will be notified once the update is completed.", - "livecareUpdateInsurance": "Please note that your insurance update request will be sent to the our LiveCare team for update. Would you like to proceed?", - "schedule": "Schedule", - "doctorSchedule": "Doctor Schedule", - "weeklyShift": "Weekly Shift", - "dayOff": "Off", - "notAvailable": "Not Available", - "hide": "Hide" + "livecareUpdateInsuranceSent": "Your insurance update request is being processed. You will be notified once the update is completed.", + "livecareUpdateInsurance": "Please note that your insurance update request will be sent to the our LiveCare team for update. Would you like to proceed?", + "schedule": "Schedule", + "doctorSchedule": "Doctor Schedule", + "weeklyShift": "Weekly Shift", + "dayOff": "Off", + "notAvailable": "Not Available", + "hide": "Hide", + "admissionNo": "Admission No", + "admissionReqNo": "Admission Request No", + "dischargeDate": "Discharge Date", + "selectAdmissionText": "Please select one of the admissions from below to view medical reports:", + "onlyAdmitted": "This service is only available for admitted patients", + "assistYou": "How we may assist you?", + "receive": "Receive", + "PRO": "PRO", + "patientRelationOffice": "Patient Relation Office", + "roomNo": "Room No.", + "InPatientServicesHeader": "InPatient Services", + "admissionGeneral": "Admission General", + "consent": "Consent", + "generalInstructionsTitle": "General", + "generalInstructionsSubTitle": "Instructions", + "generalConsentTitle": "General Consent", + "medicalInstructionsTitle": "Medical Instructions", + "mealPlanTitle": "Meal Plan", + "mealPlanSubTitle": "Services", + "birthNotificationTitle": "Birth Notification", + "admissionNoticeTitle": "Admission Notice", + "mothersMRN": "Mother's MRN *", + "mothersName": "Mother's name *", + "fathersNameEN": "Father's name english *", + "fathersNameAR": "Father's name arabic *", + "babysNameEN": "Baby's name english *", + "babysNameAR": "Baby's name arabic *", + "contactNumber": "Contact number *", + "scanID": "Scan ID", + "birthNotificationNotes1": "For Saudis: Provide copy of the identification card for both couples. If the wife doesn't have identification card, The family card must be provided.", + "birthNotificationNotes2": "Non Saudis: Provide copy of iqama or copy of the passport.", + "birthNotificationNotes3": "For Residents without identification card: Provide marriage contract.", + "placeOrder": "Place Order", + "isFasting": "Are you fasting?", + "noGeneralInstructions": "You do not have any general instructions right now.", + "noMedicalInstructions": "You do not have any medical instructions right now.", + "medicalInstructions": "Medical Instructions", + "generalInstructions": "General Instructions", + "copyLink": "COPY LINK", + "paymentLinkCopied": "Payment link copied to your clipboard!'", + "copyLinkTxt": "Or you can copy the payment link from below & send it to someone who can pay on your behalf: ", + "proErrorMessage": "Dear patient, Our staff is currently out of office, please note that our working hours are from 7:00 AM to 10:00 PM, and we'd love to help you during that time, or you can call ", + "InPatient": "InPatient", + "admissionReq": "Admission Request", + "admissionDate": "Admission Date", + "admissionRequestDate": "Expected Admission Date" } diff --git a/lib/core/api/api_client.dart b/lib/core/api/api_client.dart index 3bfbf6cb..93474cef 100644 --- a/lib/core/api/api_client.dart +++ b/lib/core/api/api_client.dart @@ -210,7 +210,7 @@ class ApiClientImp implements ApiClient { body['TokenID'] = "@dm!n"; } - // body['TokenID'] = "@dm!n"; + body['TokenID'] = "@dm!n"; // body['PatientID'] = 2122445; // body['PatientID'] = 53320; // body['PatientTypeID'] = 1; diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index 8f1455ad..8f2deaa3 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -5,7 +5,7 @@ import 'package:hmg_patient_app_new/core/enums.dart'; class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT diff --git a/lib/core/app_state.dart b/lib/core/app_state.dart index a27b727e..b86512ef 100644 --- a/lib/core/app_state.dart +++ b/lib/core/app_state.dart @@ -48,6 +48,8 @@ class AppState { bool isPaytabsEnabled = false; bool isPayfortHostedPageEnabled = true; + bool isPatientAdmitted = false; + bool hasAdmissionRequest = false; void setIsPaytabsEnabled(bool value) { isPaytabsEnabled = value; @@ -59,6 +61,14 @@ class AppState { // isPayfortHostedPageEnabled = false; } + void setIsPatientAdmitted(bool value) { + isPatientAdmitted = value; + } + + void setHasAdmissionRequest(bool value) { + hasAdmissionRequest = value; + } + int? _superUserID; bool isChildLoggedIn = false; bool isGMSAvailable = true; diff --git a/lib/core/dependencies.dart b/lib/core/dependencies.dart index ecfe1324..48f2d836 100644 --- a/lib/core/dependencies.dart +++ b/lib/core/dependencies.dart @@ -27,6 +27,8 @@ import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_repo.dart import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart'; import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_repo.dart'; import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart'; +import 'package:hmg_patient_app_new/features/inpatient_services/inpatient_services_repo.dart'; +import 'package:hmg_patient_app_new/features/inpatient_services/inpatient_services_view_model.dart'; import 'package:hmg_patient_app_new/features/insurance/insurance_repo.dart'; import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/lab_repo.dart'; @@ -194,6 +196,7 @@ class AppDependencies { getIt.registerLazySingleton(() => ProfileSettingsRepoImp(loggerService: getIt(), apiClient: getIt())); getIt.registerLazySingleton(() => RefundRequestRepoImp(apiClient: getIt(), loggerService: getIt())); getIt.registerLazySingleton(() => OffersAndDiscountsRepoImp(loggerService: getIt(), apiClient: getIt())); + getIt.registerLazySingleton(() => InpatientServicesRepoImp(loggerService: getIt(), apiClient: getIt())); // ViewModels // Global/shared VMs → LazySingleton @@ -374,5 +377,12 @@ class AppDependencies { getIt.registerLazySingleton( () => ClarityService(appState: getIt.get()), ); + + getIt.registerLazySingleton(() => InpatientServicesViewModel( + appState: getIt(), + inpatientServicesRepo: getIt(), + errorHandlerService: getIt(), + )); + } } diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index fdc16943..521efc6b 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -29,6 +29,7 @@ import 'package:hmg_patient_app_new/features/authentication/models/resp_models/c import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart'; import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart'; +import 'package:hmg_patient_app_new/features/inpatient_services/inpatient_services_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/symptoms_checker/symptoms_checker_view_model.dart'; @@ -1258,6 +1259,10 @@ class AuthenticationViewModel extends ChangeNotifier { // _appState.setUserBloodGroup = (activation.patientBlodType ?? ""); _appState.setAppAuthToken = activation.authenticationTokenId; // myAppointmentsVM.getActiveAppointmentsCount(); + + getIt.get().initInPatientServices(); + getIt.get().checkIfIsInPatient(); + final request = RequestUtils.getAuthanticatedCommonRequest().toJson(); bool isUserAgreedBefore = await checkIfUserAgreedBefore(request: request); diff --git a/lib/features/inpatient_services/inpatient_services_repo.dart b/lib/features/inpatient_services/inpatient_services_repo.dart new file mode 100644 index 00000000..67fc02b2 --- /dev/null +++ b/lib/features/inpatient_services/inpatient_services_repo.dart @@ -0,0 +1,95 @@ +import 'package:dartz/dartz.dart'; +import 'package:hmg_patient_app_new/core/api/api_client.dart'; +import 'package:hmg_patient_app_new/core/api_consts.dart'; +import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; +import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; +import 'package:hmg_patient_app_new/features/inpatient_services/models/get_general_instructions_response_model.dart'; +import 'package:hmg_patient_app_new/services/logger_service.dart'; + +abstract class InpatientServicesRepo { + Future>> checkIfIsInPatient(); + + Future>>> getGeneralInstructions({required int projectID}); +} + +// List getGeneralInstructionsList = []; + +class InpatientServicesRepoImp implements InpatientServicesRepo { + final ApiClient apiClient; + final LoggerService loggerService; + + InpatientServicesRepoImp({required this.loggerService, required this.apiClient}); + + @override + Future> checkIfIsInPatient() async { + Map mapDevice = {"IsActiveAppointment": false}; + + try { + GenericApiModel? apiResponse; + Failure? failure; + await apiClient.post( + CHECK_IF_PATIENT_ADMITTED, + body: mapDevice, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + apiResponse = GenericApiModel( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: response, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } + + @override + Future>>> getGeneralInstructions({required int projectID}) async { + Map mapDevice = {"ProjectID": projectID}; + + try { + GenericApiModel>? apiResponse; + Failure? failure; + await apiClient.post( + GET_GENERAL_INSTRUCTIONS, + body: mapDevice, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + List getGeneralInstructionsList = []; + response['generalInstructions'].forEach((v) { + getGeneralInstructionsList.add(GetGeneralInstructions.fromJson(v)); + }); + + apiResponse = GenericApiModel>( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: getGeneralInstructionsList, + ); + } catch (e) { + failure = DataParsingFailure(e.toString()); + } + }, + ); + if (failure != null) return Left(failure!); + if (apiResponse == null) return Left(ServerFailure("Unknown error")); + return Right(apiResponse!); + } catch (e) { + return Left(UnknownFailure(e.toString())); + } + } +} diff --git a/lib/features/inpatient_services/inpatient_services_view_model.dart b/lib/features/inpatient_services/inpatient_services_view_model.dart new file mode 100644 index 00000000..799108ee --- /dev/null +++ b/lib/features/inpatient_services/inpatient_services_view_model.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/features/inpatient_services/inpatient_services_repo.dart'; +import 'package:hmg_patient_app_new/features/inpatient_services/models/get_admission_info_response_model.dart'; +import 'package:hmg_patient_app_new/features/inpatient_services/models/get_admission_request_info_response_model.dart'; +import 'package:hmg_patient_app_new/features/inpatient_services/models/get_general_instructions_response_model.dart'; +import 'package:hmg_patient_app_new/services/error_handler_service.dart'; + +class InpatientServicesViewModel extends ChangeNotifier { + InpatientServicesRepo inpatientServicesRepo; + ErrorHandlerService errorHandlerService; + AppState appState; + + GetAdmissionInfoResponseModel? getAdmissionInfoResponseModel; + GetAdmissionRequestInfoResponseModel? getAdmissionRequestInfoResponseModel; + + bool isAdmitted = false; + bool hasAdmissionRequest = false; + bool isGeneralInstructionsLoading = true; + + List getGeneralInstructionsList = []; + + InpatientServicesViewModel({required this.inpatientServicesRepo, required this.errorHandlerService, required this.appState}); + + initInPatientServices() { + isAdmitted = false; + hasAdmissionRequest = false; + isGeneralInstructionsLoading = true; + notifyListeners(); + } + + Future checkIfIsInPatient({Function(dynamic)? onSuccess, Function(String)? onError}) async { + final result = await inpatientServicesRepo.checkIfIsInPatient(); + + result.fold( + (failure) async { + notifyListeners(); + }, + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + isAdmitted = apiResponse.data['isAdmitted']; + hasAdmissionRequest = apiResponse.data['hasAdmissionRequests']; + if (isAdmitted) { + if (apiResponse.data['PatientAdmittedInformation'].length != 0) { + getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel.fromJson(apiResponse.data['PatientAdmittedInformation'][0]); + appState.setIsPatientAdmitted(true); + appState.setHasAdmissionRequest(false); + } + } + if (hasAdmissionRequest) { + if (apiResponse.data['MedicalInstruction'].length != 0) { + getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel.fromJson(apiResponse.data['MedicalInstruction'][0]); + appState.setIsPatientAdmitted(false); + appState.setHasAdmissionRequest(true); + } + } + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } + + Future getGeneralInstructions({required int projectID, Function(dynamic)? onSuccess, Function(String)? onError}) async { + isGeneralInstructionsLoading = true; + getGeneralInstructionsList.clear(); + notifyListeners(); + + + final result = await inpatientServicesRepo.getGeneralInstructions(projectID: projectID); + + result.fold( + (failure) async { + isGeneralInstructionsLoading = false; + notifyListeners(); + }, + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + isGeneralInstructionsLoading = false; + getGeneralInstructionsList = apiResponse.data!; + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } +} diff --git a/lib/features/inpatient_services/models/get_admission_info_response_model.dart b/lib/features/inpatient_services/models/get_admission_info_response_model.dart new file mode 100644 index 00000000..901adda8 --- /dev/null +++ b/lib/features/inpatient_services/models/get_admission_info_response_model.dart @@ -0,0 +1,104 @@ +class GetAdmissionInfoResponseModel { + String? setupID; + int? projectID; + int? admissionNo; + String? admissionDate; + int? admissionRequestNo; + int? admissionType; + int? patientType; + int? patientID; + int? clinicID; + int? doctorID; + int? admittingClinicID; + int? admittingDoctorID; + int? categoryID; + String? roomID; + String? bedID; + dynamic dischargeDate; + int? approvalNo; + int? status; + String? statusDesc; + String? statusDescN; + String? clinicName; + String? doctorName; + String? projectName; + + GetAdmissionInfoResponseModel( + {this.setupID, + this.projectID, + this.admissionNo, + this.admissionDate, + this.admissionRequestNo, + this.admissionType, + this.patientType, + this.patientID, + this.clinicID, + this.doctorID, + this.admittingClinicID, + this.admittingDoctorID, + this.categoryID, + this.roomID, + this.bedID, + this.dischargeDate, + this.approvalNo, + this.status, + this.statusDesc, + this.statusDescN, + this.clinicName, + this.doctorName, + this.projectName}); + + GetAdmissionInfoResponseModel.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + admissionNo = json['AdmissionNo']; + admissionDate = json['AdmissionDate']; + admissionRequestNo = json['AdmissionRequestNo']; + admissionType = json['AdmissionType']; + patientType = json['PatientType']; + patientID = json['PatientID']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + admittingClinicID = json['AdmittingClinicID']; + admittingDoctorID = json['AdmittingDoctorID']; + categoryID = json['CategoryID']; + roomID = json['RoomID']; + bedID = json['BedID']; + dischargeDate = json['DischargeDate']; + approvalNo = json['ApprovalNo']; + status = json['Status']; + statusDesc = json['StatusDesc']; + statusDescN = json['StatusDescN']; + clinicName = json['ClinicName']; + doctorName = json['DoctorName']; + projectName = json['ProjectName']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['AdmissionNo'] = this.admissionNo; + data['AdmissionDate'] = this.admissionDate; + data['AdmissionRequestNo'] = this.admissionRequestNo; + data['AdmissionType'] = this.admissionType; + data['PatientType'] = this.patientType; + data['PatientID'] = this.patientID; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['AdmittingClinicID'] = this.admittingClinicID; + data['AdmittingDoctorID'] = this.admittingDoctorID; + data['CategoryID'] = this.categoryID; + data['RoomID'] = this.roomID; + data['BedID'] = this.bedID; + data['DischargeDate'] = this.dischargeDate; + data['ApprovalNo'] = this.approvalNo; + data['Status'] = this.status; + data['StatusDesc'] = this.statusDesc; + data['StatusDescN'] = this.statusDescN; + data['ClinicName'] = this.clinicName; + data['DoctorName'] = this.doctorName; + data['ProjectName'] = this.projectName; + return data; + } +} diff --git a/lib/features/inpatient_services/models/get_admission_request_info_response_model.dart b/lib/features/inpatient_services/models/get_admission_request_info_response_model.dart new file mode 100644 index 00000000..73de052b --- /dev/null +++ b/lib/features/inpatient_services/models/get_admission_request_info_response_model.dart @@ -0,0 +1,86 @@ +class GetAdmissionRequestInfoResponseModel { + int? admissionRequestNo; + String? clinicName; + String? doctorName; + String? expectedAdmissionDate; + List ?medicalInstructions; + dynamic medicalInstructionsXML; + String? medicalRemarks; + int? projectId; + String? projectName; + String? setupId; + int? clinicId; + int? doctorId; + + GetAdmissionRequestInfoResponseModel( + {this.admissionRequestNo, + this.clinicName, + this.doctorName, + this.expectedAdmissionDate, + this.medicalInstructions, + this.medicalInstructionsXML, + this.medicalRemarks, + this.projectId, + this.projectName, + this.setupId, + this.clinicId, + this.doctorId}); + + GetAdmissionRequestInfoResponseModel.fromJson(Map json) { + admissionRequestNo = json['admissionRequestNo']; + clinicName = json['clinicName']; + doctorName = json['doctorName']; + clinicId = json['ClinicID']; + doctorId = json['DoctorID']; + expectedAdmissionDate = json['expectedAdmissionDate']; + if (json['medicaLInstructions'] != null) { + medicalInstructions = []; + json['medicaLInstructions'].forEach((v) { + medicalInstructions!.add(new MedicaLInstructions.fromJson(v)); + }); + } + medicalInstructionsXML = json['medicalInstructionsXML']; + medicalRemarks = json['medicalRemarks']; + projectId = json['projectId']; + projectName = json['projectName']; + setupId = json['setupId']; + } + + Map toJson() { + final Map data = new Map(); + data['admissionRequestNo'] = this.admissionRequestNo; + data['clinicName'] = this.clinicName; + data['doctorName'] = this.doctorName; + data['clinicId'] = this.clinicId; + data['doctorId'] = this.doctorId; + data['expectedAdmissionDate'] = this.expectedAdmissionDate; + if (this.medicalInstructions != null) { + data['medicaLInstructions'] = this.medicalInstructions!.map((v) => v.toJson()).toList(); + } + data['medicalInstructionsXML'] = this.medicalInstructionsXML; + data['medicalRemarks'] = this.medicalRemarks; + data['projectId'] = this.projectId; + data['projectName'] = this.projectName; + data['setupId'] = this.setupId; + return data; + } +} + +class MedicaLInstructions { + String? description; + int? parameterCode; + + MedicaLInstructions({this.description, this.parameterCode}); + + MedicaLInstructions.fromJson(Map json) { + description = json['description']; + parameterCode = json['parameterCode']; + } + + Map toJson() { + final Map data = new Map(); + data['description'] = this.description; + data['parameterCode'] = this.parameterCode; + return data; + } +} diff --git a/lib/features/inpatient_services/models/get_general_instructions_response_model.dart b/lib/features/inpatient_services/models/get_general_instructions_response_model.dart new file mode 100644 index 00000000..7869a40e --- /dev/null +++ b/lib/features/inpatient_services/models/get_general_instructions_response_model.dart @@ -0,0 +1,52 @@ +class GetGeneralInstructions { + int? rowID; + int? iD; + int? projectID; + String? text; + String? textN; + bool? isActive; + int? createdBy; + String? createdOn; + dynamic editedBy; + dynamic editedOn; + + GetGeneralInstructions( + {this.rowID, + this.iD, + this.projectID, + this.text, + this.textN, + this.isActive, + this.createdBy, + this.createdOn, + this.editedBy, + this.editedOn}); + + GetGeneralInstructions.fromJson(Map json) { + rowID = json['RowID']; + iD = json['ID']; + projectID = json['ProjectID']; + text = json['Text']; + textN = json['TextN']; + isActive = json['IsActive']; + createdBy = json['CreatedBy']; + createdOn = json['CreatedOn']; + editedBy = json['EditedBy']; + editedOn = json['EditedOn']; + } + + Map toJson() { + final Map data = new Map(); + data['RowID'] = this.rowID; + data['ID'] = this.iD; + data['ProjectID'] = this.projectID; + data['Text'] = this.text; + data['TextN'] = this.textN; + data['IsActive'] = this.isActive; + data['CreatedBy'] = this.createdBy; + data['CreatedOn'] = this.createdOn; + data['EditedBy'] = this.editedBy; + data['EditedOn'] = this.editedOn; + return data; + } +} diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 80cea8b4..d3d5cd09 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -1948,5 +1948,50 @@ abstract class LocaleKeys { static const weeklyShift = 'weeklyShift'; static const dayOff = 'dayOff'; static const hide = 'hide'; + static const admissionNo = 'admissionNo'; + static const admissionReqNo = 'admissionReqNo'; + static const dischargeDate = 'dischargeDate'; + static const selectAdmissionText = 'selectAdmissionText'; + static const onlyAdmitted = 'onlyAdmitted'; + static const assistYou = 'assistYou'; + static const receive = 'receive'; + static const PRO = 'PRO'; + static const patientRelationOffice = 'patientRelationOffice'; + static const roomNo = 'roomNo'; + static const InPatientServicesHeader = 'InPatientServicesHeader'; + static const admissionGeneral = 'admissionGeneral'; + static const generalInstructionsTitle = 'generalInstructionsTitle'; + static const generalInstructionsSubTitle = 'generalInstructionsSubTitle'; + static const generalConsentTitle = 'generalConsentTitle'; + static const medicalInstructionsTitle = 'medicalInstructionsTitle'; + static const mealPlanTitle = 'mealPlanTitle'; + static const mealPlanSubTitle = 'mealPlanSubTitle'; + static const birthNotificationTitle = 'birthNotificationTitle'; + static const admissionNoticeTitle = 'admissionNoticeTitle'; + static const mothersMRN = 'mothersMRN'; + static const mothersName = 'mothersName'; + static const fathersNameEN = 'fathersNameEN'; + static const fathersNameAR = 'fathersNameAR'; + static const babysNameEN = 'babysNameEN'; + static const babysNameAR = 'babysNameAR'; + static const contactNumber = 'contactNumber'; + static const scanID = 'scanID'; + static const birthNotificationNotes1 = 'birthNotificationNotes1'; + static const birthNotificationNotes2 = 'birthNotificationNotes2'; + static const birthNotificationNotes3 = 'birthNotificationNotes3'; + static const placeOrder = 'placeOrder'; + static const isFasting = 'isFasting'; + static const noGeneralInstructions = 'noGeneralInstructions'; + static const noMedicalInstructions = 'noMedicalInstructions'; + static const medicalInstructions = 'medicalInstructions'; + static const generalInstructions = 'generalInstructions'; + static const copyLink = 'copyLink'; + static const paymentLinkCopied = 'paymentLinkCopied'; + static const copyLinkTxt = 'copyLinkTxt'; + static const proErrorMessage = 'proErrorMessage'; + static const InPatient = 'InPatient'; + static const admissionReq = 'admissionReq'; + static const admissionDate = 'admissionDate'; + static const admissionRequestDate = 'admissionRequestDate'; } diff --git a/lib/main.dart b/lib/main.dart index aa266871..7a54e306 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -22,6 +22,7 @@ import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_mode import 'package:hmg_patient_app_new/features/health_trackers/health_trackers_view_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart'; import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart'; +import 'package:hmg_patient_app_new/features/inpatient_services/inpatient_services_view_model.dart'; import 'package:hmg_patient_app_new/features/insurance/insurance_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/history/lab_history_viewmodel.dart'; import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart'; @@ -272,6 +273,9 @@ void main() async { ), ChangeNotifierProvider( create: (_) => getIt.get(), + ), + ChangeNotifierProvider( + create: (_) => getIt.get(), ) ], child: MyApp()), ), // Wrap your app diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index 85f1e972..4d3998a4 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -51,6 +51,7 @@ import 'package:hmg_patient_app_new/presentation/home/widgets/lakum_wallet_card. import 'package:hmg_patient_app_new/presentation/home/widgets/large_service_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card.dart'; import 'package:hmg_patient_app_new/presentation/home/widgets/welcome_widget.dart'; +import 'package:hmg_patient_app_new/presentation/inpatient_services/widgets/inpatient_services_card.dart'; import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_update_details_card.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; import 'package:hmg_patient_app_new/presentation/my_family/my_family.dart'; @@ -75,6 +76,7 @@ import 'package:lottie/lottie.dart'; import 'package:provider/provider.dart'; import 'package:smooth_corner/smooth_corner.dart'; +import '../../features/inpatient_services/inpatient_services_view_model.dart'; import '../emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart'; class LandingPage extends StatefulWidget { @@ -99,6 +101,7 @@ class _LandingPageState extends State { late EmergencyServicesViewModel emergencyServicesViewModel; late TodoSectionViewModel todoSectionViewModel; late NotificationsViewModel notificationsViewModel; + late InpatientServicesViewModel inPatientServicesViewModel; final SwiperController _controller = SwiperController(); @@ -197,6 +200,7 @@ class _LandingPageState extends State { emergencyServicesViewModel = Provider.of(context, listen: false); todoSectionViewModel = Provider.of(context, listen: false); notificationsViewModel = Provider.of(context, listen: false); + inPatientServicesViewModel = Provider.of(context, listen: false); appState = getIt.get(); return PopScope( canPop: false, @@ -498,8 +502,8 @@ class _LandingPageState extends State { // getIt.get().setPaymentConfiguration("Appointment Payment", 15.5); // getIt.get().startCardPayment(); }), - Consumer3( - builder: (context, myAppointmentsVM, immediateLiveCareVM, todoSectionVM, child) { + Consumer4( + builder: (context, myAppointmentsVM, immediateLiveCareVM, todoSectionVM, inpatientServicesVM, child) { return myAppointmentsVM.isMyAppointmentsLoading ? Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( @@ -516,7 +520,9 @@ class _LandingPageState extends State { ), ).paddingSymmetrical(24.h, 16.h) : myAppointmentsVM.patientAppointmentsHistoryList.isNotEmpty - ? myAppointmentsVM.patientAppointmentsHistoryList.length == 1 && !immediateLiveCareVM.patientHasPendingLiveCareRequest + ? myAppointmentsVM.patientAppointmentsHistoryList.length == 1 && + !immediateLiveCareVM.patientHasPendingLiveCareRequest && + !(inPatientServicesViewModel.isAdmitted || inPatientServicesViewModel.hasAdmissionRequest) ? Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration( color: AppColors.whiteColor, @@ -530,15 +536,16 @@ class _LandingPageState extends State { isLoading: false, isFromHomePage: true, ), - ).paddingSymmetrical(24.h, 0.h) + ).paddingSymmetrical(24.h, 16.h) : isTablet ? SizedBox( height: isTablet ? 290.h : 255.h, child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: () { - final int baseCount = - myAppointmentsVM.patientAppointmentsHistoryList.length + (immediateLiveCareVM.patientHasPendingLiveCareRequest ? 1 : 0); + final int baseCount = myAppointmentsVM.patientAppointmentsHistoryList.length + + (immediateLiveCareVM.patientHasPendingLiveCareRequest ? 1 : 0) + + ((inPatientServicesViewModel.isAdmitted || inPatientServicesViewModel.hasAdmissionRequest) ? 1 : 0); return baseCount < 3 ? baseCount : 3; }(), shrinkWrap: true, @@ -575,7 +582,8 @@ class _LandingPageState extends State { builder: (context) { final int baseAppointmentCount = myAppointmentsVM.patientAppointmentsHistoryList.length; final int liveCareCount = immediateLiveCareVM.patientHasPendingLiveCareRequest ? 1 : 0; - final int totalCount = baseAppointmentCount + liveCareCount; + final int inPatientServicesCount = (inPatientServicesViewModel.isAdmitted || inPatientServicesViewModel.hasAdmissionRequest) ? 1 : 0; + final int totalCount = baseAppointmentCount + liveCareCount + inPatientServicesCount; final int swiperItemCount = myAppointmentsVM.isMyAppointmentsLoading ? 3 @@ -592,7 +600,7 @@ class _LandingPageState extends State { axisDirection: isArabic ? AxisDirection.right : AxisDirection.left, controller: _controller, index: isArabic ? swiperItemCount - 1 : 0, - itemHeight: 255.h + 20, + itemHeight: 255.h + 20, // extra space for shadow pagination: SwiperPagination( alignment: Alignment.bottomCenter, @@ -1016,7 +1024,7 @@ class _LandingPageState extends State { // Main card selector based on index and priority Widget getIndexSwiperCard(int index) { - // Index 0: Priority cards (Queue > LiveCare > Upcoming Appointment > History) + // Index 0: Priority cards (InPatientServices > Queue > LiveCare > Upcoming Appointment > History) if (index == 0) { return _buildFirstCardSlot(); } @@ -1031,8 +1039,17 @@ class _LandingPageState extends State { return Container(); } + // get InPatient services card + Widget _buildInPatientCard() { + return SizedBox(width: double.infinity, child: InpatientServicesCard()); + } + // First slot: Shows highest priority card Widget _buildFirstCardSlot() { + if (inPatientServicesViewModel.isAdmitted || inPatientServicesViewModel.hasAdmissionRequest) { + return _buildInPatientCard(); + } + if (myAppointmentsViewModel.isPatientHasQueueAppointment) { return _buildQueueCard(); } @@ -1075,6 +1092,12 @@ class _LandingPageState extends State { ); } + if (myAppointmentsViewModel.patientAppointmentsHistoryList.isNotEmpty) { + return _buildAppointmentCardWrapper( + myAppointmentsViewModel.patientAppointmentsHistoryList.first, + ); + } + return Container(); // Return empty container if not enough items } diff --git a/lib/presentation/inpatient_services/general_instructions_page.dart b/lib/presentation/inpatient_services/general_instructions_page.dart new file mode 100644 index 00000000..ea74329f --- /dev/null +++ b/lib/presentation/inpatient_services/general_instructions_page.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/inpatient_services/inpatient_services_view_model.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; +import 'package:provider/provider.dart'; + +class GeneralInstructionsPage extends StatelessWidget { + const GeneralInstructionsPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: CollapsingListView( + title: "General Instructions", + child: Padding( + padding: EdgeInsets.all(24.h), + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: true, + ), + child: Consumer(builder: (context, inpatientServicesVM, child) { + return inpatientServicesVM.isGeneralInstructionsLoading + ? ListView.builder( + padding: EdgeInsets.zero, + shrinkWrap: true, + itemCount: 5, + itemBuilder: (context, index) { + return Column( + children: [ + "Lorem ipsum dolor sit amet, consectetur adipiscing elit".toText16().toShimmer2(), + SizedBox( + height: 16.h, + ), + ], + ).paddingSymmetrical(24.h, 16.h); + }, + ) + : ListView.builder( + padding: EdgeInsets.zero, + shrinkWrap: true, + itemCount: inpatientServicesVM.getGeneralInstructionsList.length, + itemBuilder: (context, index) { + final instruction = inpatientServicesVM.getGeneralInstructionsList[index]; + return "• ${instruction.text}".toText16(weight: FontWeight.w500).paddingSymmetrical(24.h, 16.h); + }, + ); + }), + ), + ), + ), + ); + } +} diff --git a/lib/presentation/inpatient_services/inpatient_services_homepage.dart b/lib/presentation/inpatient_services/inpatient_services_homepage.dart new file mode 100644 index 00000000..0e869060 --- /dev/null +++ b/lib/presentation/inpatient_services/inpatient_services_homepage.dart @@ -0,0 +1,177 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/core/utils/utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/inpatient_services/inpatient_services_view_model.dart'; +import 'package:hmg_patient_app_new/presentation/inpatient_services/general_instructions_page.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; +import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; +import 'package:provider/provider.dart'; + +import '../../generated/locale_keys.g.dart'; + +class InpatientServicesHomepage extends StatelessWidget { + InpatientServicesHomepage({super.key}); + + late InpatientServicesViewModel inPatientServicesViewModel; + + @override + Widget build(BuildContext context) { + inPatientServicesViewModel = Provider.of(context, listen: false); + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: CollapsingListView( + title: LocaleKeys.InPatientServicesHeader.tr(context: context), + child: Padding( + padding: EdgeInsets.all(24.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildInpatientServicesCard( + iconBgColor: AppColors.primaryRedColor, + icon: AppAssets.bloodSugarOnlyIcon, + title: LocaleKeys.generalConsentTitle.tr(context: context), + description: LocaleKeys.trackYourGlucoseLevels.tr(context: context), + onTap: () {}, + ), + SizedBox(height: 16.h), + buildInpatientServicesCard( + iconBgColor: AppColors.primaryRedColor, + icon: AppAssets.bloodSugarOnlyIcon, + title: LocaleKeys.generalInstructions.tr(context: context), + description: LocaleKeys.trackYourGlucoseLevels.tr(context: context), + onTap: () { + inPatientServicesViewModel.getGeneralInstructions( + projectID: inPatientServicesViewModel.isAdmitted + ? inPatientServicesViewModel.getAdmissionInfoResponseModel!.projectID! + : inPatientServicesViewModel.getAdmissionRequestInfoResponseModel!.projectId!); + Navigator.of(context).push( + CustomPageRoute( + page: GeneralInstructionsPage(), + ), + ); + }, + ), + SizedBox(height: 16.h), + buildInpatientServicesCard( + iconBgColor: AppColors.primaryRedColor, + icon: AppAssets.bloodSugarOnlyIcon, + title: LocaleKeys.medicalInstructions.tr(context: context), + description: LocaleKeys.trackYourGlucoseLevels.tr(context: context), + onTap: () {}, + ), + SizedBox(height: 16.h), + buildInpatientServicesCard( + iconBgColor: AppColors.primaryRedColor, + icon: AppAssets.bloodSugarOnlyIcon, + title: LocaleKeys.mealPlanTitle.tr(context: context), + description: LocaleKeys.trackYourGlucoseLevels.tr(context: context), + onTap: () {}, + ), + SizedBox(height: 16.h), + buildInpatientServicesCard( + iconBgColor: AppColors.primaryRedColor, + icon: AppAssets.bloodSugarOnlyIcon, + title: LocaleKeys.birthNotificationTitle.tr(context: context), + description: LocaleKeys.trackYourGlucoseLevels.tr(context: context), + onTap: () {}, + ), + SizedBox(height: 16.h), + buildInpatientServicesCard( + iconBgColor: AppColors.primaryRedColor, + icon: AppAssets.bloodSugarOnlyIcon, + title: LocaleKeys.advancePayment.tr(context: context), + description: LocaleKeys.trackYourGlucoseLevels.tr(context: context), + onTap: () {}, + ), + SizedBox(height: 16.h), + buildInpatientServicesCard( + iconBgColor: AppColors.primaryRedColor, + icon: AppAssets.bloodSugarOnlyIcon, + title: LocaleKeys.admissionNoticeTitle.tr(context: context), + description: LocaleKeys.trackYourGlucoseLevels.tr(context: context), + onTap: () {}, + ), + SizedBox(height: 16.h), + buildInpatientServicesCard( + iconBgColor: AppColors.primaryRedColor, + icon: AppAssets.bloodSugarOnlyIcon, + title: LocaleKeys.prescriptions.tr(context: context), + description: LocaleKeys.trackYourGlucoseLevels.tr(context: context), + onTap: () {}, + ), + SizedBox(height: 16.h), + buildInpatientServicesCard( + iconBgColor: AppColors.primaryRedColor, + icon: AppAssets.bloodSugarOnlyIcon, + title: LocaleKeys.patientRelationOffice.tr(context: context), + description: LocaleKeys.trackYourGlucoseLevels.tr(context: context), + onTap: () {}, + ), + SizedBox(height: 16.h), + ], + ), + ), + ), + ); + } + + Widget buildInpatientServicesCard({ + required String icon, + required String title, + required String description, + required Color iconBgColor, + required VoidCallback onTap, + }) { + return Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.r), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: iconBgColor, borderRadius: 10.r), + height: 40.w, + width: 40.w, + child: Utils.buildSvgWithAssets( + icon: icon, + fit: BoxFit.none, + height: 22.w, + width: 22.w, + ), + ), + SizedBox(width: 12.w), + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + title.toText16(isBold: true), + description.toText12( + isBold: true, + color: Color(0xFF8F9AA3), + ), + ], + ), + ), + SizedBox(width: 12.w), + Transform.flip( + flipX: getIt.get().isArabic(), + child: Utils.buildSvgWithAssets( + icon: AppAssets.arrowRight, + width: 24.w, + height: 24.h, + fit: BoxFit.contain, + iconColor: AppColors.textColor, + ), + ), + ], + ).paddingAll(16.w), + ).onPress(onTap); + } +} diff --git a/lib/presentation/inpatient_services/widgets/inpatient_services_card.dart b/lib/presentation/inpatient_services/widgets/inpatient_services_card.dart new file mode 100644 index 00000000..afcb8925 --- /dev/null +++ b/lib/presentation/inpatient_services/widgets/inpatient_services_card.dart @@ -0,0 +1,108 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; +import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; +import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; +import 'package:hmg_patient_app_new/features/inpatient_services/inpatient_services_view_model.dart'; +import 'package:hmg_patient_app_new/presentation/inpatient_services/inpatient_services_homepage.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; +import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; +import 'package:provider/provider.dart'; + +import '../../../generated/locale_keys.g.dart'; + +class InpatientServicesCard extends StatelessWidget { + const InpatientServicesCard({super.key}); + + @override + Widget build(BuildContext context) { + return Consumer(builder: (context, inpatientServicesVM, child) { + return Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: true, + ), + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Wrap( + alignment: WrapAlignment.start, + direction: Axis.horizontal, + spacing: 6.w, + runSpacing: 6.h, + children: [ + AppCustomChipWidget( + labelText: inpatientServicesVM.isAdmitted ? LocaleKeys.InPatient.tr(context: context) : LocaleKeys.admissionReq.tr(context: context), + backgroundColor: AppColors.textColor, + textColor: AppColors.whiteColor, + ), + inpatientServicesVM.isAdmitted + ? AppCustomChipWidget( + labelText: "Room: ${inpatientServicesVM.getAdmissionInfoResponseModel!.roomID} • Bed: ${inpatientServicesVM.getAdmissionInfoResponseModel!.bedID}", + backgroundColor: AppColors.infoColor.withAlpha(30), + textColor: AppColors.infoColor, + ) + : SizedBox(), + ], + ), + SizedBox(height: 24.h), + inpatientServicesVM.isAdmitted + ? "${LocaleKeys.admissionNo.tr(context: context)}: ${inpatientServicesVM.getAdmissionInfoResponseModel!.admissionNo}".toText16(isBold: true) + : "${LocaleKeys.admissionReqNo.tr(context: context)}: ${inpatientServicesVM.getAdmissionRequestInfoResponseModel!.admissionRequestNo}".toText16(isBold: true), + SizedBox(height: 8.h), + Wrap( + alignment: WrapAlignment.start, + direction: Axis.horizontal, + spacing: 6.w, + runSpacing: 6.h, + children: [ + AppCustomChipWidget( + labelText: inpatientServicesVM.isAdmitted + ? "${LocaleKeys.clinicName.tr(context: context)}: ${inpatientServicesVM.getAdmissionInfoResponseModel!.clinicName}" + : "${LocaleKeys.clinicName.tr(context: context)}: ${inpatientServicesVM.getAdmissionRequestInfoResponseModel!.clinicName}", + ), + AppCustomChipWidget( + labelText: inpatientServicesVM.isAdmitted + ? "${LocaleKeys.branch.tr(context: context)} ${inpatientServicesVM.getAdmissionInfoResponseModel!.projectName}" + : "${LocaleKeys.branch.tr(context: context)} ${inpatientServicesVM.getAdmissionRequestInfoResponseModel!.projectName}", + ), + AppCustomChipWidget( + labelText: inpatientServicesVM.isAdmitted + ? "${LocaleKeys.admissionDate.tr(context: context)}: ${DateUtil.formatDateToDate(DateUtil.convertStringToDate(inpatientServicesVM.getAdmissionInfoResponseModel!.admissionDate), false)}" + : "${LocaleKeys.admissionRequestDate.tr(context: context)}: ${DateUtil.formatDateToDate(DateUtil.convertStringToDate(inpatientServicesVM.getAdmissionRequestInfoResponseModel!.expectedAdmissionDate), false)}", + ), + ], + ), + SizedBox(height: 16.h), + CustomButton( + text: LocaleKeys.viewDetails.tr(context: context), + onPressed: () { + Navigator.of(context).push( + CustomPageRoute( + page: InpatientServicesHomepage(), + ), + ); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: (isFoldable || isTablet) ? 12.f : 14.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + padding: EdgeInsets.symmetric(horizontal: 10.w), + height: isFoldable ? 36.h : 40.h, + ) + ], + ), + ), + ); + }); + } +}