diff --git a/assets/images/svg/E_Referral.svg b/assets/images/svg/E_Referral.svg new file mode 100644 index 00000000..fb6b8591 --- /dev/null +++ b/assets/images/svg/E_Referral.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/images/svg/covid_19.svg b/assets/images/svg/covid_19.svg new file mode 100644 index 00000000..f3aa1287 --- /dev/null +++ b/assets/images/svg/covid_19.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/svg/file.svg b/assets/images/svg/file.svg new file mode 100644 index 00000000..004145cd --- /dev/null +++ b/assets/images/svg/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/svg/files.svg b/assets/images/svg/files.svg new file mode 100644 index 00000000..dfc862e3 --- /dev/null +++ b/assets/images/svg/files.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/images/svg/gallery.svg b/assets/images/svg/gallery.svg new file mode 100644 index 00000000..ec1c45ef --- /dev/null +++ b/assets/images/svg/gallery.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/images/svg/open_camera.svg b/assets/images/svg/open_camera.svg new file mode 100644 index 00000000..171452a0 --- /dev/null +++ b/assets/images/svg/open_camera.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/svg/rate_1.svg b/assets/images/svg/rate_1.svg new file mode 100644 index 00000000..8e1c2f22 --- /dev/null +++ b/assets/images/svg/rate_1.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/rate_2.svg b/assets/images/svg/rate_2.svg new file mode 100644 index 00000000..9500556e --- /dev/null +++ b/assets/images/svg/rate_2.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/rate_3.svg b/assets/images/svg/rate_3.svg new file mode 100644 index 00000000..7c9d0f54 --- /dev/null +++ b/assets/images/svg/rate_3.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/rate_4.svg b/assets/images/svg/rate_4.svg new file mode 100644 index 00000000..7f822679 --- /dev/null +++ b/assets/images/svg/rate_4.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/svg/rate_5.svg b/assets/images/svg/rate_5.svg new file mode 100644 index 00000000..a7308ba5 --- /dev/null +++ b/assets/images/svg/rate_5.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 787a7183..b8fc7ebb 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -876,5 +876,6 @@ "endDate": "تاريخ الانتهاء", "walkin": "زيارة بدون موعد", "laserClinic": "عيادة الليزر", - "continueString": "يكمل" + "continueString": "يكمل", + "covid_info": "تجري مستشفيات د. سليمان الحبيب فحص فيروس كورونا المستجد وتصدر شهادات السفر على مدار الساعة، طوال أيام الأسبوع، وبسرعة ودقة عالية. يمكن للراغبين في الاستفادة من هذه الخدمة زيارة أحد فروع مستشفيات د. سليمان الحبيب وإجراء فحص كورونا خلال بضع دقائق والحصول على النتائج خلال عدة ساعات خدمة فحص فيروس كورونا Covid 19 بتقنية PCR للكشف عن الفيروس وفقاً لأعلى المعايير العالمية وبأحدث أجهزة RT-PCR عالية الدقة (GeneXpert الأمريكي وغيره)، وهي طرق معتمدة من قبل هيئة الغذاء والدواء وكذلك من قبل المركز السعودي للوقاية من الأمراض المُعدية" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 7b8c4b83..7839083c 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -872,6 +872,6 @@ "searchClinic": "Search Clinic", "walkin": "Walk In", "continueString": "Continue", - "laserClinic": "Laser Clinic" - + "laserClinic": "Laser Clinic", + "covid_info" :"Dr. Sulaiman Al Habib hospitals are conducting a test for the emerging corona virus and issuing travel certificates 24/7 in a short time and with high accuracy. Those wishing to benefit from this service can visit one of Dr. Sulaiman Al Habib branches to conduct a corona test within few minutes, and obtain the result within several hours. Corona Virus Covid 19 testing service with PCR technology to detect the virus according to the highest international standards and with the latest high-precision RT-PCR devices (American GeneXpert and others), That is approved by the Food and Drug Authority as well as by the Saudi Center for Infectious Diseases Prevention." } \ No newline at end of file diff --git a/lib/core/api_consts.dart b/lib/core/api_consts.dart index f0db3084..66b9b7ec 100644 --- a/lib/core/api_consts.dart +++ b/lib/core/api_consts.dart @@ -14,8 +14,8 @@ var PACKAGES_ORDERS = '/api/orders'; var PACKAGES_ORDER_HISTORY = '/api/orders/items'; var PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; // var BASE_URL = 'http://10.50.100.198:2018/'; -var BASE_URL = 'https://uat.hmgwebservices.com/'; -// var BASE_URL = 'https://hmgwebservices.com/'; +// var BASE_URL = 'https://uat.hmgwebservices.com/'; +var BASE_URL = 'https://hmgwebservices.com/'; // var BASE_URL = 'http://10.201.204.103/'; // var BASE_URL = 'https://orash.cloudsolutions.com.sa/'; // var BASE_URL = 'https://vidauat.cloudsolutions.com.sa/'; @@ -700,7 +700,7 @@ var GET_PRESCRIPTION_INSTRUCTIONS_PDF = 'Services/ChatBot_Service.svc/REST/Chatb class ApiConsts { static const maxSmallScreen = 660; - static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.uat; + static AppEnvironmentTypeEnum appEnvironmentType = AppEnvironmentTypeEnum.prod; // static String baseUrl = 'https://uat.hmgwebservices.com/'; // HIS API URL UAT diff --git a/lib/core/app_assets.dart b/lib/core/app_assets.dart index f85ac797..3c11b096 100644 --- a/lib/core/app_assets.dart +++ b/lib/core/app_assets.dart @@ -262,6 +262,8 @@ class AppAssets { static const String pregnancyDayAccordion = '$svgBasePath/pregnancy_test_day_accordion.svg'; static const String pregnancyDueDateAccordion = '$svgBasePath/due_date_accordion.svg'; + static const String covid19icon = '$svgBasePath/covid_19.svg'; + // PNGS // static const String hmgLogo = '$pngBasePath/hmg_logo.png'; static const String liveCareService = '$pngBasePath/livecare_service.png'; @@ -287,6 +289,9 @@ class AppAssets { static const String fullBodyFront = '$pngBasePath/full_body_front.png'; static const String fullBodyBack = '$pngBasePath/full_body_back.png'; + + + } class AppAnimations { @@ -307,5 +312,7 @@ class AppAnimations { static const String ambulance = '$lottieBasePath/ambulance.json'; static const String ambulanceAlert = '$lottieBasePath/ambulance_alert.json'; static const String rrtAmbulance = '$lottieBasePath/rrt_ambulance.json'; + + } diff --git a/lib/core/app_state.dart b/lib/core/app_state.dart index c8659a7f..e1d6e05b 100644 --- a/lib/core/app_state.dart +++ b/lib/core/app_state.dart @@ -4,10 +4,8 @@ import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:gms_check/gms_check.dart'; import 'package:hmg_patient_app_new/core/common_models/privilege/HMCProjectListModel.dart'; -import 'package:hmg_patient_app_new/core/common_models/privilege/PrivilegeModel.dart'; import 'package:hmg_patient_app_new/core/common_models/privilege/ProjectDetailListModel.dart'; import 'package:hmg_patient_app_new/core/common_models/privilege/VidaPlusProjectListModel.dart'; -import 'package:hmg_patient_app_new/features/authentication/models/request_models/send_activation_request_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_user_staus_nhic_response_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart'; @@ -45,7 +43,7 @@ class AppState { bool isChildLoggedIn = false; bool isGMSAvailable = true; bool isAndroid = true; - + bool isRatedVisible =false; void setAuthenticatedUser(AuthenticatedUser? authenticatedUser, {bool isFamily = false}) { if (isFamily) { _authenticatedChildUser = authenticatedUser; @@ -172,4 +170,8 @@ class AppState { userLong = 0.0; userLong = 0.0; } + + setRatedVisible(bool value) { + isRatedVisible = value; + } } diff --git a/lib/core/exceptions/api_exception.dart b/lib/core/exceptions/api_exception.dart index eb11b71e..eb0258fc 100644 --- a/lib/core/exceptions/api_exception.dart +++ b/lib/core/exceptions/api_exception.dart @@ -1,7 +1,5 @@ import 'dart:convert'; -import 'package:equatable/equatable.dart'; -import 'package:hmg_patient_app_new/core/api/api_client.dart'; class APIException implements Exception { static const String BAD_REQUEST = 'api_common_bad_request'; diff --git a/lib/core/utils/doctor_response_mapper.dart b/lib/core/utils/doctor_response_mapper.dart index 994e9a17..05ed2fdc 100644 --- a/lib/core/utils/doctor_response_mapper.dart +++ b/lib/core/utils/doctor_response_mapper.dart @@ -1,7 +1,5 @@ import 'dart:math'; -import 'package:hmg_patient_app_new/core/cache_consts.dart' show CacheConst; -import 'package:hmg_patient_app_new/core/utils/utils.dart' show Utils; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/doctors_list_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart' show RegionList, PatientDoctorAppointmentList, DoctorList, PatientDoctorAppointmentListByRegion; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart' show HospitalsModel; diff --git a/lib/core/utils/push_notification_handler.dart b/lib/core/utils/push_notification_handler.dart index ee05335f..a96b8050 100644 --- a/lib/core/utils/push_notification_handler.dart +++ b/lib/core/utils/push_notification_handler.dart @@ -18,10 +18,8 @@ import 'package:flutter_ios_voip_kit_karmm/flutter_ios_voip_kit.dart'; // import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; -import 'package:get_it/get_it.dart'; import 'package:hmg_patient_app_new/core/utils/local_notifications.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; -import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:uuid/uuid.dart'; diff --git a/lib/core/utils/size_config.dart b/lib/core/utils/size_config.dart index 9f9d8358..0f8766a3 100644 --- a/lib/core/utils/size_config.dart +++ b/lib/core/utils/size_config.dart @@ -1,6 +1,5 @@ import 'package:flutter/cupertino.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; -import 'package:hmg_patient_app_new/core/cache_consts.dart'; class SizeConfig { static double _blockWidth = 0; diff --git a/lib/extensions/int_extensions.dart b/lib/extensions/int_extensions.dart index 80b31715..75460c57 100644 --- a/lib/extensions/int_extensions.dart +++ b/lib/extensions/int_extensions.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:hmg_patient_app_new/theme/colors.dart'; extension IntExtensions on int { Widget get height => SizedBox(height: toDouble()); diff --git a/lib/features/authentication/authentication_repo.dart b/lib/features/authentication/authentication_repo.dart index 47af20bb..4a1517c3 100644 --- a/lib/features/authentication/authentication_repo.dart +++ b/lib/features/authentication/authentication_repo.dart @@ -5,10 +5,8 @@ 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/app_state.dart'; import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; -import 'package:hmg_patient_app_new/core/common_models/privilege/PrivilegeModel.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/exceptions/api_failure.dart'; -import 'package:hmg_patient_app_new/features/authentication/models/request_models/check_activation_code_register_request_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; diff --git a/lib/features/authentication/authentication_view_model.dart b/lib/features/authentication/authentication_view_model.dart index faedcd82..46649fb0 100644 --- a/lib/features/authentication/authentication_view_model.dart +++ b/lib/features/authentication/authentication_view_model.dart @@ -27,7 +27,6 @@ import 'package:hmg_patient_app_new/features/authentication/models/resp_models/a import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_activation_code_resp_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/check_user_staus_nhic_response_model.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/select_device_by_imei.dart'; -import 'package:hmg_patient_app_new/features/medical_file/medical_file_repo.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; diff --git a/lib/features/blood_donation/blood_donation_repo.dart b/lib/features/blood_donation/blood_donation_repo.dart index 84997b24..dce09753 100644 --- a/lib/features/blood_donation/blood_donation_repo.dart +++ b/lib/features/blood_donation/blood_donation_repo.dart @@ -66,6 +66,7 @@ class BloodDonationRepoImp implements BloodDonationRepo { await apiClient.post( GET_BLOOD_REQUEST, body: mapDevice, + isAllowAny: true, onFailure: (error, statusCode, {messageStatus, failureType}) { failure = failureType; }, diff --git a/lib/features/blood_donation/blood_donation_view_model.dart b/lib/features/blood_donation/blood_donation_view_model.dart index f3453596..b8f0e9ca 100644 --- a/lib/features/blood_donation/blood_donation_view_model.dart +++ b/lib/features/blood_donation/blood_donation_view_model.dart @@ -1,6 +1,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_repo.dart'; import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_list_model.dart'; import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_response_model.dart'; @@ -31,7 +32,7 @@ class BloodDonationViewModel extends ChangeNotifier { List genderList = [ BloodGroupListModel(LocaleKeys.malE.tr(), 1), - BloodGroupListModel(LocaleKeys.female.tr(), 2), + BloodGroupListModel("Female".needTranslation.tr(), 2), ]; late CitiesModel selectedCity; diff --git a/lib/features/book_appointments/book_appointments_repo.dart b/lib/features/book_appointments/book_appointments_repo.dart index 3683d578..f6e83ff1 100644 --- a/lib/features/book_appointments/book_appointments_repo.dart +++ b/lib/features/book_appointments/book_appointments_repo.dart @@ -1,4 +1,3 @@ -import 'dart:io'; import 'package:dartz/dartz.dart'; import 'package:hmg_patient_app_new/core/api/api_client.dart'; @@ -26,9 +25,12 @@ abstract class BookAppointmentsRepo { Future>>> getDoctorsList(int clinicID, int projectID, bool isNearest, int doctorId, String doctorName, {isContinueDentalPlan = false}); + Future>>> getDoctorsListByHealthCal(int calculationID); + Future>> getDoctorProfile(int clinicID, int projectID, int doctorId, {Function(dynamic)? onSuccess, Function(String)? onError}); - Future>> getDoctorFreeSlots(int clinicID, int projectID, int doctorId, bool isBookingForLiveCare, {bool continueDentalPlan = false, Function(dynamic)? onSuccess, Function(String)? onError}); + Future>> getDoctorFreeSlots(int clinicID, int projectID, int doctorId, bool isBookingForLiveCare, + {bool continueDentalPlan = false, Function(dynamic)? onSuccess, Function(String)? onError}); Future>> cancelAppointment({required PatientAppointmentHistoryResponseModel patientAppointmentHistoryResponseModel}); @@ -83,8 +85,7 @@ abstract class BookAppointmentsRepo { Future>>> getDentalChiefComplaintDoctorsList(int projectID, int chiefComplaintID, {Function(dynamic)? onSuccess, Function(String)? onError}); - Future>>> getLaserClinics(int laserCategoryID, int projectID, int languageID, - {Function(dynamic)? onSuccess, Function(String)? onError}); + Future>>> getLaserClinics(int laserCategoryID, int projectID, int languageID, {Function(dynamic)? onSuccess, Function(String)? onError}); Future>> checkScannedNFCAndQRCode(String nfcCode, int projectId, {Function(dynamic)? onSuccess, Function(String)? onError}); @@ -206,6 +207,45 @@ class BookAppointmentsRepoImp implements BookAppointmentsRepo { } } + @override + Future>>> getDoctorsListByHealthCal(int calculationID, {Function(dynamic)? onSuccess, Function(String)? onError}) async { + Map mapDevice = {"CalculationID": calculationID}; + + try { + GenericApiModel>? apiResponse; + Failure? failure; + await apiClient.post( + GET_DOCTOR_LIST_CALCULATION, + body: mapDevice, + onFailure: (error, statusCode, {messageStatus, failureType}) { + failure = failureType; + onError!(error); + }, + onSuccess: (response, statusCode, {messageStatus, errorMessage}) { + try { + final list = response['List_CalculationTable']; + + final doctorsList = list.map((item) => DoctorsListResponseModel.fromJson(item as Map)).toList().cast(); + + apiResponse = GenericApiModel>( + messageStatus: messageStatus, + statusCode: statusCode, + errorMessage: null, + data: doctorsList, + ); + } 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>> getDoctorProfile(int clinicID, int projectID, int doctorId, {Function(dynamic)? onSuccess, Function(String)? onError}) async { Map mapDevice = { @@ -824,7 +864,8 @@ class BookAppointmentsRepoImp implements BookAppointmentsRepo { } @override - Future>>> getLaserClinics(int laserCategoryID, int projectID, int languageID, {Function(dynamic p1)? onSuccess, Function(String p1)? onError}) async { + Future>>> getLaserClinics(int laserCategoryID, int projectID, int languageID, + {Function(dynamic p1)? onSuccess, Function(String p1)? onError}) async { Map mapDevice = { "LaserCategoryID": laserCategoryID, "ProjectID": projectID, diff --git a/lib/features/book_appointments/book_appointments_view_model.dart b/lib/features/book_appointments/book_appointments_view_model.dart index d96cb4f1..ae74ffb7 100644 --- a/lib/features/book_appointments/book_appointments_view_model.dart +++ b/lib/features/book_appointments/book_appointments_view_model.dart @@ -46,9 +46,14 @@ class BookAppointmentsViewModel extends ChangeNotifier { bool isDoctorSearchByNameStarted = false; bool isLiveCareSchedule = false; + bool isGetDocForHealthCal = false; + int? calculationID = 0; + bool isSortByClinic = true; int initialSlotDuration = 0; + bool isNearestAppointmentSelected = false; + LocationUtils locationUtils; List clinicsList = []; @@ -61,6 +66,11 @@ class BookAppointmentsViewModel extends ChangeNotifier { List doctorsList = []; List filteredDoctorList = []; + // Grouped doctors lists + List> doctorsListByClinic = []; + List> doctorsListByHospital = []; + List> doctorsListGrouped = []; + List liveCareDoctorsList = []; List patientDentalPlanEstimationList = []; @@ -143,6 +153,31 @@ class BookAppointmentsViewModel extends ChangeNotifier { bool isBodyPartsLoading = false; int duration = 0; + + setIsSortByClinic(bool value) { + isSortByClinic = value; + doctorsListGrouped = isSortByClinic ? doctorsListByClinic : doctorsListByHospital; + notifyListeners(); + } + + // Group doctors by clinic and hospital + void _groupDoctorsList() { + final clinicMap = >{}; + final hospitalMap = >{}; + + for (var doctor in doctorsList) { + final clinicKey = (doctor.clinicName ?? 'Unknown').trim(); + clinicMap.putIfAbsent(clinicKey, () => []).add(doctor); + + final hospitalKey = (doctor.projectName ?? 'Unknown').trim(); + hospitalMap.putIfAbsent(hospitalKey, () => []).add(doctor); + } + + doctorsListByClinic = clinicMap.values.toList(); + doctorsListByHospital = hospitalMap.values.toList(); + doctorsListGrouped = isSortByClinic ? doctorsListByClinic : doctorsListByHospital; + } + BookAppointmentsViewModel( {required this.bookAppointmentsRepo, required this.errorHandlerService, @@ -187,6 +222,18 @@ class BookAppointmentsViewModel extends ChangeNotifier { notifyListeners(); } + setIsNearestAppointmentSelected(bool isNearestAppointmentSelected) { + this.isNearestAppointmentSelected = isNearestAppointmentSelected; + + if (isNearestAppointmentSelected) { + doctorsList.sort((a, b) => DateUtil.convertStringToDate(a.nearestFreeSlot!).compareTo(DateUtil.convertStringToDate(b.nearestFreeSlot!))); + } else { + doctorsList.sort((a, b) => b.decimalDoctorRate!.compareTo(a.decimalDoctorRate!)); + } + + notifyListeners(); + } + setIsWaitingAppointmentSelected(bool isWaitingAppointmentSelected) { this.isWaitingAppointmentSelected = isWaitingAppointmentSelected; notifyListeners(); @@ -280,6 +327,8 @@ class BookAppointmentsViewModel extends ChangeNotifier { } void onTabChanged(int index) { + calculationID = null; + isGetDocForHealthCal = false; selectedTabIndex = index; notifyListeners(); } @@ -319,8 +368,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { Future getLiveCareScheduleClinics({Function(dynamic)? onSuccess, Function(String)? onError}) async { liveCareClinicsList.clear(); - final result = - await bookAppointmentsRepo.getLiveCareScheduleClinics(_appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!); + final result = await bookAppointmentsRepo.getLiveCareScheduleClinics(_appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!); result.fold( (failure) async => await errorHandlerService.handleError(failure: failure), @@ -342,9 +390,8 @@ class BookAppointmentsViewModel extends ChangeNotifier { Future getLiveCareDoctorsList({Function(dynamic)? onSuccess, Function(String)? onError}) async { doctorsList.clear(); - final result = await bookAppointmentsRepo.getLiveCareDoctorsList( - selectedLiveCareClinic.serviceID!, _appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!, - onError: onError); + final result = + await bookAppointmentsRepo.getLiveCareDoctorsList(selectedLiveCareClinic.serviceID!, _appState.getAuthenticatedUser()!.age!, _appState.getAuthenticatedUser()!.gender!, onError: onError); result.fold( (failure) async { @@ -367,11 +414,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { } //TODO: Make the API dynamic with parameters for ProjectID, isNearest, languageID, doctorId, doctorName - Future getDoctorsList( - {int projectID = 0, bool isNearest = true, int doctorId = 0, - String doctorName = "", - Function(dynamic)? onSuccess, - Function(String)? onError}) async { + Future getDoctorsList({int projectID = 0, bool isNearest = true, int doctorId = 0, String doctorName = "", Function(dynamic)? onSuccess, Function(String)? onError}) async { doctorsList.clear(); projectID = currentlySelectedHospitalFromRegionFlow != null ? int.parse(currentlySelectedHospitalFromRegionFlow!) : projectID; final result = @@ -391,9 +434,43 @@ class BookAppointmentsViewModel extends ChangeNotifier { doctorsList = apiResponse.data!; filteredDoctorList = doctorsList; isDoctorsListLoading = false; + doctorsList.sort((a, b) => b.decimalDoctorRate!.compareTo(a.decimalDoctorRate!)); + initializeFilteredList(); + clearSearchFilters(); + getFiltersFromDoctorList(); + _groupDoctorsList(); + notifyListeners(); + if (onSuccess != null) { + onSuccess(apiResponse); + } + } + }, + ); + } + + //TODO: GetDockets & Calculations For Health Calculator + Future getDoctorsListByHealthCal({Function(dynamic)? onSuccess, Function(String)? onError}) async { + doctorsList.clear(); + final result = await bookAppointmentsRepo.getDoctorsListByHealthCal(calculationID!); + result.fold( + (failure) async { + isDoctorsListLoading = false; + if (onError != null) onError("No doctors found for the search criteria".needTranslation); + + notifyListeners(); + }, + (apiResponse) { + if (apiResponse.messageStatus == 2) { + // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); + } else if (apiResponse.messageStatus == 1) { + doctorsList = apiResponse.data!; + setIsSortByClinic(true); + filteredDoctorList = doctorsList; + isDoctorsListLoading = false; initializeFilteredList(); clearSearchFilters(); getFiltersFromDoctorList(); + _groupDoctorsList(); notifyListeners(); if (onSuccess != null) { onSuccess(apiResponse); @@ -404,13 +481,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { } Future getMappedDoctors( - {int projectID = 0, - bool isNearest = false, - int doctorId = 0, - String doctorName = "", - isContinueDentalPlan = false, - Function(dynamic)? onSuccess, - Function(String)? onError}) async { + {int projectID = 0, bool isNearest = false, int doctorId = 0, String doctorName = "", isContinueDentalPlan = false, Function(dynamic)? onSuccess, Function(String)? onError}) async { filteredHospitalList = null; hospitalList = null; isRegionListLoading = true; @@ -446,8 +517,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { } Future getDoctorProfile({Function(dynamic)? onSuccess, Function(String)? onError}) async { - final result = await bookAppointmentsRepo - .getDoctorProfile(selectedDoctor.clinicID ?? 0, selectedDoctor.projectID ?? 0, selectedDoctor.doctorID ?? 0, onError: onError); + final result = await bookAppointmentsRepo.getDoctorProfile(selectedDoctor.clinicID ?? 0, selectedDoctor.projectID ?? 0, selectedDoctor.doctorID ?? 0, onError: onError); result.fold( (failure) async {}, @@ -506,8 +576,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { // : date = DateUtil.convertStringToDateSaudiTimezone(element, int.parse(selectedDoctor.projectID.toString())); slotsList.add(FreeSlot(date, ['slot'])); - docFreeSlots.add(TimeSlot( - isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date, vidaDate: element)); + docFreeSlots.add(TimeSlot(isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date, vidaDate: element)); }); notifyListeners(); @@ -526,8 +595,8 @@ class BookAppointmentsViewModel extends ChangeNotifier { final DateFormat dateFormatter = DateFormat('yyyy-MM-dd'); Map _eventsParsed; - final result = await bookAppointmentsRepo.getLiveCareDoctorFreeSlots(selectedDoctor.clinicID ?? 0, selectedLiveCareClinic.serviceID ?? 0, - selectedDoctor.projectID ?? 0, selectedDoctor.doctorID ?? 0, isBookingForLiveCare, + final result = await bookAppointmentsRepo.getLiveCareDoctorFreeSlots( + selectedDoctor.clinicID ?? 0, selectedLiveCareClinic.serviceID ?? 0, selectedDoctor.projectID ?? 0, selectedDoctor.doctorID ?? 0, isBookingForLiveCare, onError: onError); result.fold( @@ -551,8 +620,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { // : date = DateUtil.convertStringToDateSaudiTimezone(element, int.parse(selectedDoctor.projectID.toString())); slotsList.add(FreeSlot(date, ['slot'])); - docFreeSlots.add(TimeSlot( - isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date, vidaDate: element)); + docFreeSlots.add(TimeSlot(isoTime: formatter.format(date), start: new DateTime(date.year, date.month, date.day, 0, 0, 0, 0), end: date, vidaDate: element)); }); notifyListeners(); @@ -564,10 +632,7 @@ class BookAppointmentsViewModel 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 bookAppointmentsRepo.cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel); result.fold( @@ -651,15 +716,13 @@ class BookAppointmentsViewModel extends ChangeNotifier { await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel).then((val) async { navigationService.pop(); Future.delayed(Duration(milliseconds: 50)).then((value) async {}); - LoadingUtils.showFullScreenLoader( - barrierDismissible: true, isSuccessDialog: false, loadingText: "Booking your appointment...".needTranslation); + LoadingUtils.showFullScreenLoader(barrierDismissible: true, isSuccessDialog: false, loadingText: "Booking your appointment...".needTranslation); await insertSpecificAppointment( onError: (err) {}, onSuccess: (apiResp) async { LoadingUtils.hideFullScreenLoader(); await Future.delayed(Duration(milliseconds: 50)).then((value) async { - LoadingUtils.showFullScreenLoader( - barrierDismissible: true, isSuccessDialog: true, loadingText: LocaleKeys.appointmentSuccess.tr()); + LoadingUtils.showFullScreenLoader(barrierDismissible: true, isSuccessDialog: true, loadingText: LocaleKeys.appointmentSuccess.tr()); await Future.delayed(Duration(milliseconds: 4000)).then((value) { LoadingUtils.hideFullScreenLoader(); Navigator.pushAndRemoveUntil( @@ -749,15 +812,13 @@ class BookAppointmentsViewModel extends ChangeNotifier { await cancelAppointment(patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel).then((val) async { navigationService.pop(); Future.delayed(Duration(milliseconds: 50)).then((value) async {}); - LoadingUtils.showFullScreenLoader( - barrierDismissible: true, isSuccessDialog: false, loadingText: "Booking your appointment...".needTranslation); + LoadingUtils.showFullScreenLoader(barrierDismissible: true, isSuccessDialog: false, loadingText: "Booking your appointment...".needTranslation); await insertSpecificAppointment( onError: (err) {}, onSuccess: (apiResp) async { LoadingUtils.hideFullScreenLoader(); await Future.delayed(Duration(milliseconds: 50)).then((value) async { - LoadingUtils.showFullScreenLoader( - barrierDismissible: true, isSuccessDialog: true, loadingText: LocaleKeys.appointmentSuccess.tr()); + LoadingUtils.showFullScreenLoader(barrierDismissible: true, isSuccessDialog: true, loadingText: LocaleKeys.appointmentSuccess.tr()); await Future.delayed(Duration(milliseconds: 4000)).then((value) { LoadingUtils.hideFullScreenLoader(); Navigator.pushAndRemoveUntil( @@ -831,9 +892,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { } else { filteredHospitalList = RegionList(); - var list = isHMG - ? hospitalList?.registeredDoctorMap![selectedRegionId]!.hmgDoctorList - : hospitalList?.registeredDoctorMap![selectedRegionId]!.hmcDoctorList; + var list = isHMG ? hospitalList?.registeredDoctorMap![selectedRegionId]!.hmgDoctorList : hospitalList?.registeredDoctorMap![selectedRegionId]!.hmcDoctorList; if (list != null && list.isEmpty) { notifyListeners(); @@ -916,8 +975,8 @@ class BookAppointmentsViewModel extends ChangeNotifier { notifyListeners(); } - void setSelections(List? selectedFacilityForFilters, List? selectedRegionForFilters, String? selectedClinicForFilters, - PatientDoctorAppointmentList? selectedHospitalForFilters, bool applyFilters) { + void setSelections( + List? selectedFacilityForFilters, List? selectedRegionForFilters, String? selectedClinicForFilters, PatientDoctorAppointmentList? selectedHospitalForFilters, bool applyFilters) { this.selectedFacilityForFilters = selectedFacilityForFilters; this.selectedClinicForFilters = selectedClinicForFilters; this.selectedHospitalForFilters = selectedHospitalForFilters; @@ -985,15 +1044,11 @@ class BookAppointmentsViewModel extends ChangeNotifier { List getDoctorListAsPerSelection() { if (!applyFilters) return doctorsList; - if ((selectedRegionForFilters?.isEmpty == true) && - (selectedFacilityForFilters?.isEmpty == true) && - selectedClinicForFilters == null && - selectedHospitalForFilters == null) { + if ((selectedRegionForFilters?.isEmpty == true) && (selectedFacilityForFilters?.isEmpty == true) && selectedClinicForFilters == null && selectedHospitalForFilters == null) { return doctorsList; } var list = doctorsList.where((element) { - var isInSelectedRegion = - (selectedRegionForFilters?.isEmpty == true) ? true : selectedRegionForFilters?.any((region) => region == element.getRegionName(isArabic())); + var isInSelectedRegion = (selectedRegionForFilters?.isEmpty == true) ? true : selectedRegionForFilters?.any((region) => region == element.getRegionName(isArabic())); var shouldApplyFacilityFilter = (selectedFacilityForFilters?.isEmpty == true) ? false : true; var isHMC = (selectedFacilityForFilters?.isEmpty == true) ? true : selectedFacilityForFilters?.any((item) => item.contains("hmc")); var isInSelectedClinic = (selectedClinicForFilters == null) ? true : selectedClinicForFilters == element.clinicName; @@ -1044,8 +1099,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { dentalChiefComplaintsList.clear(); notifyListeners(); int patientID = _appState.isAuthenticated ? _appState.getAuthenticatedUser()!.patientId ?? -1 : -1; - final result = await bookAppointmentsRepo.getDentalChiefComplaintsList( - patientID: patientID, projectID: int.parse(currentlySelectedHospitalFromRegionFlow ?? "0"), clinicID: 17); + final result = await bookAppointmentsRepo.getDentalChiefComplaintsList(patientID: patientID, projectID: int.parse(currentlySelectedHospitalFromRegionFlow ?? "0"), clinicID: 17); result.fold( (failure) async => await errorHandlerService.handleError(failure: failure), @@ -1084,6 +1138,7 @@ class BookAppointmentsViewModel extends ChangeNotifier { // initializeFilteredList(); // clearSearchFilters(); // getFiltersFromDoctorList(); + _groupDoctorsList(); notifyListeners(); if (onSuccess != null) { onSuccess(apiResponse); diff --git a/lib/features/book_appointments/models/resp_models/doctors_list_response_model.dart b/lib/features/book_appointments/models/resp_models/doctors_list_response_model.dart index 5df6ed8b..75ed1229 100644 --- a/lib/features/book_appointments/models/resp_models/doctors_list_response_model.dart +++ b/lib/features/book_appointments/models/resp_models/doctors_list_response_model.dart @@ -65,75 +65,77 @@ class DoctorsListResponseModel { String? regionID; String? projectBottomName; String? projectTopName; + int? calcID; - - DoctorsListResponseModel( - {this.clinicID, - this.clinicName, - this.clinicNameN, - this.doctorTitle, - this.iD, - this.name, - this.projectID, - this.projectName, - this.actualDoctorRate, - this.clinicRoomNo, - this.date, - this.dayName, - this.decimalDoctorRate, - this.doctorAvailability, - this.doctorID, - this.doctorImageURL, - this.doctorMobileNumber, - this.doctorProfile, - this.doctorProfileInfo, - this.doctorRate, - this.doctorStarsRate, - this.employmentType, - this.gender, - this.genderDescription, - this.hISRegionId, - this.isActive, - this.isAllowWaitList, - this.isAppointmentAllowed, - this.isDoctorAllowVedioCall, - this.isDoctorDummy, - this.isDoctorHasPrePostImages, - this.isHMC, - this.isHmg, - this.isLiveCare, - this.latitude, - this.longitude, - this.nationalityFlagURL, - this.nationalityID, - this.nationalityName, - this.nearestFreeSlot, - this.noOfFreeSlotsAvailable, - this.noOfPatientsRate, - this.originalClinicID, - this.personRate, - this.projectDistanceInKiloMeters, - this.projectNameBottom, - this.projectNameTop, - this.qR, - this.qRString, - this.rateNumber, - this.regionName, - this.regionNameN, - this.serviceID, - this.setupID, - this.speciality, - this.specialityN, - this.transactionType, - this.virtualEmploymentType, - this.workingHours, - this.vida3Id, - this.region, - this.regionArabic, - this.regionEnglish, - this.regionID, - this.projectBottomName, - this.projectTopName,}); + DoctorsListResponseModel({ + this.clinicID, + this.clinicName, + this.clinicNameN, + this.doctorTitle, + this.iD, + this.name, + this.projectID, + this.projectName, + this.actualDoctorRate, + this.clinicRoomNo, + this.date, + this.dayName, + this.decimalDoctorRate, + this.doctorAvailability, + this.doctorID, + this.doctorImageURL, + this.doctorMobileNumber, + this.doctorProfile, + this.doctorProfileInfo, + this.doctorRate, + this.doctorStarsRate, + this.employmentType, + this.gender, + this.genderDescription, + this.hISRegionId, + this.isActive, + this.isAllowWaitList, + this.isAppointmentAllowed, + this.isDoctorAllowVedioCall, + this.isDoctorDummy, + this.isDoctorHasPrePostImages, + this.isHMC, + this.isHmg, + this.isLiveCare, + this.latitude, + this.longitude, + this.nationalityFlagURL, + this.nationalityID, + this.nationalityName, + this.nearestFreeSlot, + this.noOfFreeSlotsAvailable, + this.noOfPatientsRate, + this.originalClinicID, + this.personRate, + this.projectDistanceInKiloMeters, + this.projectNameBottom, + this.projectNameTop, + this.qR, + this.qRString, + this.rateNumber, + this.regionName, + this.regionNameN, + this.serviceID, + this.setupID, + this.speciality, + this.specialityN, + this.transactionType, + this.virtualEmploymentType, + this.workingHours, + this.vida3Id, + this.region, + this.regionArabic, + this.regionEnglish, + this.regionID, + this.projectBottomName, + this.projectTopName, + this.calcID, + }); DoctorsListResponseModel.fromJson(Map json) { clinicID = json['ClinicID']; @@ -141,7 +143,7 @@ class DoctorsListResponseModel { clinicNameN = json['ClinicNameN']; doctorTitle = json['DoctorTitle']; iD = json['ID']; - name = json['Name']; + name = json['Name'] ?? json["DoctorName"]; projectID = json['ProjectID']; projectName = json['ProjectName']; actualDoctorRate = json['ActualDoctorRate']; @@ -174,7 +176,7 @@ class DoctorsListResponseModel { longitude = json['Longitude']; nationalityFlagURL = json['NationalityFlagURL']; nationalityID = json['NationalityID']; - nationalityName = json['NationalityName']; + nationalityName = json['NationalityName'] ?? json["Nationality"]; nearestFreeSlot = json['NearestFreeSlot']; noOfFreeSlotsAvailable = json['NoOfFreeSlotsAvailable']; noOfPatientsRate = json['NoOfPatientsRate']; @@ -200,6 +202,7 @@ class DoctorsListResponseModel { regionEnglish = json['RegionName']; projectBottomName = json['ProjectNameBottom']; projectTopName = json['ProjectNameTop']; + calcID = json["CalcID"]; } Map toJson() { @@ -264,6 +267,7 @@ class DoctorsListResponseModel { data['VirtualEmploymentType'] = this.virtualEmploymentType; data['WorkingHours'] = this.workingHours; data['vida3Id'] = this.vida3Id; + data['CalcID'] = this.calcID; return data; } @@ -273,7 +277,8 @@ class DoctorsListResponseModel { } return regionEnglish; } - String getProjectCompleteName(){ + + String getProjectCompleteName() { return "${this.projectTopName} ${this.projectBottomName}"; } diff --git a/lib/features/hmg_services/hmg_services_repo.dart b/lib/features/hmg_services/hmg_services_repo.dart index 41035696..b2b3709e 100644 --- a/lib/features/hmg_services/hmg_services_repo.dart +++ b/lib/features/hmg_services/hmg_services_repo.dart @@ -14,7 +14,6 @@ import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart'; import 'package:hmg_patient_app_new/services/logger_service.dart'; -import 'package:provider/provider.dart'; import 'models/req_models/create_e_referral_model.dart'; import 'models/req_models/send_activation_code_ereferral_req_model.dart'; diff --git a/lib/features/hmg_services/hmg_services_view_model.dart b/lib/features/hmg_services/hmg_services_view_model.dart index b1a77578..5da08609 100644 --- a/lib/features/hmg_services/hmg_services_view_model.dart +++ b/lib/features/hmg_services/hmg_services_view_model.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/common_models/generic_api_model.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; @@ -18,6 +20,7 @@ import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'models/req_models/check_activation_e_referral_req_model.dart'; import 'models/resq_models/relationship_type_resp_mode.dart'; +import 'models/ui_models/covid_questionnare_model.dart'; class HmgServicesViewModel extends ChangeNotifier { final HmgServicesRepo hmgServicesRepo; @@ -60,6 +63,8 @@ class HmgServicesViewModel extends ChangeNotifier { Future getOrdersList() async {} + + // HHC multiple services selection List selectedHhcServices = []; @@ -766,4 +771,16 @@ class HmgServicesViewModel extends ChangeNotifier { }, ); } + List getQuestionsFromJson() { + final String questionsJson = '''[ { "id": 1, "questionEN": "Is the test intended for travel?", "questionAR": "هل تجري التحليل بغرض السفر؟", "ans": 2 }, { "id": 2, "questionEN": "Coming from outside KSA within last 2 weeks?", "questionAR": "هل قدمت من خارج المملكة خلال الأسبوعين الماضيين؟", "ans": 2 }, { "id": 3, "questionEN": "Do you currently have fever?", "questionAR": "هل تعاني حاليا من حرارة؟", "ans": 2 }, { "id": 4, "questionEN": "Did you have fever in last 2 weeks?", "questionAR": "هل عانيت من حرارة في الأسبوعين الماضيين؟", "ans": 2 }, { "id": 5, "questionEN": "Do you have a sore throat?", "questionAR": "هل لديك التهاب في الحلق؟", "ans": 2 }, { "id": 6, "questionEN": "Do you have a runny nose?", "questionAR": "هل لديك سيلان بالأنف؟" }, { "id": 7, "questionEN": "Do you have a cough?", "questionAR": "هل لديك سعال؟", "ans": 2 }, { "id": 8, "questionEN": "Do you have shortness of breath?", "questionAR": "هل تعاني من ضيق في التنفس؟", "ans": 2 }, { "id": 9, "questionEN": "Do you have nausea?", "questionAR": "هل تعاني من غثيان؟", "ans": 2 }, { "id": 10, "questionEN": "Do you have vomiting?", "questionAR": "هل تعاني من القيء؟", "ans": 2 }, { "id": 11, "questionEN": "Do you have a headache?", "questionAR": "هل تعاني من صداع في الرأس؟", "ans": 2 }, { "id": 12, "questionEN": "Do you have muscle pain?", "questionAR": "هل تعانين من آلام عضلية؟", "ans": 2 }, { "id": 13, "questionEN": "Do you have joint pain?", "questionAR": "هل تعاني من آلام المفاصل؟", "ans": 2 }, { "id": 14, "questionEN": "Do you have diarrhea?", "questionAR": "هل لديك اسهال؟", "ans": 2 } ]'''; + + try { + final parsed = json.decode(questionsJson) as List; + return parsed + .map((e) => CovidQuestionnaireModel.fromJson(Map.from(e))) + .toList(); + } catch (_) { + return []; + } + } } diff --git a/lib/features/hmg_services/models/ui_models/covid_questionnare_model.dart b/lib/features/hmg_services/models/ui_models/covid_questionnare_model.dart new file mode 100644 index 00000000..35b0efe3 --- /dev/null +++ b/lib/features/hmg_services/models/ui_models/covid_questionnare_model.dart @@ -0,0 +1,33 @@ +import 'dart:convert'; + +class CovidQuestionnaireModel { + int? id; + String? questionEn; + String? questionAr; + int? ans; + + CovidQuestionnaireModel({ + this.id, + this.questionEn, + this.questionAr, + this.ans, + }); + + factory CovidQuestionnaireModel.fromRawJson(String str) => CovidQuestionnaireModel.fromJson(json.decode(str)); + + String toRawJson() => json.encode(toJson()); + + factory CovidQuestionnaireModel.fromJson(Map json) => CovidQuestionnaireModel( + id: json["id"], + questionEn: json["questionEN"], + questionAr: json["questionAR"], + ans: json["ans"], + ); + + Map toJson() => { + "id": id, + "questionEN": questionEn, + "questionAR": questionAr, + "ans": ans, + }; +} diff --git a/lib/features/hmg_services/models/ui_models/e_referral_form_model.dart b/lib/features/hmg_services/models/ui_models/e_referral_form_model.dart index 32964b1b..8be00d6f 100644 --- a/lib/features/hmg_services/models/ui_models/e_referral_form_model.dart +++ b/lib/features/hmg_services/models/ui_models/e_referral_form_model.dart @@ -1,5 +1,4 @@ // models/referral_models.dart -import 'package:hmg_patient_app_new/core/common_models/nationality_country_model.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/create_e_referral_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_all_cities_resp_model.dart'; diff --git a/lib/features/insurance/insurance_view_model.dart b/lib/features/insurance/insurance_view_model.dart index 30f4c264..0bbdda20 100644 --- a/lib/features/insurance/insurance_view_model.dart +++ b/lib/features/insurance/insurance_view_model.dart @@ -5,7 +5,6 @@ import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patien import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_card_history.dart'; import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_details_response_model.dart'; import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_update_response_model.dart'; -import 'package:hmg_patient_app_new/features/lab/lab_repo.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; class InsuranceViewModel extends ChangeNotifier { diff --git a/lib/features/lab/lab_view_model.dart b/lib/features/lab/lab_view_model.dart index cd4065e5..118c54a0 100644 --- a/lib/features/lab/lab_view_model.dart +++ b/lib/features/lab/lab_view_model.dart @@ -1,6 +1,5 @@ import 'dart:collection'; import 'dart:core'; -import 'dart:math'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -18,7 +17,6 @@ import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:intl/intl.dart' show DateFormat; -import 'package:logger/logger.dart'; class LabViewModel extends ChangeNotifier { bool isLabOrdersLoading = false; @@ -82,6 +80,12 @@ class LabViewModel extends ChangeNotifier { double minY = double.infinity; double maxX = double.infinity; + // --- New grouping fields --- + bool isSortByClinic = true; + List> patientLabOrdersByClinic = []; + List> patientLabOrdersByHospital = []; + List> patientLabOrdersViewList = []; + LabViewModel( {required this.labRepo, required this.errorHandlerService, @@ -94,6 +98,9 @@ class LabViewModel extends ChangeNotifier { labOrderTests.clear(); isLabOrdersLoading = true; isLabResultsLoading = true; + patientLabOrdersByClinic.clear(); + patientLabOrdersByHospital.clear(); + patientLabOrdersViewList.clear(); getPatientLabOrders(); // } notifyListeners(); @@ -104,6 +111,12 @@ class LabViewModel extends ChangeNotifier { notifyListeners(); } + void setIsSortByClinic(bool value) { + isSortByClinic = value; + patientLabOrdersViewList = isSortByClinic ? patientLabOrdersByClinic : patientLabOrdersByHospital; + notifyListeners(); + } + Future getPatientLabOrders({Function(dynamic)? onSuccess, Function(String)? onError}) async { // if (!isLabNeedToLoad) return; @@ -112,6 +125,9 @@ class LabViewModel extends ChangeNotifier { uniqueTests.clear(); labOrderTests.clear(); uniqueTests = {}; + patientLabOrdersByClinic.clear(); + patientLabOrdersByHospital.clear(); + patientLabOrdersViewList.clear(); notifyListeners(); final result = await labRepo.getPatientLabOrders(); @@ -122,7 +138,7 @@ class LabViewModel extends ChangeNotifier { isLabResultsLoading = false; notifyListeners(); }, - // => await errorHandlerService.handleError(failure: failure), + // => await errorHandler_service.handleError(failure: failure), (apiResponse) { if (apiResponse.messageStatus == 2) { // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {}); @@ -132,6 +148,23 @@ class LabViewModel extends ChangeNotifier { tempLabOrdersList = apiResponse.data!; isLabOrdersLoading = false; isLabResultsLoading = false; + + // --- Build groups by clinic and by hospital (projectName) --- + final clinicMap = >{}; + final hospitalMap = >{}; + + for (var order in patientLabOrders) { + final clinicKey = (order.clinicDescription ?? 'Unknown').trim(); + clinicMap.putIfAbsent(clinicKey, () => []).add(order); + + final hospitalKey = (order.projectName ?? order.projectID ?? 'Unknown').toString().trim(); + hospitalMap.putIfAbsent(hospitalKey, () => []).add(order); + } + + patientLabOrdersByClinic = clinicMap.values.toList(); + patientLabOrdersByHospital = hospitalMap.values.toList(); + patientLabOrdersViewList = isSortByClinic ? patientLabOrdersByClinic : patientLabOrdersByHospital; + filterSuggestions(); getUniqueTestDescription(); isLabNeedToLoad = false; @@ -206,7 +239,6 @@ class LabViewModel extends ChangeNotifier { createdOn: item.createdOn, model: item)) }; - var sortedResult = SplayTreeSet.from(uniqueTests, (a, b) => a.description?[0].toUpperCase().compareTo(b.description?[0] ?? "") ?? -1); uniqueTestsList = uniqueTests.toList(); uniqueTestsList.sort((a, b) { return a.description!.toLowerCase().compareTo(b.description!.toLowerCase()); @@ -291,7 +323,7 @@ class LabViewModel extends ChangeNotifier { PatientLabOrdersResponseModel laborder) async { isLabResultByHospitalLoading = true; notifyListeners(); - mainLabResultsByHospitals.clear; + mainLabResultsByHospitals.clear(); final result = await labRepo.getPatientLabResultsByHospitals(laborder, Utils.isVidaPlusProject(int.parse(laborder.projectID ?? "0"))); @@ -334,8 +366,7 @@ class LabViewModel extends ChangeNotifier { LoaderBottomSheet.hideLoader(); if (apiResponse.messageStatus == 2) { } else if (apiResponse.messageStatus == 1) { - var sortedResponse = sortByFlagAndValue(apiResponse.data!); - var recentThree = sort(sortedResponse); + var recentThree = sort(apiResponse.data!); mainLabResults = recentThree; @@ -617,19 +648,6 @@ class LabViewModel extends ChangeNotifier { } List sort(List original) { - DateTime? parseVerifiedDate(String? raw) { - if (raw == null) return null; - final regex = RegExp(r'\/Date\((\d+)\)\/'); - final match = regex.firstMatch(raw); - if (match != null) { - final millis = int.tryParse(match.group(1)!); - if (millis != null) { - - return DateTime.fromMillisecondsSinceEpoch(millis); - } - } - return null; - } final copy = List.from(original); copy.sort((a, b) { @@ -649,8 +667,8 @@ class LabViewModel extends ChangeNotifier { final copy = List.from(original); copy.sort((a, b) { - final aDate =a.time; - final bDate = a.time; + final aDate = a.time; + final bDate = b.time; final now = DateTime.now(); if (aDate == now && bDate == now) return 0; if (aDate == now) return 1; diff --git a/lib/features/location/location_view_model.dart b/lib/features/location/location_view_model.dart index 76d7c2c8..5b0eef6d 100644 --- a/lib/features/location/location_view_model.dart +++ b/lib/features/location/location_view_model.dart @@ -37,7 +37,9 @@ class LocationViewModel extends ChangeNotifier { } GMSMapServices.CameraPosition getGMSLocation() { - return GMSMapServices.CameraPosition(target: GMSMapServices.LatLng(getIt().userLat, getIt().userLong), zoom: 18); + return GMSMapServices.CameraPosition( + target: GMSMapServices.LatLng(getIt().userLat != 0.0 ? getIt().userLat : 24.7248316, getIt().userLong != 0.0 ? getIt().userLong : 46.4928828), + zoom: 18); } void placeValueInController() async { diff --git a/lib/features/medical_file/medical_file_repo.dart b/lib/features/medical_file/medical_file_repo.dart index bf10e9e1..2f5cae6e 100644 --- a/lib/features/medical_file/medical_file_repo.dart +++ b/lib/features/medical_file/medical_file_repo.dart @@ -3,7 +3,6 @@ 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/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/get_allergies_response_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart'; diff --git a/lib/features/medical_file/medical_file_view_model.dart b/lib/features/medical_file/medical_file_view_model.dart index de7f067d..d67e5de8 100644 --- a/lib/features/medical_file/medical_file_view_model.dart +++ b/lib/features/medical_file/medical_file_view_model.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'dart:developer'; import 'package:flutter/material.dart'; @@ -36,6 +35,12 @@ class MedicalFileViewModel extends ChangeNotifier { List patientVaccineList = []; List patientSickLeaveList = []; + List patientSickLeavesByClinic = []; + List patientSickLeavesByHospital = []; + List patientSickLeavesViewList = []; + + bool isSickLeavesSortByClinic = true; + List patientAllergiesList = []; List patientMedicalReportList = []; @@ -44,6 +49,12 @@ class MedicalFileViewModel extends ChangeNotifier { List patientMedicalReportReadyList = []; List patientMedicalReportCancelledList = []; + List patientMedicalReportsByClinic = []; + List patientMedicalReportsByHospital = []; + List patientMedicalReportsViewList = []; + + bool isMedicalReportsSortByClinic = true; + List patientMedicalReportAppointmentHistoryList = []; PatientAppointmentHistoryResponseModel? patientMedicalReportSelectedAppointment; @@ -90,6 +101,49 @@ class MedicalFileViewModel extends ChangeNotifier { } else if (index == 2) { patientMedicalReportList = patientMedicalReportCancelledList; } + // Re-group by clinic/hospital for the selected tab + _groupMedicalReportsByClinicAndHospital(); + notifyListeners(); + } + + void _groupMedicalReportsByClinicAndHospital() { + patientMedicalReportsByClinic.clear(); + patientMedicalReportsByHospital.clear(); + + for (var element in patientMedicalReportList) { + // Group by clinic + List reportsByClinic = patientMedicalReportsByClinic.where((elementClinic) => elementClinic.filterName == element.clinicDescription).toList(); + + if (reportsByClinic.isNotEmpty) { + patientMedicalReportsByClinic[patientMedicalReportsByClinic.indexOf(reportsByClinic[0])].medicalReportsList!.add(element); + } else { + patientMedicalReportsByClinic.add(MedicalReportList(filterName: element.clinicDescription, medicalReport: element)); + } + + // Group by hospital + List reportsByHospital = patientMedicalReportsByHospital.where((elementHospital) => elementHospital.filterName == element.projectName).toList(); + + if (reportsByHospital.isNotEmpty) { + patientMedicalReportsByHospital[patientMedicalReportsByHospital.indexOf(reportsByHospital[0])].medicalReportsList!.add(element); + } else { + patientMedicalReportsByHospital.add(MedicalReportList(filterName: element.projectName, medicalReport: element)); + } + } + + if (isMedicalReportsSortByClinic) { + patientMedicalReportsViewList = patientMedicalReportsByClinic; + } else { + patientMedicalReportsViewList = patientMedicalReportsByHospital; + } + } + + setIsMedicalReportsSortByClinic(bool value) { + isMedicalReportsSortByClinic = value; + if (isMedicalReportsSortByClinic) { + patientMedicalReportsViewList = patientMedicalReportsByClinic; + } else { + patientMedicalReportsViewList = patientMedicalReportsByHospital; + } notifyListeners(); } @@ -110,17 +164,35 @@ class MedicalFileViewModel extends ChangeNotifier { setIsPatientSickLeaveListLoading(bool val) { if (val) { patientSickLeaveList.clear(); + patientSickLeavesByClinic.clear(); + patientSickLeavesByHospital.clear(); + patientSickLeavesViewList.clear(); patientSickLeavePDFBase64 = ""; + isSickLeavesSortByClinic = true; } isPatientSickLeaveListLoading = val; notifyListeners(); } + setIsSickLeavesSortByClinic(bool value) { + isSickLeavesSortByClinic = value; + if (isSickLeavesSortByClinic) { + patientSickLeavesViewList = patientSickLeavesByClinic; + } else { + patientSickLeavesViewList = patientSickLeavesByHospital; + } + notifyListeners(); + } + setIsPatientMedicalReportsLoading(bool val) { if (val) { onMedicalReportTabChange(0); patientMedicalReportList.clear(); + patientMedicalReportsByClinic.clear(); + patientMedicalReportsByHospital.clear(); + patientMedicalReportsViewList.clear(); patientMedicalReportPDFBase64 = ""; + isMedicalReportsSortByClinic = true; } isPatientMedicalReportsListLoading = val; notifyListeners(); @@ -214,6 +286,29 @@ class MedicalFileViewModel extends ChangeNotifier { } else if (apiResponse.messageStatus == 1) { patientSickLeaveList = apiResponse.data!; isPatientSickLeaveListLoading = false; + + // Group by clinic and hospital + for (var element in patientSickLeaveList) { + // Group by clinic + List sickLeavesByClinic = patientSickLeavesByClinic.where((elementClinic) => elementClinic.filterName == element.clinicName).toList(); + + if (sickLeavesByClinic.isNotEmpty) { + patientSickLeavesByClinic[patientSickLeavesByClinic.indexOf(sickLeavesByClinic[0])].sickLeavesList!.add(element); + } else { + patientSickLeavesByClinic.add(SickLeaveList(filterName: element.clinicName, sickLeaves: element)); + } + + // Group by hospital + List sickLeavesByHospital = patientSickLeavesByHospital.where((elementHospital) => elementHospital.filterName == element.projectName).toList(); + + if (sickLeavesByHospital.isNotEmpty) { + patientSickLeavesByHospital[patientSickLeavesByHospital.indexOf(sickLeavesByHospital[0])].sickLeavesList!.add(element); + } else { + patientSickLeavesByHospital.add(SickLeaveList(filterName: element.projectName, sickLeaves: element)); + } + } + patientSickLeavesViewList = patientSickLeavesByClinic; + notifyListeners(); if (onSuccess != null) { onSuccess(apiResponse); diff --git a/lib/features/medical_file/models/patient_medical_response_model.dart b/lib/features/medical_file/models/patient_medical_response_model.dart index 52785af1..3bcf5cdd 100644 --- a/lib/features/medical_file/models/patient_medical_response_model.dart +++ b/lib/features/medical_file/models/patient_medical_response_model.dart @@ -190,3 +190,16 @@ class PatientMedicalReportResponseModel { return data; } } + +class MedicalReportList { + String? filterName; + List? medicalReportsList; + + MedicalReportList({this.filterName, PatientMedicalReportResponseModel? medicalReport}) { + medicalReportsList = []; + if (medicalReport != null) { + medicalReportsList!.add(medicalReport); + } + } +} + diff --git a/lib/features/medical_file/models/patient_sickleave_response_model.dart b/lib/features/medical_file/models/patient_sickleave_response_model.dart index 3bf732c7..53c886f6 100644 --- a/lib/features/medical_file/models/patient_sickleave_response_model.dart +++ b/lib/features/medical_file/models/patient_sickleave_response_model.dart @@ -174,3 +174,16 @@ class PatientSickLeavesResponseModel { return data; } } + +class SickLeaveList { + String? filterName; + List? sickLeavesList; + + SickLeaveList({this.filterName, PatientSickLeavesResponseModel? sickLeaves}) { + sickLeavesList = []; + if (sickLeaves != null) { + sickLeavesList!.add(sickLeaves); + } + } +} + diff --git a/lib/features/my_appointments/appointment_rating_view_model.dart b/lib/features/my_appointments/appointment_rating_view_model.dart index a192df10..6dd41ff5 100644 --- a/lib/features/my_appointments/appointment_rating_view_model.dart +++ b/lib/features/my_appointments/appointment_rating_view_model.dart @@ -1,7 +1,6 @@ // dart import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; -import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/appointment_details_resp_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_repo.dart'; import 'package:hmg_patient_app_new/services/error_handler_service.dart'; diff --git a/lib/features/my_appointments/appointment_via_region_viewmodel.dart b/lib/features/my_appointments/appointment_via_region_viewmodel.dart index 4a0ffab6..f51f7017 100644 --- a/lib/features/my_appointments/appointment_via_region_viewmodel.dart +++ b/lib/features/my_appointments/appointment_via_region_viewmodel.dart @@ -7,7 +7,6 @@ import 'package:hmg_patient_app_new/presentation/book_appointment/select_clinic_ import 'package:hmg_patient_app_new/presentation/book_appointment/select_doctor_page.dart'; import 'package:hmg_patient_app_new/services/navigation_service.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; -import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; enum AppointmentViaRegionState { REGION_SELECTION, diff --git a/lib/features/my_appointments/my_appointments_repo.dart b/lib/features/my_appointments/my_appointments_repo.dart index af03cb8c..ce9e8770 100644 --- a/lib/features/my_appointments/my_appointments_repo.dart +++ b/lib/features/my_appointments/my_appointments_repo.dart @@ -11,7 +11,6 @@ import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/rate_appointment_resp_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/ask_doctor_request_type_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/get_tamara_installments_details_response_model.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart' show HospitalsModel; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_share_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_queue_details_response_model.dart'; diff --git a/lib/features/my_appointments/my_appointments_view_model.dart b/lib/features/my_appointments/my_appointments_view_model.dart index d0779703..b4a25eec 100644 --- a/lib/features/my_appointments/my_appointments_view_model.dart +++ b/lib/features/my_appointments/my_appointments_view_model.dart @@ -60,6 +60,12 @@ class MyAppointmentsViewModel extends ChangeNotifier { List patientEyeMeasurementsAppointmentsHistoryList = []; + // Grouping by Clinic and Hospital + List patientAppointmentsByClinic = []; + List patientAppointmentsByHospital = []; + List patientAppointmentsViewList = []; + bool isAppointmentsSortByClinic = true; + List askDoctorRequestTypeList = []; PatientAppointmentShareResponseModel? patientAppointmentShareResponseModel; @@ -82,6 +88,43 @@ class MyAppointmentsViewModel extends ChangeNotifier { notifyListeners(); } + setIsAppointmentsSortByClinic(bool value) { + isAppointmentsSortByClinic = value; + _groupAppointmentsByClinicAndHospital(); + notifyListeners(); + } + + void _groupAppointmentsByClinicAndHospital() { + patientAppointmentsByClinic.clear(); + patientAppointmentsByHospital.clear(); + + for (var element in filteredAppointmentList) { + // Group by clinic + List appointmentsByClinic = patientAppointmentsByClinic.where((elementClinic) => elementClinic.filterName == element.clinicName).toList(); + + if (appointmentsByClinic.isNotEmpty) { + patientAppointmentsByClinic[patientAppointmentsByClinic.indexOf(appointmentsByClinic[0])].patientDoctorAppointmentList!.add(element); + } else { + patientAppointmentsByClinic.add(PatientAppointmentList(filterName: element.clinicName, patientDoctorAppointment: element)); + } + + // Group by hospital + List appointmentsByHospital = patientAppointmentsByHospital.where((elementHospital) => elementHospital.filterName == element.projectName).toList(); + + if (appointmentsByHospital.isNotEmpty) { + patientAppointmentsByHospital[patientAppointmentsByHospital.indexOf(appointmentsByHospital[0])].patientDoctorAppointmentList!.add(element); + } else { + patientAppointmentsByHospital.add(PatientAppointmentList(filterName: element.projectName, patientDoctorAppointment: element)); + } + } + + if (isAppointmentsSortByClinic) { + patientAppointmentsViewList = patientAppointmentsByClinic; + } else { + patientAppointmentsViewList = patientAppointmentsByHospital; + } + } + initAppointmentsViewModel() { if (isAppointmentDataToBeLoaded) { patientAppointmentsHistoryList.clear(); @@ -513,6 +556,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { break; } getFiltersForSelectedAppointmentList(filteredAppointmentList); + _groupAppointmentsByClinicAndHospital(); notifyListeners(); } @@ -570,6 +614,7 @@ class MyAppointmentsViewModel extends ChangeNotifier { } catch (e) {} } } + _groupAppointmentsByClinicAndHospital(); notifyListeners(); } diff --git a/lib/features/payfort/payfort_view_model.dart b/lib/features/payfort/payfort_view_model.dart index db8209a5..dda8f51a 100644 --- a/lib/features/payfort/payfort_view_model.dart +++ b/lib/features/payfort/payfort_view_model.dart @@ -110,7 +110,7 @@ class PayfortViewModel extends ChangeNotifier { onError!(failure.message); }, (apiResponse) { - log(apiResponse.data); + log(apiResponse.data.toString()); if (onSuccess != null) { onSuccess(apiResponse); } @@ -134,7 +134,7 @@ class PayfortViewModel extends ChangeNotifier { onError!(failure.message); }, (apiResponse) { - log(apiResponse.data); + log(apiResponse.data.toString()); if (onSuccess != null) { onSuccess(apiResponse); } diff --git a/lib/features/prescriptions/prescriptions_view_model.dart b/lib/features/prescriptions/prescriptions_view_model.dart index 75171348..ff864061 100644 --- a/lib/features/prescriptions/prescriptions_view_model.dart +++ b/lib/features/prescriptions/prescriptions_view_model.dart @@ -5,8 +5,6 @@ import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/location_util.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/features/location/GeocodeResponse.dart'; -import 'package:hmg_patient_app_new/features/location/PlaceDetails.dart'; -import 'package:hmg_patient_app_new/features/location/PlacePrediction.dart'; import 'package:hmg_patient_app_new/features/location/location_view_model.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/calender_utils_new.dart'; diff --git a/lib/features/radiology/radiology_view_model.dart b/lib/features/radiology/radiology_view_model.dart index 4a879063..986945e6 100644 --- a/lib/features/radiology/radiology_view_model.dart +++ b/lib/features/radiology/radiology_view_model.dart @@ -29,6 +29,18 @@ class RadiologyViewModel extends ChangeNotifier { late PatientRadiologyResponseModel patientRadiologyOrderByAppointment; + // --- Grouping fields: By Clinic / By Hospital --- + bool isSortByClinic = true; + List> patientRadiologyOrdersByClinic = []; + List> patientRadiologyOrdersByHospital = []; + List> patientRadiologyOrdersViewList = []; + + void setIsSortByClinic(bool value) { + isSortByClinic = value; + patientRadiologyOrdersViewList = isSortByClinic ? patientRadiologyOrdersByClinic : patientRadiologyOrdersByHospital; + notifyListeners(); + } + RadiologyViewModel({required this.radiologyRepo, required this.errorHandlerService, required this.navigationService}); initRadiologyViewModel() { diff --git a/lib/features/smartwatch_health_data/health_service.dart b/lib/features/smartwatch_health_data/health_service.dart index c5dca48b..d3815b3b 100644 --- a/lib/features/smartwatch_health_data/health_service.dart +++ b/lib/features/smartwatch_health_data/health_service.dart @@ -1,7 +1,5 @@ import 'dart:io'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/cupertino.dart'; import 'package:health/health.dart'; import 'package:permission_handler/permission_handler.dart'; diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 44d671f5..f550c81b 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -2,7 +2,7 @@ // ignore_for_file: constant_identifier_names -abstract class LocaleKeys { +abstract class LocaleKeys { static const english = 'english'; static const arabic = 'arabic'; static const login = 'login'; @@ -189,7 +189,6 @@ abstract class LocaleKeys { static const firstName = 'firstName'; static const middleName = 'middleName'; static const lastName = 'lastName'; - static const female = 'female'; static const preferredLanguage = 'preferredLanguage'; static const locationsRegister = 'locationsRegister'; static const ksa = 'ksa'; @@ -801,7 +800,7 @@ abstract class LocaleKeys { static const fullName = 'fullName'; static const married = 'married'; static const uae = 'uae'; - static const malE = 'male'; + static const malE = 'malE'; static const loginBy = 'loginBy'; static const loginByOTP = 'loginByOTP'; static const guest = 'guest'; @@ -876,4 +875,6 @@ abstract class LocaleKeys { static const walkin = 'walkin'; static const laserClinic = 'laserClinic'; static const continueString = 'continueString'; + static const covid_info = 'covid_info'; + } diff --git a/lib/presentation/appointments/appointment_details_page.dart b/lib/presentation/appointments/appointment_details_page.dart index 2086c2a0..7b605b9f 100644 --- a/lib/presentation/appointments/appointment_details_page.dart +++ b/lib/presentation/appointments/appointment_details_page.dart @@ -1,13 +1,9 @@ import 'dart:async'; -import 'dart:collection'; -import 'dart:io'; -import 'package:device_calendar/device_calendar.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; -import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/utils/calender_utils_new.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; @@ -41,7 +37,6 @@ import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:maps_launcher/maps_launcher.dart'; import 'package:provider/provider.dart'; -import '../../core/dependencies.dart'; import '../medical_file/widgets/medical_file_card.dart'; class AppointmentDetailsPage extends StatefulWidget { diff --git a/lib/presentation/appointments/my_appointments_page.dart b/lib/presentation/appointments/my_appointments_page.dart index 934aca42..abf2464c 100644 --- a/lib/presentation/appointments/my_appointments_page.dart +++ b/lib/presentation/appointments/my_appointments_page.dart @@ -4,6 +4,9 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -35,6 +38,7 @@ class MyAppointmentsPage extends StatefulWidget { } class _MyAppointmentsPageState extends State { + int? expandedIndex; late MyAppointmentsViewModel myAppointmentsViewModel; late BookAppointmentsViewModel bookAppointmentsViewModel; @@ -68,6 +72,9 @@ class _MyAppointmentsPageState extends State { CustomTabBarModel(null, "Completed".needTranslation), ], onTabChange: (index) { + setState(() { + expandedIndex = null; + }); myAppointmentsViewModel.onTabChange(index); myAppointmentsViewModel.updateListWRTTab(index); context.read().flush(); @@ -91,17 +98,55 @@ class _MyAppointmentsPageState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + SizedBox(height: 16.h), + // Clinic & Hospital Sort + Row( + children: [ + CustomButton( + text: LocaleKeys.byClinic.tr(context: context), + onPressed: () { + myAppointmentsVM.setIsAppointmentsSortByClinic(true); + }, + backgroundColor: myAppointmentsVM.isAppointmentsSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderColor: myAppointmentsVM.isAppointmentsSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), + textColor: myAppointmentsVM.isAppointmentsSortByClinic ? 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: () { + myAppointmentsVM.setIsAppointmentsSortByClinic(false); + }, + backgroundColor: myAppointmentsVM.isAppointmentsSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, + borderColor: myAppointmentsVM.isAppointmentsSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, + textColor: myAppointmentsVM.isAppointmentsSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, + fontSize: 12, + fontWeight: FontWeight.w500, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + ], + ).paddingSymmetrical(24.h, 0.h), Visibility(visible: myAppointmentsVM.availableFilters.isNotEmpty, child: getAppointmentFilters(myAppointmentsVM)), - ListView.separated( - padding: EdgeInsets.only(top: 16.h), + SizedBox(height: 8.h), + // Expandable list + ListView.builder( + padding: EdgeInsets.only(top: 8.h), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: myAppointmentsVM.isMyAppointmentsLoading - ? 5 + ? 4 : filteredAppointmentList.isNotEmpty - ? filteredAppointmentList.length + ? myAppointmentsVM.patientAppointmentsViewList.length : 1, itemBuilder: (context, index) { + final isExpanded = expandedIndex == index; return myAppointmentsVM.isMyAppointmentsLoading ? Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), @@ -123,15 +168,149 @@ class _MyAppointmentsPageState extends State { child: AnimatedContainer( duration: Duration(milliseconds: 300), curve: Curves.easeInOut, - decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), - child: AppointmentCard( - patientAppointmentHistoryResponseModel: filteredAppointmentList[index], - myAppointmentsViewModel: myAppointmentsViewModel, - bookAppointmentsViewModel: bookAppointmentsViewModel, - isLoading: false, - isFromHomePage: false, + 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: [ + CustomButton( + text: "${myAppointmentsVM.patientAppointmentsViewList[index].patientDoctorAppointmentList!.length} Appointments", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ), + Icon(isExpanded ? Icons.expand_less : Icons.expand_more), + ], + ), + SizedBox(height: 8.h), + myAppointmentsVM.patientAppointmentsViewList[index].filterName!.toText16(isBold: true) + ], + ), + ), + AnimatedSwitcher( + duration: Duration(milliseconds: 500), + switchInCurve: Curves.easeIn, + switchOutCurve: Curves.easeOut, + transitionBuilder: (Widget child, Animation animation) { + return FadeTransition( + opacity: animation, + child: SizeTransition( + sizeFactor: animation, + axisAlignment: 0.0, + child: child, + ), + ); + }, + child: isExpanded + ? Container( + key: ValueKey(index), + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 8.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ...myAppointmentsVM.patientAppointmentsViewList[index].patientDoctorAppointmentList!.map((appointment) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Image.network( + appointment.doctorImageURL!, + width: 24.h, + height: 24.h, + fit: BoxFit.fill, + ).circle(100), + SizedBox(width: 8.h), + Expanded(child: appointment.doctorNameObj!.toText14(weight: FontWeight.w500)), + ], + ), + SizedBox(height: 8.h), + Row( + children: [ + CustomButton( + text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(appointment.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, + ), + SizedBox(width: 8.h), + CustomButton( + text: myAppointmentsVM.isAppointmentsSortByClinic ? appointment.projectName! : appointment.clinicName!, + 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: appointment.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, + ), + ], + ), + SizedBox(height: 8.h), + AppointmentCard( + patientAppointmentHistoryResponseModel: appointment, + myAppointmentsViewModel: myAppointmentsViewModel, + bookAppointmentsViewModel: bookAppointmentsViewModel, + isLoading: false, + isFromHomePage: false, + ), + SizedBox(height: 12.h), + Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + SizedBox(height: 12.h), + ], + ); + }), + ], + ), + ) + : SizedBox.shrink(), + ), + ], + ), ), - ).paddingSymmetrical(24.h, 0.h), + ), ), ), ) @@ -160,8 +339,7 @@ class _MyAppointmentsPageState extends State { ).paddingSymmetrical(48.h, 0.h), ); }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), - ), + ).paddingSymmetrical(24.h, 0.h), SizedBox(height: 24.h), ], ); diff --git a/lib/presentation/appointments/my_doctors_page.dart b/lib/presentation/appointments/my_doctors_page.dart index 51e97032..3740a4ad 100644 --- a/lib/presentation/appointments/my_doctors_page.dart +++ b/lib/presentation/appointments/my_doctors_page.dart @@ -1,6 +1,5 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; @@ -21,169 +20,377 @@ import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; import '../../widgets/chip/app_custom_chip_widget.dart'; +import '../../widgets/buttons/custom_button.dart'; -class MyDoctorsPage extends StatelessWidget { +class MyDoctorsPage extends StatefulWidget { MyDoctorsPage({super.key}); + @override + State createState() => _MyDoctorsPageState(); +} + +class _MyDoctorsPageState extends State { late MyAppointmentsViewModel myAppointmentsViewModel; late BookAppointmentsViewModel bookAppointmentsViewModel; + bool isSortByClinic = true; // default like lab page + int? expandedIndex; + final Map _groupKeys = {}; + @override Widget build(BuildContext context) { - AppState appState = getIt.get(); myAppointmentsViewModel = Provider.of(context, listen: false); bookAppointmentsViewModel = Provider.of(context, listen: false); - return Scaffold( - backgroundColor: AppColors.bgScaffoldColor, - body: CollapsingListView( + + return CollapsingListView( title: LocaleKeys.myDoctor.tr(context: context), - child: SingleChildScrollView( - child: Consumer(builder: (context, myAppointmentsVM, child) { + child: Consumer(builder: (context, myAppointmentsVM, child) { + // build grouped lists from the flat list + final clinicMap = >{}; + final hospitalMap = >{}; + + for (var doc in myAppointmentsVM.patientMyDoctorsList) { + final clinicKey = (doc.clinicName ?? 'Unknown').trim(); + clinicMap.putIfAbsent(clinicKey, () => []).add(doc); + + final hospitalKey = (doc.projectName ?? doc.projectID?.toString() ?? 'Unknown').toString().trim(); + hospitalMap.putIfAbsent(hospitalKey, () => []).add(doc); + } + + final patientMyDoctorsByClinic = clinicMap.values.toList(); + final patientMyDoctorsByHospital = hospitalMap.values.toList(); + final patientMyDoctorsViewList = isSortByClinic ? patientMyDoctorsByClinic : patientMyDoctorsByHospital; + return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 16.h), + // Add Clinic / Hospital toggle buttons styled like LabOrdersPage + Padding( + padding: EdgeInsets.symmetric(horizontal: 24.h), + child: Row( + children: [ + CustomButton( + text: LocaleKeys.byClinic.tr(context: context), + onPressed: () { + setState(() { + isSortByClinic = true; + expandedIndex = null; + }); + }, + backgroundColor: isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderColor: isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), + textColor: 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: () { + setState(() { + isSortByClinic = false; + expandedIndex = null; + }); + }, + backgroundColor: isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, + borderColor: isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, + textColor: isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, + fontSize: 12, + fontWeight: FontWeight.w500, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + + ), + ], + ), + ), + SizedBox(height: 16.h), ListView.separated( scrollDirection: Axis.vertical, - itemCount: myAppointmentsVM.isPatientMyDoctorsLoading ? 5 : myAppointmentsVM.patientMyDoctorsList.length, + itemCount: myAppointmentsVM.isPatientMyDoctorsLoading ? 5 : (patientMyDoctorsViewList.isNotEmpty ? patientMyDoctorsViewList.length : 0), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.only(left: 24.h, right: 24.h), itemBuilder: (context, index) { - return myAppointmentsVM.isPatientMyDoctorsLoading - ? Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.h, - hasShadow: true, - ), - child: Padding( - padding: EdgeInsets.all(14.h), - child: Column( + if (myAppointmentsVM.isPatientMyDoctorsLoading) { + return Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: true, + ), + child: Padding( + padding: EdgeInsets.all(14.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.network( - "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", - width: 63.h, - height: 63.h, - fit: BoxFit.cover, - ).circle(100).toShimmer2(isShow: true), - SizedBox(width: 16.h), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - "Dr John Smith".toText16(isBold: true).toShimmer2(isShow: true), - SizedBox(height: 8.h), - Wrap( - direction: Axis.horizontal, - spacing: 3.h, - runSpacing: 4.h, - children: [ - AppCustomChipWidget(labelText: "").toShimmer2(isShow: true, width: 16.h), - AppCustomChipWidget(labelText: "").toShimmer2(isShow: true, width: 16.h), - ], - ), - ], - ), - ), - ], - ), - ], - ), - ), - ) - : AnimationConfiguration.staggeredList( - position: index, - duration: const Duration(milliseconds: 1000), - child: SlideAnimation( - verticalOffset: 100.0, - child: FadeInAnimation( - child: Container( - decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.whiteColor, - borderRadius: 20.h, - hasShadow: true, - ), - child: Padding( - padding: EdgeInsets.all(14.h), + Image.network( + "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + width: 63.h, + height: 63.h, + fit: BoxFit.cover, + ).circle(100).toShimmer2(isShow: true), + SizedBox(width: 16.h), + Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.network( - myAppointmentsVM.patientMyDoctorsList[index].doctorImageURL!, - width: 63.h, - height: 63.h, - fit: BoxFit.cover, - ).circle(100).toShimmer2(isShow: false), - SizedBox(width: 16.h), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - (myAppointmentsVM.patientMyDoctorsList[index].doctorName).toString().toText16(isBold: true).toShimmer2(isShow: false), - SizedBox(height: 8.h), - Wrap( - direction: Axis.horizontal, - spacing: 3.h, - runSpacing: 4.h, - children: [ - AppCustomChipWidget(labelText: myAppointmentsVM.patientMyDoctorsList[index].clinicName).toShimmer2(isShow: false, width: 16.h), - AppCustomChipWidget(labelText: myAppointmentsVM.patientMyDoctorsList[index].projectName).toShimmer2(isShow: false, width: 16.h), - ], - ), - ], - ), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + "Dr John Smith".toText16(isBold: true).toShimmer2(isShow: true), + SizedBox(height: 8.h), + Wrap( + direction: Axis.horizontal, + spacing: 3.h, + runSpacing: 4.h, children: [ - "".toText16(), - Transform.flip( - flipX: appState.isArabic(), - child: - Utils.buildSvgWithAssets(icon: AppAssets.forward_arrow_icon_small, width: 15.h, height: 15.h, fit: BoxFit.contain, iconColor: AppColors.textColor)), + AppCustomChipWidget(labelText: "").toShimmer2(isShow: true, width: 16.h), + AppCustomChipWidget(labelText: "").toShimmer2(isShow: true, width: 16.h), ], ), ], ), ), - ).onPress(() async { - bookAppointmentsViewModel.setSelectedDoctor(DoctorsListResponseModel( - clinicID: myAppointmentsVM.patientMyDoctorsList[index].clinicID, - projectID: myAppointmentsVM.patientMyDoctorsList[index].projectID, - doctorID: myAppointmentsVM.patientMyDoctorsList[index].doctorID, - )); - LoaderBottomSheet.showLoader(); - await bookAppointmentsViewModel.getDoctorProfile(onSuccess: (dynamic respData) { - LoaderBottomSheet.hideLoader(); - Navigator.of(context).push( - CustomPageRoute( - page: DoctorProfilePage(), - ), - ); - }, onError: (err) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - context, - child: Utils.getErrorWidget(loadingText: err), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }); - }), + ], ), + ], + ), + ), + ); + } + + final group = patientMyDoctorsViewList[index]; + final displayName = isSortByClinic ? (group.first.clinicName ?? 'Unknown') : (group.first.projectName ?? 'Unknown'); + final isExpanded = expandedIndex == index; + + return Container( + key: _groupKeys.putIfAbsent(index, () => GlobalKey()), + margin: EdgeInsets.only(bottom: 12.h), + padding: EdgeInsets.all(16.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 20.h, + hasShadow: true, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + GestureDetector( + onTap: () { + setState(() { + expandedIndex = isExpanded ? null : index; + }); + WidgetsBinding.instance.addPostFrameCallback((_) { + final key = _groupKeys[index]; + if (key != null && key.currentContext != null && expandedIndex == index) { + Scrollable.ensureVisible( + key.currentContext!, + duration: Duration(milliseconds: 350), + curve: Curves.easeInOut, + alignment: 0.1, + ); + } + }); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + CustomButton( + text: "${group.length} ${'doctors'.needTranslation}", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ), + Icon(isExpanded ? Icons.expand_less : Icons.chevron_right, color: AppColors.greyColor), + ], + ), + SizedBox(height: 8.h), + Text( + displayName, + style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), + overflow: TextOverflow.ellipsis, + ), + ], ), - ); + ), + AnimatedSwitcher( + duration: Duration(milliseconds: 400), + child: isExpanded + ? Container( + key: ValueKey(index), + padding: EdgeInsets.only(top: 12.h), + child: Column( + children: group.map((doctor) { + return Container( + margin: EdgeInsets.only(bottom: 12.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 12.h, + hasShadow: true, + ), + child: Padding( + padding: EdgeInsets.all(14.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.network( + (doctor?.doctorImageURL ?? doctor?.doctorImage ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png"), + width: 24.h, + height: 24.h, + fit: BoxFit.cover, + ).circle(100), + SizedBox(width: 8.h), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + (doctor?.doctorName ?? "").toString().toText14(weight: FontWeight.w500), + SizedBox(height: 6.h), + ], + ), + ), + ], + ), + SizedBox(height: 8.h), + Row( + children: [ + CustomButton( + text: isSortByClinic ? (doctor?.clinicName ?? "") : (doctor?.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: 8.h), + Row( + children: [ + Expanded( + flex: 6, + child: CustomButton( + text: "View Profile".needTranslation.tr(context: context), + onPressed: () async { + bookAppointmentsViewModel.setSelectedDoctor(DoctorsListResponseModel( + clinicID: doctor?.clinicID ?? 0, + projectID: doctor?.projectID ?? 0, + doctorID: doctor?.doctorID ?? 0, + )); + LoaderBottomSheet.showLoader(); + await bookAppointmentsViewModel.getDoctorProfile(onSuccess: (dynamic respData) { + LoaderBottomSheet.hideLoader(); + Navigator.of(context).push( + CustomPageRoute( + page: DoctorProfilePage(), + ), + ); + }, onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: err), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + }, + backgroundColor: AppColors.bgRedLightColor, + borderColor: AppColors.primaryRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + ), + SizedBox(width: 8.h), + Expanded( + flex: 1, + child: Container( + height: 40.h, + width: 40.w, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.textColor, + borderRadius: 12, + ), + child: Padding( + padding: EdgeInsets.all(12.h), + child: Transform.flip( + flipX: getIt().isArabic(), + child: Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon_small, + iconColor: AppColors.whiteColor, + fit: BoxFit.contain, + ), + ), + ), + ).onPress(() async { + bookAppointmentsViewModel.setSelectedDoctor(DoctorsListResponseModel( + clinicID: doctor?.clinicID ?? 0, + projectID: doctor?.projectID ?? 0, + doctorID: doctor?.doctorID ?? 0, + )); + LoaderBottomSheet.showLoader(); + await bookAppointmentsViewModel.getDoctorProfile(onSuccess: (dynamic respData) { + LoaderBottomSheet.hideLoader(); + Navigator.of(context).push( + CustomPageRoute( + page: DoctorProfilePage(), + ), + ); + }, onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: err), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + }), + ), + ], + ), + ], + ), + ), + ); + }).toList(), + ), + ) + : SizedBox.shrink(), + ), + ], + ), + ); }, separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), ), @@ -191,8 +398,6 @@ class MyDoctorsPage extends StatelessWidget { ], ); }), - ), - ), ); } } diff --git a/lib/presentation/appointments/widgets/AppointmentFilter.dart b/lib/presentation/appointments/widgets/AppointmentFilter.dart index 98da22d3..6546c650 100644 --- a/lib/presentation/appointments/widgets/AppointmentFilter.dart +++ b/lib/presentation/appointments/widgets/AppointmentFilter.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/appointemnet_filters.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:smooth_corner/smooth_corner.dart'; diff --git a/lib/presentation/appointments/widgets/appointment_card.dart b/lib/presentation/appointments/widgets/appointment_card.dart index a35c1ca5..57e19ca2 100644 --- a/lib/presentation/appointments/widgets/appointment_card.dart +++ b/lib/presentation/appointments/widgets/appointment_card.dart @@ -17,7 +17,6 @@ import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_vie import 'package:hmg_patient_app_new/features/my_appointments/utils/appointment_type.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/appointments/appointment_details_page.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/appointment_queue_page.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/ask_doctor_request_type_select.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/eye_measurement_details_page.dart'; @@ -353,14 +352,14 @@ class AppointmentCard extends StatelessWidget { backgroundColor: AppColors.greyColor, borderColor: AppColors.greyColor, textColor: AppColors.blackColor, - fontSize: 14.f, + fontSize: 12.f, fontWeight: FontWeight.w500, borderRadius: 12.r, padding: EdgeInsets.symmetric(horizontal: 10.w), height: 40.h, icon: AppAssets.rebook_appointment_icon, iconColor: AppColors.blackColor, - iconSize: 16.h, + iconSize: 14.h, ); } diff --git a/lib/presentation/appointments/widgets/appointment_checkin_bottom_sheet.dart b/lib/presentation/appointments/widgets/appointment_checkin_bottom_sheet.dart index 5b1d1cd6..d118a5e8 100644 --- a/lib/presentation/appointments/widgets/appointment_checkin_bottom_sheet.dart +++ b/lib/presentation/appointments/widgets/appointment_checkin_bottom_sheet.dart @@ -14,7 +14,6 @@ import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/ 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/appointments/appointment_queue_page.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/my_appointments_page.dart'; import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:barcode_scan2/barcode_scan2.dart'; @@ -22,7 +21,6 @@ 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/nfc/nfc_reader_sheet.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; -import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; class AppointmentCheckinBottomSheet extends StatelessWidget { AppointmentCheckinBottomSheet({super.key, required this.patientAppointmentHistoryResponseModel, required this.myAppointmentsViewModel}); @@ -60,7 +58,7 @@ class AppointmentCheckinBottomSheet extends StatelessWidget { double dist = Utils.distance(value.latitude, value.longitude, double.parse(projectDetailListModel.latitude!), double.parse(projectDetailListModel.longitude!)).ceilToDouble() * 1000; print(dist); if (dist <= projectDetailListModel.geofenceRadius!) { - sendCheckInRequest(projectDetailListModel.checkInQrCode!, context); + sendCheckInRequest(projectDetailListModel.checkInQrCode!, 3, context); } else { showCommonBottomSheetWithoutHeight(context, title: "Error".needTranslation, @@ -79,7 +77,7 @@ class AppointmentCheckinBottomSheet extends StatelessWidget { Future.delayed(const Duration(milliseconds: 500), () { showNfcReader(context, onNcfScan: (String nfcId) { Future.delayed(const Duration(milliseconds: 100), () { - sendCheckInRequest(nfcId, context); + sendCheckInRequest(nfcId, 1, context); }); }, onCancel: () {}); }); @@ -92,7 +90,7 @@ class AppointmentCheckinBottomSheet extends StatelessWidget { ).onPress(() async { String onlineCheckInQRCode = (await BarcodeScanner.scan().then((value) => value.rawContent)); if (onlineCheckInQRCode != "") { - sendCheckInRequest(onlineCheckInQRCode, context); + sendCheckInRequest(onlineCheckInQRCode, 2, context); } else {} }), ], @@ -140,12 +138,12 @@ class AppointmentCheckinBottomSheet extends StatelessWidget { ); } - void sendCheckInRequest(String scannedCode, BuildContext context) async { + void sendCheckInRequest(String scannedCode, int checkInType, BuildContext context) async { LoaderBottomSheet.showLoader(loadingText: "Processing Check-In...".needTranslation); await myAppointmentsViewModel.sendCheckInNfcRequest( patientAppointmentHistoryResponseModel: patientAppointmentHistoryResponseModel, scannedCode: scannedCode, - checkInType: 2, + checkInType: checkInType, onSuccess: (apiResponse) { LoaderBottomSheet.hideLoader(); showCommonBottomSheetWithoutHeight(context, title: "Success".needTranslation, child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr()), callBackFunc: () async { diff --git a/lib/presentation/appointments/widgets/appointment_doctor_card.dart b/lib/presentation/appointments/widgets/appointment_doctor_card.dart index 6b5dde7e..ccf6674a 100644 --- a/lib/presentation/appointments/widgets/appointment_doctor_card.dart +++ b/lib/presentation/appointments/widgets/appointment_doctor_card.dart @@ -167,14 +167,14 @@ class AppointmentDoctorCard extends StatelessWidget { backgroundColor: AppColors.greyColor, borderColor: AppColors.greyColor, textColor: AppColors.blackColor, - fontSize: 14.f, + fontSize: 12.f, fontWeight: FontWeight.w500, borderRadius: 12.r, padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 0), height: 40.h, icon: AppAssets.rebook_appointment_icon, iconColor: AppColors.blackColor, - iconSize: 16.h, + iconSize: 14.h, ); } else { return patientAppointmentHistoryResponseModel.isLiveCareAppointment ?? false diff --git a/lib/presentation/appointments/widgets/ask_doctor_request_type_select.dart b/lib/presentation/appointments/widgets/ask_doctor_request_type_select.dart index 69cdca3e..01aab4e0 100644 --- a/lib/presentation/appointments/widgets/ask_doctor_request_type_select.dart +++ b/lib/presentation/appointments/widgets/ask_doctor_request_type_select.dart @@ -1,7 +1,6 @@ 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/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; diff --git a/lib/presentation/appointments/widgets/faculity_selection/facility_selection_item.dart b/lib/presentation/appointments/widgets/faculity_selection/facility_selection_item.dart index c7ef3a90..2f5589c8 100644 --- a/lib/presentation/appointments/widgets/faculity_selection/facility_selection_item.dart +++ b/lib/presentation/appointments/widgets/faculity_selection/facility_selection_item.dart @@ -4,10 +4,8 @@ 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/theme/colors.dart' show AppColors; -import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; class FacilitySelectionItem extends StatelessWidget { diff --git a/lib/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart b/lib/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart index cacc9d39..cb27f9f2 100644 --- a/lib/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart +++ b/lib/presentation/appointments/widgets/faculity_selection/facility_type_selection_widget.dart @@ -8,8 +8,6 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart' - show MyAppointmentsViewModel; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/faculity_selection/facility_selection_item.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; diff --git a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body_for_doctor_filter.dart b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body_for_doctor_filter.dart index 58a0d009..a2d22cda 100644 --- a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body_for_doctor_filter.dart +++ b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body_for_doctor_filter.dart @@ -1,21 +1,14 @@ import 'package:easy_localization/easy_localization.dart' show tr, StringTranslateExtension; import 'package:flutter/material.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/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.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/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart'; -import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors; -import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:provider/provider.dart'; class HospitalBottomSheetBodyForDoctorFilter extends StatelessWidget { diff --git a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart index 660f95e6..b01b541f 100644 --- a/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart +++ b/lib/presentation/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart @@ -7,7 +7,6 @@ import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; diff --git a/lib/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart b/lib/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart index b023f7a7..cbf68f62 100644 --- a/lib/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart +++ b/lib/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart @@ -4,7 +4,6 @@ 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/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:provider/provider.dart' show Consumer; diff --git a/lib/presentation/appointments/widgets/region_bottomsheet/region_list_item.dart b/lib/presentation/appointments/widgets/region_bottomsheet/region_list_item.dart index 754db53c..969e23af 100644 --- a/lib/presentation/appointments/widgets/region_bottomsheet/region_list_item.dart +++ b/lib/presentation/appointments/widgets/region_bottomsheet/region_list_item.dart @@ -5,7 +5,6 @@ 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/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors; diff --git a/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart b/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart index 6bc80072..2def72cf 100644 --- a/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart +++ b/lib/presentation/appointments/widgets/region_bottomsheet/region_list_widget.dart @@ -6,7 +6,6 @@ import 'package:hmg_patient_app_new/core/utils/utils.dart' show Utils; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart' show MyAppointmentsViewModel; import 'package:hmg_patient_app_new/presentation/appointments/widgets/region_bottomsheet/region_list_item.dart' show RegionListItem; import 'package:provider/provider.dart'; diff --git a/lib/presentation/blood_donation/widgets/select_blood_group_widget.dart b/lib/presentation/blood_donation/widgets/select_blood_group_widget.dart index f9cadb20..a5ac071c 100644 --- a/lib/presentation/blood_donation/widgets/select_blood_group_widget.dart +++ b/lib/presentation/blood_donation/widgets/select_blood_group_widget.dart @@ -5,7 +5,6 @@ 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/blood_donation/blood_donation_view_model.dart'; -import 'package:hmg_patient_app_new/presentation/blood_donation/widgets/city_list_item.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; class SelectBloodGroupWidget extends StatelessWidget { diff --git a/lib/presentation/blood_donation/widgets/select_city_widget.dart b/lib/presentation/blood_donation/widgets/select_city_widget.dart index a0e84777..8e2f9a0f 100644 --- a/lib/presentation/blood_donation/widgets/select_city_widget.dart +++ b/lib/presentation/blood_donation/widgets/select_city_widget.dart @@ -1,10 +1,8 @@ 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/blood_donation/blood_donation_view_model.dart'; import 'package:hmg_patient_app_new/presentation/blood_donation/widgets/city_list_item.dart'; -import 'package:hmg_patient_app_new/theme/colors.dart'; class SelectCityWidget extends StatelessWidget { SelectCityWidget({super.key, required this.bloodDonationViewModel}); diff --git a/lib/presentation/blood_donation/widgets/select_gender_widget.dart b/lib/presentation/blood_donation/widgets/select_gender_widget.dart index b253331c..67cd4bbb 100644 --- a/lib/presentation/blood_donation/widgets/select_gender_widget.dart +++ b/lib/presentation/blood_donation/widgets/select_gender_widget.dart @@ -5,7 +5,6 @@ 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/blood_donation/blood_donation_view_model.dart'; -import 'package:hmg_patient_app_new/presentation/blood_donation/widgets/city_list_item.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; class SelectGenderWidget extends StatelessWidget { diff --git a/lib/presentation/book_appointment/doctor_filter/RegionChips.dart b/lib/presentation/book_appointment/doctor_filter/RegionChips.dart index c81e5485..19e391ef 100644 --- a/lib/presentation/book_appointment/doctor_filter/RegionChips.dart +++ b/lib/presentation/book_appointment/doctor_filter/RegionChips.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; -import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart' - show BookAppointmentsViewModel; import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; diff --git a/lib/presentation/book_appointment/doctor_filter/clinic_bottomsheet.dart b/lib/presentation/book_appointment/doctor_filter/clinic_bottomsheet.dart index 155d8e36..982fc54d 100644 --- a/lib/presentation/book_appointment/doctor_filter/clinic_bottomsheet.dart +++ b/lib/presentation/book_appointment/doctor_filter/clinic_bottomsheet.dart @@ -2,26 +2,16 @@ import 'package:easy_localization/easy_localization.dart' show tr, StringTranslateExtension; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.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/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.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/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_filter/clinic_item.dart'; -import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/clinic_card.dart'; -import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors; -import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:provider/provider.dart'; -import '../../../features/book_appointments/models/resp_models/get_clinic_list_response_model.dart' show GetClinicsListResponseModel; class ClinicBottomSheet extends StatelessWidget { late BookAppointmentsViewModel appointmentsViewModel; diff --git a/lib/presentation/book_appointment/doctor_filter/doctors_filter.dart b/lib/presentation/book_appointment/doctor_filter/doctors_filter.dart index 6e51f8a1..e4d11bd1 100644 --- a/lib/presentation/book_appointment/doctor_filter/doctors_filter.dart +++ b/lib/presentation/book_appointment/doctor_filter/doctors_filter.dart @@ -9,7 +9,6 @@ import 'package:hmg_patient_app_new/features/book_appointments/book_appointments import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/hospital_bottom_sheet_body_for_doctor_filter.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_filter/RegionChips.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_filter/clinic_bottomsheet.dart'; diff --git a/lib/presentation/book_appointment/doctor_filter/facility_Chips.dart b/lib/presentation/book_appointment/doctor_filter/facility_Chips.dart index f416ed4d..e64c53fe 100644 --- a/lib/presentation/book_appointment/doctor_filter/facility_Chips.dart +++ b/lib/presentation/book_appointment/doctor_filter/facility_Chips.dart @@ -4,8 +4,6 @@ import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; -import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart' - show BookAppointmentsViewModel; import 'package:hmg_patient_app_new/features/doctor_filter/doctor_filter_view_model.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; diff --git a/lib/presentation/book_appointment/doctor_profile_page.dart b/lib/presentation/book_appointment/doctor_profile_page.dart index c3f4ad95..5ce7fac8 100644 --- a/lib/presentation/book_appointment/doctor_profile_page.dart +++ b/lib/presentation/book_appointment/doctor_profile_page.dart @@ -1,18 +1,13 @@ -import 'dart:math'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; -import 'package:hijri_gregorian_calendar/hijri_gregorian_calendar.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; -import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; -import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/appointment_calendar.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; diff --git a/lib/presentation/book_appointment/laser/laser_appointment.dart b/lib/presentation/book_appointment/laser/laser_appointment.dart index 440ae457..28f0f2d0 100644 --- a/lib/presentation/book_appointment/laser/laser_appointment.dart +++ b/lib/presentation/book_appointment/laser/laser_appointment.dart @@ -1,7 +1,6 @@ import 'package:easy_localization/easy_localization.dart'; 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/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/book_appointments/models/resp_models/laser_body_parts.dart'; @@ -82,7 +81,7 @@ class LaserAppointment extends StatelessWidget { activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), tabs: [ CustomTabBarModel(null,LocaleKeys.malE.tr()), - CustomTabBarModel(null,LocaleKeys.female.tr()), + CustomTabBarModel(null,"Female".needTranslation.tr()), ], onTabChange: (index) { var viewmodel = context.read(); diff --git a/lib/presentation/book_appointment/laser/widgets/body_type_listing.dart b/lib/presentation/book_appointment/laser/widgets/body_type_listing.dart index 46047ff7..baf72d26 100644 --- a/lib/presentation/book_appointment/laser/widgets/body_type_listing.dart +++ b/lib/presentation/book_appointment/laser/widgets/body_type_listing.dart @@ -1,7 +1,6 @@ import 'package:easy_localization/easy_localization.dart'; 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/book_appointments/models/LaserCategoryType.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; diff --git a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart index 2877b276..2371f4ac 100644 --- a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart +++ b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_details.dart @@ -1,3 +1,4 @@ + import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; @@ -322,15 +323,29 @@ class ImmediateLiveCarePaymentDetails extends StatelessWidget { } Future askVideoCallPermission() async { - Map statuses = await [Permission.camera, Permission.microphone, Permission.notification].request(); + bool hasPermission = false; + if (Platform.isIOS) { + Map statuses = await [Permission.camera, Permission.microphone].request(); - if (statuses[Permission.camera] == PermissionStatus.granted && statuses[Permission.microphone] == PermissionStatus.granted && statuses[Permission.notification] == PermissionStatus.granted) { - // Camera permission granted - return true; + if (statuses[Permission.camera] == PermissionStatus.granted && statuses[Permission.microphone] == PermissionStatus.granted) { + // Camera permission granted + hasPermission = true; + } else { + hasPermission = false; + } } else { - return false; + Map statuses = await [Permission.camera, Permission.microphone, Permission.notification].request(); + + if (statuses[Permission.camera] == PermissionStatus.granted && statuses[Permission.microphone] == PermissionStatus.granted && statuses[Permission.notification] == PermissionStatus.granted) { + // Camera permission granted + hasPermission = true; + } else { + hasPermission = false; + } } + return hasPermission; + // if (!(await Permission.camera.request().isGranted) || !(await Permission.microphone.request().isGranted)) { // return false; // } diff --git a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart index b0529694..48e79b18 100644 --- a/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart +++ b/lib/presentation/book_appointment/livecare/immediate_livecare_payment_page.dart @@ -11,30 +11,25 @@ import 'package:hmg_patient_app_new/core/cache_consts.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/date_util.dart'; -import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart'; import 'package:hmg_patient_app_new/features/payfort/models/apple_pay_request_insert_model.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/my_appointments/models/resp_models/patient_appointment_history_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/payfort/payfort_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/my_appointments_page.dart'; import 'package:hmg_patient_app_new/presentation/book_appointment/livecare/immediate_livecare_pending_request_page.dart'; import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/presentation/insurance/insurance_home_page.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; -import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/in_app_browser/InAppBrowser.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; -import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:smooth_corner/smooth_corner.dart'; diff --git a/lib/presentation/book_appointment/livecare/immediate_livecare_pending_request_page.dart b/lib/presentation/book_appointment/livecare/immediate_livecare_pending_request_page.dart index 8c8b79c1..8488a49f 100644 --- a/lib/presentation/book_appointment/livecare/immediate_livecare_pending_request_page.dart +++ b/lib/presentation/book_appointment/livecare/immediate_livecare_pending_request_page.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; @@ -11,13 +10,11 @@ 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/immediate_livecare/immediate_livecare_view_model.dart'; -import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/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/countdown_timer.dart'; -import 'package:lottie/lottie.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; diff --git a/lib/presentation/book_appointment/livecare/widgets/livecare_clinic_card.dart b/lib/presentation/book_appointment/livecare/widgets/livecare_clinic_card.dart index 3913f107..cdf13c65 100644 --- a/lib/presentation/book_appointment/livecare/widgets/livecare_clinic_card.dart +++ b/lib/presentation/book_appointment/livecare/widgets/livecare_clinic_card.dart @@ -7,7 +7,6 @@ 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/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/immediate_livecare/models/resp_models/get_livecare_immediate_clinics_response_model.dart'; import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; diff --git a/lib/presentation/book_appointment/livecare/widgets/select_livecare_call_type.dart b/lib/presentation/book_appointment/livecare/widgets/select_livecare_call_type.dart index e4d69b16..31fb71f1 100644 --- a/lib/presentation/book_appointment/livecare/widgets/select_livecare_call_type.dart +++ b/lib/presentation/book_appointment/livecare/widgets/select_livecare_call_type.dart @@ -6,10 +6,7 @@ import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; -import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/immediate_livecare/immediate_livecare_view_model.dart'; -import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/medical_file/widgets/medical_file_card.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; class SelectLiveCareCallType extends StatelessWidget { diff --git a/lib/presentation/book_appointment/review_appointment_page.dart b/lib/presentation/book_appointment/review_appointment_page.dart index f76a5b00..40abd404 100644 --- a/lib/presentation/book_appointment/review_appointment_page.dart +++ b/lib/presentation/book_appointment/review_appointment_page.dart @@ -21,7 +21,6 @@ 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/loading_dialog.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; diff --git a/lib/presentation/book_appointment/search_doctor_by_name.dart b/lib/presentation/book_appointment/search_doctor_by_name.dart index bdb67733..d0084973 100644 --- a/lib/presentation/book_appointment/search_doctor_by_name.dart +++ b/lib/presentation/book_appointment/search_doctor_by_name.dart @@ -2,8 +2,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_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'; @@ -21,7 +19,6 @@ import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; -import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:provider/provider.dart'; import '../../features/book_appointments/models/resp_models/doctors_list_response_model.dart'; diff --git a/lib/presentation/book_appointment/select_clinic_page.dart b/lib/presentation/book_appointment/select_clinic_page.dart index d801bdb9..450e86b5 100644 --- a/lib/presentation/book_appointment/select_clinic_page.dart +++ b/lib/presentation/book_appointment/select_clinic_page.dart @@ -33,7 +33,6 @@ import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; -import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:provider/provider.dart'; class SelectClinicPage extends StatefulWidget { @@ -82,7 +81,14 @@ class _SelectClinicPageState extends State { child: CustomButton( text: LocaleKeys.bookAppo.tr(), onPressed: () { - onClinicSelected(GetClinicsListResponseModel(clinicID: 108, clinicDescription: "asdfds", clinicDescriptionN: "asdfds")); + if (widget.calculatedResult["clinicId"] == null) { + bookAppointmentsViewModel.setIsDoctorsListLoading(true); + bookAppointmentsViewModel.isGetDocForHealthCal = true; + bookAppointmentsViewModel.calculationID = widget.calculatedResult["calculationID"]; + Navigator.push(context, CustomPageRoute(page: SelectDoctorPage())); + } else { + onClinicSelected(GetClinicsListResponseModel(clinicID: widget.calculatedResult["clinicId"], clinicDescription: "asdfds", clinicDescriptionN: "asdfds")); + } }, icon: null, fontSize: 16.f, @@ -248,7 +254,6 @@ class _SelectClinicPageState extends State { } Widget resultWidget({required HealthCalculatorsTypeEnum type, dynamic calculatedResult}) { - print(calculatedResult); return Column( children: [ if (type == HealthCalculatorsTypeEnum.bmi) ...[ @@ -747,8 +752,6 @@ class _SelectClinicPageState extends State { ], ), ), - - SizedBox(height: 16.h), Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, customBorder: BorderRadius.all(Radius.circular(24.r))), @@ -793,7 +796,6 @@ class _SelectClinicPageState extends State { ], ), ), - SizedBox(height: 16.h), Container( decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, customBorder: BorderRadius.all(Radius.circular(24.r))), @@ -838,8 +840,6 @@ class _SelectClinicPageState extends State { ], ), ), - - ], ) ], diff --git a/lib/presentation/book_appointment/select_doctor_page.dart b/lib/presentation/book_appointment/select_doctor_page.dart index 46c37744..d77e152b 100644 --- a/lib/presentation/book_appointment/select_doctor_page.dart +++ b/lib/presentation/book_appointment/select_doctor_page.dart @@ -17,6 +17,7 @@ import 'package:hmg_patient_app_new/presentation/book_appointment/doctor_profile import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/doctor_card.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; @@ -32,20 +33,30 @@ class SelectDoctorPage extends StatefulWidget { class _SelectDoctorPageState extends State { TextEditingController searchEditingController = TextEditingController(); + int? expandedIndex; FocusNode textFocusNode = FocusNode(); late AppState appState; late BookAppointmentsViewModel bookAppointmentsViewModel; + // Scroll controller to control page scrolling when a group expands + late ScrollController _scrollController; + // Map of keys for each item to allow scrolling to them + final Map _itemKeys = {}; + @override void initState() { + _scrollController = ScrollController(); scheduleMicrotask(() { + bookAppointmentsViewModel.setIsNearestAppointmentSelected(false); if (bookAppointmentsViewModel.isLiveCareSchedule) { bookAppointmentsViewModel.getLiveCareDoctorsList(); } else { if (bookAppointmentsViewModel.selectedClinic.clinicID == 17) { bookAppointmentsViewModel.getDentalChiefComplaintDoctorsList(); + } else if (bookAppointmentsViewModel.isGetDocForHealthCal) { + bookAppointmentsViewModel.getDoctorsListByHealthCal(); } else { bookAppointmentsViewModel.getDoctorsList(); } @@ -54,6 +65,12 @@ class _SelectDoctorPageState extends State { super.initState(); } + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { bookAppointmentsViewModel = Provider.of(context, listen: false); @@ -63,6 +80,7 @@ class _SelectDoctorPageState extends State { body: CollapsingListView( title: "Choose Doctor".needTranslation, child: SingleChildScrollView( + controller: _scrollController, child: Padding( padding: EdgeInsets.symmetric(horizontal: 24.h), child: Consumer(builder: (context, bookAppointmentsVM, child) { @@ -105,23 +123,80 @@ class _SelectDoctorPageState extends State { ), ], ), + SizedBox(height: 16.h), + Row( + children: [ + CustomButton( + text: LocaleKeys.byClinic.tr(context: context), + onPressed: () { + bookAppointmentsVM.setIsSortByClinic(true); + }, + backgroundColor: bookAppointmentsVM.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderColor: bookAppointmentsVM.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2), + textColor: bookAppointmentsVM.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: () { + bookAppointmentsVM.setIsSortByClinic(false); + }, + backgroundColor: bookAppointmentsVM.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, + borderColor: bookAppointmentsVM.isSortByClinic ? AppColors.textColor.withOpacity(0.2) : AppColors.primaryRedColor, + textColor: bookAppointmentsVM.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, + fontSize: 12, + fontWeight: FontWeight.w500, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + ], + ).paddingSymmetrical(0.h, 0.h), + SizedBox(height: 16.h), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.nearestAppo.tr(context: context).toText13(isBold: true), + SizedBox(height: 4.h), + "View nearest available appointments".needTranslation.toText11(color: AppColors.textColorLight, weight: FontWeight.w500), + ], + ), + const Spacer(), + Switch( + activeThumbColor: AppColors.successColor, + activeTrackColor: AppColors.successColor.withValues(alpha: .15), + value: bookAppointmentsVM.isNearestAppointmentSelected, + onChanged: (newValue) async { + bookAppointmentsVM.setIsNearestAppointmentSelected(newValue); + + }, + ), + ], + ), ListView.separated( - padding: EdgeInsets.only(top: 24.h), + padding: EdgeInsets.only(top: 16.h), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: bookAppointmentsVM.isDoctorsListLoading ? 5 - : (bookAppointmentsVM.isLiveCareSchedule - ? (bookAppointmentsVM.liveCareDoctorsList.isNotEmpty ? bookAppointmentsVM.liveCareDoctorsList.length : 1) - : (bookAppointmentsVM.doctorsList.isNotEmpty ? bookAppointmentsVM.doctorsList.length : 1)), + : (bookAppointmentsVM.doctorsListGrouped.isNotEmpty ? bookAppointmentsVM.doctorsListGrouped.length : 1), itemBuilder: (context, index) { + final isExpanded = expandedIndex == index; return bookAppointmentsVM.isDoctorsListLoading ? DoctorCard( doctorsListResponseModel: DoctorsListResponseModel(), isLoading: true, bookAppointmentsViewModel: bookAppointmentsViewModel, ) - : checkIsDoctorsListEmpty() + : bookAppointmentsVM.doctorsListGrouped.isEmpty ? Utils.getNoDataWidget(context, noDataText: "No Doctor found for selected criteria...".needTranslation) : AnimationConfiguration.staggeredList( position: index, @@ -130,40 +205,107 @@ class _SelectDoctorPageState extends State { verticalOffset: 100.0, child: FadeInAnimation( child: AnimatedContainer( + key: _itemKeys.putIfAbsent(index, () => GlobalKey()), duration: Duration(milliseconds: 300), curve: Curves.easeInOut, - decoration: - RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), - child: DoctorCard( - doctorsListResponseModel: bookAppointmentsVM.isLiveCareSchedule - ? bookAppointmentsVM.liveCareDoctorsList[index] - : bookAppointmentsVM.doctorsList[index], - isLoading: false, - bookAppointmentsViewModel: bookAppointmentsViewModel, - ).onPress(() async { - bookAppointmentsVM.setSelectedDoctor(bookAppointmentsVM.isLiveCareSchedule - ? bookAppointmentsVM.liveCareDoctorsList[index] - : bookAppointmentsVM.doctorsList[index]); - // bookAppointmentsVM.setSelectedDoctor(DoctorsListResponseModel()); - LoaderBottomSheet.showLoader(); - await bookAppointmentsVM.getDoctorProfile(onSuccess: (dynamic respData) { - LoaderBottomSheet.hideLoader(); - Navigator.of(context).push( - CustomPageRoute( - page: DoctorProfilePage(), - ), - ); - }, onError: (err) { - LoaderBottomSheet.hideLoader(); - showCommonBottomSheetWithoutHeight( - context, - child: Utils.getErrorWidget(loadingText: err), - callBackFunc: () {}, - isFullScreen: false, - isCloseButtonVisible: true, - ); - }); - }), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), + child: InkWell( + onTap: () { + setState(() { + expandedIndex = isExpanded ? null : index; + }); + // After rebuild, ensure the expanded item is visible + WidgetsBinding.instance.addPostFrameCallback((_) { + final key = _itemKeys[index]; + if (key != null && key.currentContext != null && expandedIndex == index) { + Scrollable.ensureVisible( + key.currentContext!, + duration: Duration(milliseconds: 350), + curve: Curves.easeInOut, + alignment: 0.1, + ); + } + }); + }, + child: Padding( + padding: EdgeInsets.all(16.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Header row with count badge and expand/collapse icon + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + CustomButton( + text: "${bookAppointmentsVM.doctorsListGrouped[index].length} ${'doctors'.needTranslation}", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ), + Icon(isExpanded ? Icons.expand_less : Icons.expand_more), + ], + ), + SizedBox(height: 8.h), + // Clinic/Hospital name as group title + Text( + bookAppointmentsVM.isSortByClinic + ? (bookAppointmentsVM.doctorsListGrouped[index].first.clinicName ?? 'Unknown') + : (bookAppointmentsVM.doctorsListGrouped[index].first.projectName ?? 'Unknown'), + style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), + overflow: TextOverflow.ellipsis, + ), + // Expanded content - list of doctors in this group + AnimatedSwitcher( + duration: Duration(milliseconds: 400), + child: isExpanded + ? Container( + key: ValueKey(index), + padding: EdgeInsets.only(top: 12.h), + child: Column( + children: bookAppointmentsVM.doctorsListGrouped[index].map((doctor) { + return Container( + margin: EdgeInsets.only(bottom: 12.h), + child: DoctorCard( + doctorsListResponseModel: doctor, + isLoading: false, + bookAppointmentsViewModel: bookAppointmentsViewModel, + ).onPress(() async { + bookAppointmentsVM.setSelectedDoctor(doctor); + LoaderBottomSheet.showLoader(); + await bookAppointmentsVM.getDoctorProfile(onSuccess: (dynamic respData) { + LoaderBottomSheet.hideLoader(); + Navigator.of(context).push( + CustomPageRoute( + page: DoctorProfilePage(), + ), + ); + }, onError: (err) { + LoaderBottomSheet.hideLoader(); + showCommonBottomSheetWithoutHeight( + context, + child: Utils.getErrorWidget(loadingText: err), + callBackFunc: () {}, + isFullScreen: false, + isCloseButtonVisible: true, + ); + }); + }), + ); + }).toList(), + ), + ) + : SizedBox.shrink(), + ), + ], + ), + ), + ), ), ), ), diff --git a/lib/presentation/book_appointment/waiting_appointment/waiting_appointment_online_checkin_sheet.dart b/lib/presentation/book_appointment/waiting_appointment/waiting_appointment_online_checkin_sheet.dart index 965844a4..8a04843d 100644 --- a/lib/presentation/book_appointment/waiting_appointment/waiting_appointment_online_checkin_sheet.dart +++ b/lib/presentation/book_appointment/waiting_appointment/waiting_appointment_online_checkin_sheet.dart @@ -1,4 +1,3 @@ -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; diff --git a/lib/presentation/book_appointment/widgets/appointment_calendar.dart b/lib/presentation/book_appointment/widgets/appointment_calendar.dart index 7c4226c0..b2666b69 100644 --- a/lib/presentation/book_appointment/widgets/appointment_calendar.dart +++ b/lib/presentation/book_appointment/widgets/appointment_calendar.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; @@ -21,7 +20,6 @@ import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; -import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:lottie/lottie.dart'; import 'package:provider/provider.dart'; import 'package:smooth_corner/smooth_corner.dart'; diff --git a/lib/presentation/book_appointment/widgets/doctor_card.dart b/lib/presentation/book_appointment/widgets/doctor_card.dart index 7257dbf4..ffe26ffb 100644 --- a/lib/presentation/book_appointment/widgets/doctor_card.dart +++ b/lib/presentation/book_appointment/widgets/doctor_card.dart @@ -110,17 +110,19 @@ class DoctorCard extends StatelessWidget { AppCustomChipWidget( labelText: "Branch: ${isLoading ? "Olaya Hospital" : doctorsListResponseModel.projectName}".needTranslation, ).toShimmer2(isShow: isLoading), - AppCustomChipWidget( + doctorsListResponseModel.decimalDoctorRate != null ? AppCustomChipWidget( icon: AppAssets.rating_icon, iconColor: AppColors.ratingColorYellow, labelText: "Rating: ${isLoading ? 4.78 : doctorsListResponseModel.decimalDoctorRate}".needTranslation, - ).toShimmer2(isShow: isLoading), - doctorsListResponseModel.nearestFreeSlot != null + ).toShimmer2(isShow: isLoading) : SizedBox(), + bookAppointmentsViewModel.isNearestAppointmentSelected + ? doctorsListResponseModel.nearestFreeSlot != null ? AppCustomChipWidget( labelText: (isLoading ? "Cardiologist" : DateUtil.getDateStringForNearestSlot(doctorsListResponseModel.nearestFreeSlot)).needTranslation, backgroundColor: AppColors.successColor, textColor: AppColors.whiteColor, ).toShimmer2(isShow: isLoading) + : SizedBox.shrink() : SizedBox.shrink(), ], ), diff --git a/lib/presentation/contact_us/feedback_page.dart b/lib/presentation/contact_us/feedback_page.dart index 71601795..078b3a15 100644 --- a/lib/presentation/contact_us/feedback_page.dart +++ b/lib/presentation/contact_us/feedback_page.dart @@ -8,13 +8,10 @@ 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/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/contact_us/contact_us_view_model.dart'; import 'package:hmg_patient_app_new/features/contact_us/models/feedback_type.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_card.dart'; import 'package:hmg_patient_app_new/presentation/contact_us/widgets/feedback_appointment_selection.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; diff --git a/lib/presentation/contact_us/find_us_page.dart b/lib/presentation/contact_us/find_us_page.dart index a4e42585..5957bb83 100644 --- a/lib/presentation/contact_us/find_us_page.dart +++ b/lib/presentation/contact_us/find_us_page.dart @@ -4,14 +4,11 @@ import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; -import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/contact_us/contact_us_view_model.dart'; -import 'package:hmg_patient_app_new/features/medical_file/models/patient_sickleave_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/contact_us/widgets/find_us_item_card.dart'; -import 'package:hmg_patient_app_new/presentation/medical_file/widgets/patient_sick_leave_card.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; diff --git a/lib/presentation/contact_us/widgets/find_us_item_card.dart b/lib/presentation/contact_us/widgets/find_us_item_card.dart index a59959fd..96375c0c 100644 --- a/lib/presentation/contact_us/widgets/find_us_item_card.dart +++ b/lib/presentation/contact_us/widgets/find_us_item_card.dart @@ -4,13 +4,11 @@ import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; -import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/contact_us/models/resp_models/get_hmg_locations.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; -import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; import 'package:maps_launcher/maps_launcher.dart'; import 'package:url_launcher/url_launcher.dart'; diff --git a/lib/presentation/covid19test/covid19_landing_page.dart b/lib/presentation/covid19test/covid19_landing_page.dart new file mode 100644 index 00000000..62bd651d --- /dev/null +++ b/lib/presentation/covid19test/covid19_landing_page.dart @@ -0,0 +1,283 @@ +import 'dart:async'; + +import 'package:easy_localization/easy_localization.dart'; +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/habib_wallet/habib_wallet_view_model.dart'; +import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; +import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; +import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; +import 'package:provider/provider.dart'; + +import 'covid_19_questionnaire.dart'; + +class Covid19LandingPage extends StatefulWidget { +const Covid19LandingPage({super.key}); + +@override +State createState() => _Covid19LandingPageState(); +} + +class _Covid19LandingPageState extends State { + + late HabibWalletViewModel habibWalletVM; + int? _selectedBranchIndex; + + @override + void initState() { + habibWalletVM = Provider.of(context, listen: false); + scheduleMicrotask(() { + getProjectList(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: Column( + children: [ + Expanded( + child: CollapsingListView( + title: "COVID-19", + child: Padding( + padding: EdgeInsets.all(24.w), + child: SingleChildScrollView( + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: false, + ), + child: Padding( + padding: EdgeInsets.all(20.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Get the results in Few Hours" + .toText18( + color: AppColors.textColor, + weight: FontWeight.w600, + ), + SizedBox(height: 16.h), + LocaleKeys.covid_info + .tr() + .toText14( + color: AppColors.greyTextColor, + weight: FontWeight.w400, + height: 1.6, + ), + ], + ), + ), + ), + ), + ), + ), + ), + Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + // borderRadius: 24.r, + hasShadow: true, + customBorder: BorderRadius.only(topLeft:Radius.circular(24.r) , topRight:Radius.circular(24.r)) + ), + child: SizedBox( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CustomButton( + text: "SelectLocation".needTranslation, + onPressed: () { + _showBranchBottomSheet(context); + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: AppColors.whiteColor, + fontSize: 16.f, + fontWeight: FontWeight.w500, + borderRadius: 12.r, + padding: EdgeInsets.symmetric(horizontal: 10.w), + height: 50.h, + iconSize: 18.h, + ).paddingSymmetrical(16.h, 24.w), + ], + ), + ), + ), + ], + )); + } + void _showBranchBottomSheet(BuildContext context, ) { + // Set first branch as selected by default + setState(() { + _selectedBranchIndex = 0; + }); + + showCommonBottomSheet( + + context, + title: "Select Branch".needTranslation, + height: ResponsiveExtension.screenHeight * 0.651, + child: StatefulBuilder( + builder: (context, setBottomSheetState) { + return Consumer( + builder: (context, habibWalletVM, child) { + + final hospitals = habibWalletVM.advancePaymentHospitals; + if (hospitals.isEmpty) { + return const Center( + child: Padding( + padding: EdgeInsets.all(16.0), + child: Text('No branches available'), + ), + ); + } + + return Column( + children: [ + Expanded( + child:Container( + margin: EdgeInsets.only(left: 16.w, right: 16.w, top: 12.h, bottom: 24.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + hasShadow: true, + customBorder: BorderRadius.only( + topLeft: Radius.circular(24.r), + topRight: Radius.circular(24.r), + ), + ), child: ListView.separated( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), + itemBuilder: (context, index) { + final branch = hospitals[index]; + final isSelected = _selectedBranchIndex == index; + return GestureDetector( + onTap: () { + setBottomSheetState(() { + _selectedBranchIndex = index; + }); + setState(() { + _selectedBranchIndex = index; + }); + }, + child: Container( + + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), + child: Row( + children: [ + // Radio button + Container( + width: 20.w, + height: 20.h, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: isSelected + ? AppColors.primaryRedColor + : AppColors.greyTextColor.withValues(alpha: 0.3), + width: 2, + ), + ), + child: isSelected + ? Center( + child: Container( + width: 10.w, + height: 10.h, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: AppColors.primaryRedColor, + ), + ), + ) + : null, + ), + SizedBox(width: 12.w), + // Branch details + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + SizedBox(height: 4.h), + (branch.desciption ?? 'Unknown').toText14( + color: AppColors.textColor, + weight: FontWeight.w600, + ), + ], + ), + ), + // Location icon + + ], + ), + ), + ); + }, + separatorBuilder: (context, index) => SizedBox(height: 12.h), + itemCount: hospitals.length, + )), + ), + // Next button + Container( + padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 16.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + hasShadow: true, + customBorder: BorderRadius.only( + topLeft: Radius.circular(24.r), + topRight: Radius.circular(24.r), + ), + ), + child: SafeArea( + top: false, + child: CustomButton( + text: "Next".needTranslation, + onPressed: (){ + + Navigator.of(context) + .push( + CustomPageRoute( + page: Covid19Questionnaire(selectedHospital: hospitals[_selectedBranchIndex!],), + ), + ); + + }, + backgroundColor: _selectedBranchIndex != null + ? AppColors.primaryRedColor + : AppColors.greyTextColor.withValues(alpha: 0.3), + borderColor: _selectedBranchIndex != null + ? AppColors.primaryRedColor + : AppColors.greyTextColor.withValues(alpha: 0.3), + textColor: AppColors.whiteColor, + fontSize: 16.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + height: 56.h, + ), + ), + ), + ], + ); + }, + ); + }, + ), + + ); + } + + getProjectList() async{ + await habibWalletVM.getProjectsList(); + } +} + + diff --git a/lib/presentation/covid19test/covid_19_questionnaire.dart b/lib/presentation/covid19test/covid_19_questionnaire.dart new file mode 100644 index 00000000..8d7e8bdd --- /dev/null +++ b/lib/presentation/covid19test/covid_19_questionnaire.dart @@ -0,0 +1,132 @@ +import 'dart:async'; + +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/hmg_services/hmg_services_view_model.dart'; +import 'package:hmg_patient_app_new/features/hmg_services/models/ui_models/covid_questionnare_model.dart'; +import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_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:hmg_patient_app_new/widgets/CustomSwitch.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; + +import 'package:provider/provider.dart'; + +class Covid19Questionnaire extends StatefulWidget { + final HospitalsModel selectedHospital; + const Covid19Questionnaire({super.key, required this.selectedHospital}); + + @override + State createState() => _Covid19QuestionnaireState(); +} + +class _Covid19QuestionnaireState extends State { + late HmgServicesViewModel hmgServicesViewModel; + List qaList = []; + + + @override + void initState() { + hmgServicesViewModel = Provider.of(context, listen: false); + scheduleMicrotask(() { + setState(() { + qaList = hmgServicesViewModel.getQuestionsFromJson(); + }); + }); + super.initState(); + } + + void _toggleAnswer(int index, bool value) { + setState(() { + qaList[index].ans = value ? 1 : 0; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColors.bgScaffoldColor, + body: Column(children: [ + Expanded( + child: CollapsingListView( + title: "COVID-19", + child: Padding( + padding: EdgeInsets.all(24.w), + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 24.r, + hasShadow: false, + ), + child: Padding( + padding: EdgeInsets.all(20.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Please answer below questionnaire:".toText14( + color: AppColors.textColor, + weight: FontWeight.w500, + ), + SizedBox(height: 20.h), + // Question list + ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: qaList.length, + separatorBuilder: (context, index) => SizedBox(height: 16.h), + itemBuilder: (context, index) { + final question = qaList[index]; + final isAnswerYes = question.ans == 1; + + return Row( + children: [ + Expanded( + child: (question.questionEn ?? '').toText14( + color: AppColors.textColor, + weight: FontWeight.w400, + ), + ), + SizedBox(width: 12.w), + CustomSwitch( + value: isAnswerYes, + onChanged: (value) => _toggleAnswer(index, value), + ), + ], + ); + }, + ), + ], + ), + ), + ), + ), + ), + SizedBox(height: 16.h), + // Next button + CustomButton( + text: "Next".needTranslation, + onPressed: () { + // Handle next action + }, + backgroundColor: AppColors.primaryRedColor, + borderColor: AppColors.primaryRedColor, + textColor: AppColors.whiteColor, + fontSize: 16.f, + fontWeight: FontWeight.w600, + borderRadius: 12.r, + height: 56.h, + ), + ], + ), + ), + ), + ), + ])); + } +} diff --git a/lib/presentation/e_referral/e_referral_form_manager.dart b/lib/presentation/e_referral/e_referral_form_manager.dart index f7093c58..9e5cbe8c 100644 --- a/lib/presentation/e_referral/e_referral_form_manager.dart +++ b/lib/presentation/e_referral/e_referral_form_manager.dart @@ -1,6 +1,5 @@ // managers/referral_form_manager.dart import 'package:flutter/material.dart'; -import 'package:hmg_patient_app_new/core/common_models/nationality_country_model.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/create_e_referral_model.dart'; import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_all_cities_resp_model.dart'; diff --git a/lib/presentation/e_referral/e_referral_search_result.dart b/lib/presentation/e_referral/e_referral_search_result.dart index ba31f1b3..8702d5a8 100644 --- a/lib/presentation/e_referral/e_referral_search_result.dart +++ b/lib/presentation/e_referral/e_referral_search_result.dart @@ -1,4 +1,3 @@ -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; diff --git a/lib/presentation/e_referral/widget/e_referral_other_details.dart b/lib/presentation/e_referral/widget/e_referral_other_details.dart index fd1649f4..6efd0638 100644 --- a/lib/presentation/e_referral/widget/e_referral_other_details.dart +++ b/lib/presentation/e_referral/widget/e_referral_other_details.dart @@ -1,5 +1,4 @@ import 'dart:io'; -import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/utils/validation_utils.dart'; @@ -233,7 +232,6 @@ class _OtherDetailsStepState extends State { } void _showBranchBottomSheet(BuildContext context, ReferralFormManager formManager) { - final habibWalletVM = context.read(); showCommonBottomSheetWithoutHeight( context, diff --git a/lib/presentation/emergency_services/RRT/rrt_map_screen.dart b/lib/presentation/emergency_services/RRT/rrt_map_screen.dart index 3a17e5d3..afe68b60 100644 --- a/lib/presentation/emergency_services/RRT/rrt_map_screen.dart +++ b/lib/presentation/emergency_services/RRT/rrt_map_screen.dart @@ -1,4 +1,3 @@ -import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -8,13 +7,11 @@ 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/emergency_services/models/AmbulanceCallingPlace.dart'; import 'package:hmg_patient_app_new/features/location/GeocodeResponse.dart'; import 'package:hmg_patient_app_new/features/location/PlaceDetails.dart'; import 'package:hmg_patient_app_new/features/location/PlacePrediction.dart'; import 'package:hmg_patient_app_new/features/location/location_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_doctor_card.dart'; import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/AddressItem.dart'; import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart'; import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/appointment_bottom_sheet.dart' show AppointmentBottomSheet; diff --git a/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart b/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart index 66894b6f..13e01064 100644 --- a/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart +++ b/lib/presentation/emergency_services/RRT/rrt_request_type_select.dart @@ -1,5 +1,4 @@ import 'package:easy_localization/easy_localization.dart' show tr, StringTranslateExtension; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; @@ -11,8 +10,6 @@ import 'package:hmg_patient_app_new/features/emergency_services/models/resp_mode import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; -import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; -import 'package:hmg_patient_app_new/widgets/radio/custom_radio_button.dart'; import 'package:provider/provider.dart'; class RrtRequestTypeSelect extends StatelessWidget { diff --git a/lib/presentation/emergency_services/RRT/terms_and_condition.dart b/lib/presentation/emergency_services/RRT/terms_and_condition.dart index 8a507922..1d1dac16 100644 --- a/lib/presentation/emergency_services/RRT/terms_and_condition.dart +++ b/lib/presentation/emergency_services/RRT/terms_and_condition.dart @@ -1,14 +1,10 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_widget_from_html/flutter_widget_from_html.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/emergency_services/emergency_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 TermsAndCondition extends StatelessWidget { final String termsAndCondition; diff --git a/lib/presentation/emergency_services/call_ambulance/requesting_services_page.dart b/lib/presentation/emergency_services/call_ambulance/requesting_services_page.dart index 83c16b6c..396e5098 100644 --- a/lib/presentation/emergency_services/call_ambulance/requesting_services_page.dart +++ b/lib/presentation/emergency_services/call_ambulance/requesting_services_page.dart @@ -1,15 +1,10 @@ -import 'dart:async'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; -import 'package:hmg_patient_app_new/features/emergency_services/models/request_model/PatientER_RC.dart'; -import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/tracking_screen.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; -import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart' - show CustomPageRoute; import 'package:lottie/lottie.dart'; class RequestingServicesPage extends StatelessWidget { diff --git a/lib/presentation/emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart b/lib/presentation/emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart index 71e589ea..7d243934 100644 --- a/lib/presentation/emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart +++ b/lib/presentation/emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart @@ -5,22 +5,13 @@ import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/debouncer.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/book_appointments/book_appointments_view_model.dart'; -import 'package:hmg_patient_app_new/features/emergency_services/emergency_services_view_model.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart' show HospitalsModel; -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/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart'; import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/type_selection_widget.dart'; -import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; -import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; -import 'package:provider/provider.dart'; class HospitalBottomSheetBody extends StatelessWidget { diff --git a/lib/presentation/emergency_services/call_ambulance/widgets/ambulance_option_selection_bottomsheet.dart b/lib/presentation/emergency_services/call_ambulance/widgets/ambulance_option_selection_bottomsheet.dart index de20d1aa..be1d3800 100644 --- a/lib/presentation/emergency_services/call_ambulance/widgets/ambulance_option_selection_bottomsheet.dart +++ b/lib/presentation/emergency_services/call_ambulance/widgets/ambulance_option_selection_bottomsheet.dart @@ -2,12 +2,9 @@ import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart' show AppAssets; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart' show Utils; -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/emergency_services/models/resp_model/PatientERTransportationMethod.dart'; import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/transport_option_Item.dart' show TransportOptionItem; -import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:provider/provider.dart'; class AmbulanceOptionSelectionBottomSheet extends StatelessWidget { diff --git a/lib/presentation/emergency_services/call_ambulance/widgets/appointment_bottom_sheet.dart b/lib/presentation/emergency_services/call_ambulance/widgets/appointment_bottom_sheet.dart index 6f5db922..e1f7420a 100644 --- a/lib/presentation/emergency_services/call_ambulance/widgets/appointment_bottom_sheet.dart +++ b/lib/presentation/emergency_services/call_ambulance/widgets/appointment_bottom_sheet.dart @@ -1,13 +1,8 @@ import 'package:flutter/cupertino.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.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/models/resp_models/patient_appointment_history_response_model.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_card.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_doctor_card.dart'; -import 'package:hmg_patient_app_new/presentation/book_appointment/widgets/doctor_card.dart'; -import 'package:hmg_patient_app_new/theme/colors.dart'; -import 'package:provider/provider.dart'; class AppointmentBottomSheet extends StatelessWidget{ diff --git a/lib/presentation/emergency_services/call_ambulance/widgets/type_selection_widget.dart b/lib/presentation/emergency_services/call_ambulance/widgets/type_selection_widget.dart index 3b8d8d71..1b851653 100644 --- a/lib/presentation/emergency_services/call_ambulance/widgets/type_selection_widget.dart +++ b/lib/presentation/emergency_services/call_ambulance/widgets/type_selection_widget.dart @@ -2,12 +2,9 @@ import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.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/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; -import 'package:provider/provider.dart' show Consumer; class TypeSelectionWidget extends StatelessWidget { final String hmcCount; 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 0dfd0813..ee061b70 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 @@ -8,7 +8,6 @@ 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/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/emergency_services/er_online_checkin/er_online_checkin_select_checkin_bottom_sheet.dart'; import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; diff --git a/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_details_page.dart b/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_details_page.dart index 3aa975d9..f48efe73 100644 --- a/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_details_page.dart +++ b/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_details_page.dart @@ -10,7 +10,6 @@ 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/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/my_appointments_page.dart'; import 'package:hmg_patient_app_new/presentation/emergency_services/er_online_checkin/er_online_checkin_payment_page.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; diff --git a/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_select_checkin_bottom_sheet.dart b/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_select_checkin_bottom_sheet.dart index 0b224178..d44686ca 100644 --- a/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_select_checkin_bottom_sheet.dart +++ b/lib/presentation/emergency_services/er_online_checkin/er_online_checkin_select_checkin_bottom_sheet.dart @@ -1,4 +1,3 @@ -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; @@ -10,17 +9,10 @@ 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/my_appointments/models/resp_models/patient_appointment_history_response_model.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; -import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/my_appointments_page.dart'; -import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:barcode_scan2/barcode_scan2.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/nfc/nfc_reader_sheet.dart'; -import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; -import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; class ErOnlineCheckinSelectCheckinBottomSheet extends StatelessWidget { ErOnlineCheckinSelectCheckinBottomSheet({super.key, required this.projectID}); diff --git a/lib/presentation/emergency_services/history/er_history_listing.dart b/lib/presentation/emergency_services/history/er_history_listing.dart index b98f2f13..fe1ed317 100644 --- a/lib/presentation/emergency_services/history/er_history_listing.dart +++ b/lib/presentation/emergency_services/history/er_history_listing.dart @@ -1,4 +1,3 @@ -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart' show AppAssets; import 'package:hmg_patient_app_new/core/app_export.dart'; @@ -9,7 +8,6 @@ import 'package:hmg_patient_app_new/features/emergency_services/emergency_servic import 'package:hmg_patient_app_new/features/emergency_services/models/OrderDisplay.dart'; import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/AmbulanceRequestOrdersModel.dart'; import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/RRTServiceData.dart'; -import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/emergency_services/history/widget/ambulance_history_item.dart' show AmbulanceHistoryItem; import 'package:hmg_patient_app_new/presentation/emergency_services/history/widget/rrt_item.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; diff --git a/lib/presentation/emergency_services/history/widget/rrt_item.dart b/lib/presentation/emergency_services/history/widget/rrt_item.dart index 61eccedb..dfb6e79b 100644 --- a/lib/presentation/emergency_services/history/widget/rrt_item.dart +++ b/lib/presentation/emergency_services/history/widget/rrt_item.dart @@ -5,7 +5,6 @@ import 'package:hmg_patient_app_new/core/utils/date_util.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/emergency_services/models/resp_model/AmbulanceRequestOrdersModel.dart'; import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/RRTServiceData.dart'; import 'package:hmg_patient_app_new/presentation/emergency_services/history/widget/RequestStatus.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; diff --git a/lib/presentation/emergency_services/nearest_er_page.dart b/lib/presentation/emergency_services/nearest_er_page.dart index 13373f1c..16863bf6 100644 --- a/lib/presentation/emergency_services/nearest_er_page.dart +++ b/lib/presentation/emergency_services/nearest_er_page.dart @@ -14,7 +14,6 @@ import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:provider/provider.dart' show Selector, WatchContext, ReadContext; -import '../../core/enums.dart' show SelectionTypeEnum; import '../../core/utils/debouncer.dart' show Debouncer; class NearestErPage extends StatefulWidget { diff --git a/lib/presentation/emergency_services/widgets/location_input_bottom_sheet.dart b/lib/presentation/emergency_services/widgets/location_input_bottom_sheet.dart index 559a0a5d..c5301ea0 100644 --- a/lib/presentation/emergency_services/widgets/location_input_bottom_sheet.dart +++ b/lib/presentation/emergency_services/widgets/location_input_bottom_sheet.dart @@ -18,7 +18,6 @@ import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:provider/provider.dart'; import '../../../theme/colors.dart'; -import '../../appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart'; class LocationInputBottomSheet extends StatelessWidget { final Debouncer debouncer = Debouncer(milliseconds: 500); diff --git a/lib/presentation/habib_wallet/widgets/select_hospital_bottom_sheet.dart b/lib/presentation/habib_wallet/widgets/select_hospital_bottom_sheet.dart index b7a16c5e..086e0da5 100644 --- a/lib/presentation/habib_wallet/widgets/select_hospital_bottom_sheet.dart +++ b/lib/presentation/habib_wallet/widgets/select_hospital_bottom_sheet.dart @@ -1,21 +1,10 @@ -import 'package:easy_localization/easy_localization.dart' show tr, StringTranslateExtension; import 'package:flutter/material.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/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; -import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/appointment_via_region_viewmodel.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.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/appointments/widgets/hospital_bottom_sheet/hospital_list_items.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/widgets/hospital_bottom_sheet/type_selection_widget.dart'; import 'package:hmg_patient_app_new/presentation/habib_wallet/widgets/hospital_list_item.dart'; -import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/theme/colors.dart' show AppColors; -import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:provider/provider.dart'; class SelectHospitalBottomSheet extends StatelessWidget { diff --git a/lib/presentation/health_calculators/health_calculator_result.dart b/lib/presentation/health_calculators/health_calculator_result.dart deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/presentation/health_calculators_and_converts/health_calculator_detailed_page.dart b/lib/presentation/health_calculators_and_converts/health_calculator_detailed_page.dart index e0f3a7a2..eb22ab65 100644 --- a/lib/presentation/health_calculators_and_converts/health_calculator_detailed_page.dart +++ b/lib/presentation/health_calculators_and_converts/health_calculator_detailed_page.dart @@ -26,8 +26,10 @@ import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; class HealthCalculatorDetailedPage extends StatefulWidget { HealthCalculatorsTypeEnum calculatorType; + int? clinicID; + int? calculationID; - HealthCalculatorDetailedPage({super.key, required this.calculatorType}); + HealthCalculatorDetailedPage({super.key, required this.calculatorType, this.clinicID, this.calculationID}); @override State createState() => _HealthCalculatorDetailedPageState(); @@ -75,37 +77,90 @@ class _HealthCalculatorDetailedPageState extends State _mmolValue; + // Store the original entered value and which field it was entered in + String? _originalValue; + String _originalUnit = 'mg/dL'; // which field the original value was entered in + bool _isSwapped = false; // toggle state for switch + String _activeUnit = 'mg/dL'; // current source unit String get activeUnit => _activeUnit; - // ================== BLOOD CHOLESTEROL ================== String? _cholMgdlValue; String? _cholMmolValue; + String? _cholOriginalValue; + String _cholOriginalUnit = 'mg/dL'; + bool _cholIsSwapped = false; String _cholActiveUnit = 'mg/dL'; String? get cholMgdlValue => _cholMgdlValue; + String? get cholMmolValue => _cholMmolValue; + String get cholActiveUnit => _cholActiveUnit; // ================== TRIGLYCERIDES ================== String? _triMgdlValue; String? _triMmolValue; + String? _triOriginalValue; + String _triOriginalUnit = 'mg/dL'; + bool _triIsSwapped = false; String _triActiveUnit = 'mg/dL'; String? get triMgdlValue => _triMgdlValue; + String? get triMmolValue => _triMmolValue; - String get triActiveUnit => _triActiveUnit; + String get triActiveUnit => _triActiveUnit; // Generic helpers @@ -726,13 +739,10 @@ class HealthCalcualtorViewModel extends ChangeNotifier { final DateTime firstTrimesterStart = lmp; final DateTime firstTrimesterEnd = lmp.add(const Duration(days: 83)); - final DateTime secondTrimesterStart = - firstTrimesterEnd.add(const Duration(days: 1)); - final DateTime secondTrimesterEnd = - lmp.add(const Duration(days: 195)); + final DateTime secondTrimesterStart = firstTrimesterEnd.add(const Duration(days: 1)); + final DateTime secondTrimesterEnd = lmp.add(const Duration(days: 195)); - final DateTime thirdTrimesterStart = - secondTrimesterEnd.add(const Duration(days: 1)); + final DateTime thirdTrimesterStart = secondTrimesterEnd.add(const Duration(days: 1)); final DateTime thirdTrimesterEnd = dueDate; deliveryResult = { @@ -741,7 +751,7 @@ class HealthCalcualtorViewModel extends ChangeNotifier { // Raw DateTime (useful for logic/UI) 'lmpDateTime': lmp, 'dueDateTime': dueDate, - 'dueDateDay' : _formatDateWithDayName(dueDate), + 'dueDateDay': _formatDateWithDayName(dueDate), // Trimester info 'firstTrimester': { 'start': _formatDate(firstTrimesterStart), @@ -769,7 +779,6 @@ class HealthCalcualtorViewModel extends ChangeNotifier { notifyListeners(); } - // Blood sugar conversions void calculateBloodSugar({required String valueText, required String unit}) { if (valueText.trim().isEmpty) { @@ -838,8 +847,6 @@ class HealthCalcualtorViewModel extends ChangeNotifier { 'dietType': dietType }; - - void onBloodSugarChanged(String value, String fromUnit) { _activeUnit = fromUnit; @@ -855,47 +862,105 @@ class HealthCalcualtorViewModel extends ChangeNotifier { if (fromUnit == 'mg/dL') { _mgdlValue = value; - _mmolValue = (parsed / 18.0182).toStringAsFixed(1); + _mmolValue = (parsed / 18.0182).toStringAsFixed(3); } else { _mmolValue = value; - _mgdlValue = (parsed * 18.0182).toStringAsFixed(0); + _mgdlValue = (parsed * 18.0182).toStringAsFixed(3); } notifyListeners(); } - void switchBloodSugarValues() { - if (_activeUnit == 'mg/dL') { - final mmol = double.tryParse(_mmolValue ?? ''); - if (mmol == null) return; + void onBloodSugarMgdlChanged(String value) { + _mgdlValue = value; + _originalValue = value; + _originalUnit = 'mg/dL'; + _isSwapped = false; + _activeUnit = 'mg/dL'; + + if (value.isEmpty) { + _mmolValue = null; + _originalValue = null; + notifyListeners(); + return; + } - _activeUnit = 'mmol/L'; + final parsed = double.tryParse(value); + if (parsed == null) return; - // mmol stays as source - _mmolValue = mmol.toStringAsFixed(1); - _mgdlValue = (mmol * 18.0182).toStringAsFixed(0); - } else { - final mgdl = double.tryParse(_mgdlValue ?? ''); - if (mgdl == null) return; + // Convert mg/dL to mmol/L + _mmolValue = (parsed / 18.0182).toStringAsFixed(3); + notifyListeners(); + } - _activeUnit = 'mg/dL'; + void onBloodSugarMmolChanged(String value) { + _mmolValue = value; + _originalValue = value; + _originalUnit = 'mmol/L'; + _isSwapped = false; + _activeUnit = 'mmol/L'; - // mg/dL stays as source - _mgdlValue = mgdl.toStringAsFixed(0); - _mmolValue = (mgdl / 18.0182).toStringAsFixed(1); + if (value.isEmpty) { + _mgdlValue = null; + _originalValue = null; + notifyListeners(); + return; } + final parsed = double.tryParse(value); + if (parsed == null) return; + + // Convert mmol/L to mg/dL + _mgdlValue = (parsed * 18.0182).toStringAsFixed(3); notifyListeners(); } + + void switchBloodSugarValues() { + // Toggle between two states using the original entered value + if (_originalValue == null || _originalValue!.isEmpty) return; + + final originalParsed = double.tryParse(_originalValue!); + if (originalParsed == null) return; + + _isSwapped = !_isSwapped; + + if (_originalUnit == 'mg/dL') { + if (_isSwapped) { + // Original was in mg/dL, now treat it as mmol/L + _mmolValue = _originalValue; // Keep original format + _mgdlValue = (originalParsed * 18.0182).toStringAsFixed(3); + } else { + // Back to original: value in mg/dL + _mgdlValue = _originalValue; // Keep original format + _mmolValue = (originalParsed / 18.0182).toStringAsFixed(3); + } + } else { + // Original was in mmol/L + if (_isSwapped) { + // Now treat it as mg/dL + _mgdlValue = _originalValue; // Keep original format + _mmolValue = (originalParsed / 18.0182).toStringAsFixed(3); + } else { + // Back to original: value in mmol/L + _mmolValue = _originalValue; // Keep original format + _mgdlValue = (originalParsed * 18.0182).toStringAsFixed(3); + } + } + + notifyListeners(); + } + // --- NEW: Method to clear the values --- void clearBloodSugar() { _mgdlValue = null; _mmolValue = null; + _originalValue = null; + _originalUnit = 'mg/dL'; + _isSwapped = false; + _activeUnit = 'mg/dL'; notifyListeners(); } - - void onBloodCholesterolChanged(String value, String fromUnit) { _cholActiveUnit = fromUnit; @@ -911,47 +976,104 @@ class HealthCalcualtorViewModel extends ChangeNotifier { if (fromUnit == 'mg/dL') { _cholMgdlValue = value; - _cholMmolValue = (parsed / 38.67).toStringAsFixed(2); + _cholMmolValue = (parsed / 38.67).toStringAsFixed(3); } else { _cholMmolValue = value; - _cholMgdlValue = (parsed * 38.67).toStringAsFixed(0); + _cholMgdlValue = (parsed * 38.67).toStringAsFixed(3); } notifyListeners(); } - void switchBloodCholesterolValues() { - if (_cholActiveUnit == 'mg/dL') { - final mmol = double.tryParse(_cholMmolValue ?? ''); - if (mmol == null) return; + void onCholesterolMgdlChanged(String value) { + _cholMgdlValue = value; + _cholOriginalValue = value; + _cholOriginalUnit = 'mg/dL'; + _cholIsSwapped = false; + _cholActiveUnit = 'mg/dL'; + + if (value.isEmpty) { + _cholMmolValue = null; + _cholOriginalValue = null; + notifyListeners(); + return; + } - _cholActiveUnit = 'mmol/L'; + final parsed = double.tryParse(value); + if (parsed == null) return; - _cholMmolValue = mmol.toStringAsFixed(2); - _cholMgdlValue = (mmol * 38.67).toStringAsFixed(0); - } else { - final mgdl = double.tryParse(_cholMgdlValue ?? ''); - if (mgdl == null) return; + // Convert mg/dL to mmol/L + _cholMmolValue = (parsed / 38.67).toStringAsFixed(3); + notifyListeners(); + } - _cholActiveUnit = 'mg/dL'; + void onCholesterolMmolChanged(String value) { + _cholMmolValue = value; + _cholOriginalValue = value; + _cholOriginalUnit = 'mmol/L'; + _cholIsSwapped = false; + _cholActiveUnit = 'mmol/L'; - _cholMgdlValue = mgdl.toStringAsFixed(0); - _cholMmolValue = (mgdl / 38.67).toStringAsFixed(2); + if (value.isEmpty) { + _cholMgdlValue = null; + _cholOriginalValue = null; + notifyListeners(); + return; } + final parsed = double.tryParse(value); + if (parsed == null) return; + + // Convert mmol/L to mg/dL + _cholMgdlValue = (parsed * 38.67).toStringAsFixed(3); notifyListeners(); } + void switchBloodCholesterolValues() { + // Toggle between two states using the original entered value + if (_cholOriginalValue == null || _cholOriginalValue!.isEmpty) return; + + final originalParsed = double.tryParse(_cholOriginalValue!); + if (originalParsed == null) return; + + _cholIsSwapped = !_cholIsSwapped; + + if (_cholOriginalUnit == 'mg/dL') { + if (_cholIsSwapped) { + // Original was in mg/dL, now treat it as mmol/L + _cholMmolValue = _cholOriginalValue; // Keep original format + _cholMgdlValue = (originalParsed * 38.67).toStringAsFixed(3); + } else { + // Back to original: value in mg/dL + _cholMgdlValue = _cholOriginalValue; // Keep original format + _cholMmolValue = (originalParsed / 38.67).toStringAsFixed(3); + } + } else { + // Original was in mmol/L + if (_cholIsSwapped) { + // Now treat it as mg/dL + _cholMgdlValue = _cholOriginalValue; // Keep original format + _cholMmolValue = (originalParsed / 38.67).toStringAsFixed(3); + } else { + // Back to original: value in mmol/L + _cholMmolValue = _cholOriginalValue; // Keep original format + _cholMgdlValue = (originalParsed * 38.67).toStringAsFixed(3); + } + } + + notifyListeners(); + } void clearBloodCholesterol() { _cholMgdlValue = null; _cholMmolValue = null; + _cholOriginalValue = null; + _cholOriginalUnit = 'mg/dL'; + _cholIsSwapped = false; _cholActiveUnit = 'mg/dL'; notifyListeners(); } - - void onTriglyceridesChanged(String value, String fromUnit) { _triActiveUnit = fromUnit; @@ -967,30 +1089,89 @@ class HealthCalcualtorViewModel extends ChangeNotifier { if (fromUnit == 'mg/dL') { _triMgdlValue = value; - _triMmolValue = (parsed / 88.57).toStringAsFixed(2); + _triMmolValue = (parsed / 88.57).toStringAsFixed(3); } else { _triMmolValue = value; - _triMgdlValue = (parsed * 88.57).toStringAsFixed(0); + _triMgdlValue = (parsed * 88.57).toStringAsFixed(3); } notifyListeners(); } + void onTriglyceridesMgdlChanged(String value) { + _triMgdlValue = value; + _triOriginalValue = value; + _triOriginalUnit = 'mg/dL'; + _triIsSwapped = false; + _triActiveUnit = 'mg/dL'; + + if (value.isEmpty) { + _triMmolValue = null; + _triOriginalValue = null; + notifyListeners(); + return; + } + + final parsed = double.tryParse(value); + if (parsed == null) return; + + // Convert mg/dL to mmol/L + _triMmolValue = (parsed / 88.57).toStringAsFixed(3); + notifyListeners(); + } + + void onTriglyceridesMmolChanged(String value) { + _triMmolValue = value; + _triOriginalValue = value; + _triOriginalUnit = 'mmol/L'; + _triIsSwapped = false; + _triActiveUnit = 'mmol/L'; + + if (value.isEmpty) { + _triMgdlValue = null; + _triOriginalValue = null; + notifyListeners(); + return; + } + + final parsed = double.tryParse(value); + if (parsed == null) return; + + // Convert mmol/L to mg/dL + _triMgdlValue = (parsed * 88.57).toStringAsFixed(3); + notifyListeners(); + } + void switchTriglyceridesValues() { - if (_triActiveUnit == 'mg/dL') { - final mmol = double.tryParse(_triMmolValue ?? ''); - if (mmol == null) return; + // Toggle between two states using the original entered value + if (_triOriginalValue == null || _triOriginalValue!.isEmpty) return; - _triActiveUnit = 'mmol/L'; - _triMmolValue = mmol.toStringAsFixed(2); - _triMgdlValue = (mmol * 88.57).toStringAsFixed(0); - } else { - final mgdl = double.tryParse(_triMgdlValue ?? ''); - if (mgdl == null) return; + final originalParsed = double.tryParse(_triOriginalValue!); + if (originalParsed == null) return; + + _triIsSwapped = !_triIsSwapped; - _triActiveUnit = 'mg/dL'; - _triMgdlValue = mgdl.toStringAsFixed(0); - _triMmolValue = (mgdl / 88.57).toStringAsFixed(2); + if (_triOriginalUnit == 'mg/dL') { + if (_triIsSwapped) { + // Original was in mg/dL, now treat it as mmol/L + _triMmolValue = _triOriginalValue; // Keep original format + _triMgdlValue = (originalParsed * 88.57).toStringAsFixed(3); + } else { + // Back to original: value in mg/dL + _triMgdlValue = _triOriginalValue; // Keep original format + _triMmolValue = (originalParsed / 88.57).toStringAsFixed(3); + } + } else { + // Original was in mmol/L + if (_triIsSwapped) { + // Now treat it as mg/dL + _triMgdlValue = _triOriginalValue; // Keep original format + _triMmolValue = (originalParsed / 88.57).toStringAsFixed(3); + } else { + // Back to original: value in mmol/L + _triMmolValue = _triOriginalValue; // Keep original format + _triMgdlValue = (originalParsed * 88.57).toStringAsFixed(3); + } } notifyListeners(); @@ -999,10 +1180,10 @@ class HealthCalcualtorViewModel extends ChangeNotifier { void clearTriglycerides() { _triMgdlValue = null; _triMmolValue = null; + _triOriginalValue = null; + _triOriginalUnit = 'mg/dL'; + _triIsSwapped = false; _triActiveUnit = 'mg/dL'; notifyListeners(); } - - - } diff --git a/lib/presentation/health_calculators_and_converts/health_calculators_page.dart b/lib/presentation/health_calculators_and_converts/health_calculators_page.dart index 702e04cc..faf97a14 100644 --- a/lib/presentation/health_calculators_and_converts/health_calculators_page.dart +++ b/lib/presentation/health_calculators_and_converts/health_calculators_page.dart @@ -218,6 +218,8 @@ class _HealthCalculatorsPageState extends State { CustomPageRoute( page: HealthCalculatorDetailedPage( calculatorType: type == HealthCalculatorEnum.general ? generalHealthServices[index].type : womenHealthServices[index].type, + clinicID: type == HealthCalculatorEnum.general ? generalHealthServices[index].clinicID : womenHealthServices[index].clinicID, + calculationID: type == HealthCalculatorEnum.general ? generalHealthServices[index].calculationID : womenHealthServices[index].calculationID, ), ), ); @@ -228,17 +230,17 @@ class _HealthCalculatorsPageState extends State { } final List generalHealthServices = [ - HealthComponentModel(title: "BMI\nCalculator".needTranslation, icon: AppAssets.bmi, type: HealthCalculatorsTypeEnum.bmi), - HealthComponentModel(title: "Calories\nCalculator".needTranslation, icon: AppAssets.calories, type: HealthCalculatorsTypeEnum.calories), - HealthComponentModel(title: "BMR\nCalculator".needTranslation, icon: AppAssets.bmr, type: HealthCalculatorsTypeEnum.bmr), - HealthComponentModel(title: "Ideal Body\nWeight".needTranslation, icon: AppAssets.ibw, type: HealthCalculatorsTypeEnum.idealBodyWeight), - HealthComponentModel(title: "Body Fat\nCalculator".needTranslation, icon: AppAssets.ibw, type: HealthCalculatorsTypeEnum.bodyFat), - HealthComponentModel(title: "Carbs\nProtein & Fat".needTranslation, icon: AppAssets.ibw, type: HealthCalculatorsTypeEnum.crabsProteinFat), + HealthComponentModel(title: "BMI\nCalculator".needTranslation, icon: AppAssets.bmi, type: HealthCalculatorsTypeEnum.bmi, clinicID: 108, calculationID: null), + HealthComponentModel(title: "Calories\nCalculator".needTranslation, icon: AppAssets.calories, type: HealthCalculatorsTypeEnum.calories, clinicID: null, calculationID: 2), + HealthComponentModel(title: "BMR\nCalculator".needTranslation, icon: AppAssets.bmr, type: HealthCalculatorsTypeEnum.bmr, clinicID: null, calculationID: 3), + HealthComponentModel(title: "Ideal Body\nWeight".needTranslation, icon: AppAssets.ibw, type: HealthCalculatorsTypeEnum.idealBodyWeight, clinicID: null, calculationID: 4), + HealthComponentModel(title: "Body Fat\nCalculator".needTranslation, icon: AppAssets.ibw, type: HealthCalculatorsTypeEnum.bodyFat, clinicID: null, calculationID: 5), + HealthComponentModel(title: "Carbs\nProtein & Fat".needTranslation, icon: AppAssets.ibw, type: HealthCalculatorsTypeEnum.crabsProteinFat, clinicID: null, calculationID: 11), ]; final List womenHealthServices = [ - HealthComponentModel(title: "Ovulation\nPeriod".needTranslation, icon: AppAssets.locate_me, type: HealthCalculatorsTypeEnum.ovulation), - HealthComponentModel(title: "Delivery\nDue Date".needTranslation, icon: AppAssets.activeCheck, type: HealthCalculatorsTypeEnum.deliveryDueDate), + HealthComponentModel(title: "Ovulation\nPeriod".needTranslation, icon: AppAssets.locate_me, type: HealthCalculatorsTypeEnum.ovulation, clinicID: null, calculationID: 6 ), + HealthComponentModel(title: "Delivery\nDue Date".needTranslation, icon: AppAssets.activeCheck, type: HealthCalculatorsTypeEnum.deliveryDueDate, clinicID: null, calculationID: 6), ]; } @@ -250,6 +252,8 @@ class HealthComponentModel { Color? bgColor; Color? textColor; HealthCalculatorsTypeEnum type; + int? clinicID; + int? calculationID; - HealthComponentModel({required this.title, this.subTitle, required this.icon, this.iconColor, this.bgColor, this.textColor, required this.type}); + HealthComponentModel({required this.title, this.subTitle, required this.icon, this.iconColor, this.bgColor, this.textColor, required this.type, this.clinicID, this.calculationID}); } diff --git a/lib/presentation/health_calculators_and_converts/widgets/bf.dart b/lib/presentation/health_calculators_and_converts/widgets/bf.dart index 3a37036d..3a88eb3f 100644 --- a/lib/presentation/health_calculators_and_converts/widgets/bf.dart +++ b/lib/presentation/health_calculators_and_converts/widgets/bf.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/presentation/health_calculators_and_converts/health_calculator_view_model.dart'; -import 'dart:math'; import 'package:provider/provider.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; diff --git a/lib/presentation/health_calculators_and_converts/widgets/blood_cholesterol.dart b/lib/presentation/health_calculators_and_converts/widgets/blood_cholesterol.dart index 161f318e..e3bc7ff7 100644 --- a/lib/presentation/health_calculators_and_converts/widgets/blood_cholesterol.dart +++ b/lib/presentation/health_calculators_and_converts/widgets/blood_cholesterol.dart @@ -52,14 +52,15 @@ class _BloodCholesterolWidgetState extends State { final mgdlText = provider.cholMgdlValue ?? ''; final mmolText = provider.cholMmolValue ?? ''; - if (_mgdlController.text != mgdlText) { + // Only update if focus is not on this field (to avoid cursor jumping) + if (!_mgdlFocus.hasFocus && _mgdlController.text != mgdlText) { _mgdlController.text = mgdlText; _mgdlController.selection = TextSelection.fromPosition( TextPosition(offset: _mgdlController.text.length), ); } - if (_mmolController.text != mmolText) { + if (!_mmolFocus.hasFocus && _mmolController.text != mmolText) { _mmolController.text = mmolText; _mmolController.selection = TextSelection.fromPosition( TextPosition(offset: _mmolController.text.length), @@ -81,7 +82,7 @@ class _BloodCholesterolWidgetState extends State { focusNode: _mgdlFocus, onChanged: (value) { if (_isProgrammaticChange) return; - provider.onBloodCholesterolChanged(value, 'mg/dL'); + provider.onCholesterolMgdlChanged(value); }, ).paddingOnly(top: 16.h), Row( @@ -96,24 +97,21 @@ class _BloodCholesterolWidgetState extends State { width: 40.h, height: 40.h, ).onPress(() { + // Unfocus both fields before switching + _mgdlFocus.unfocus(); + _mmolFocus.unfocus(); provider.switchBloodCholesterolValues(); - if (provider.cholActiveUnit == 'mg/dL') { - _mgdlFocus.requestFocus(); - } else { - _mmolFocus.requestFocus(); - } }), ], ), _buildInputField( label: "MMOL/L", - hint: "6.7", + hint: "3.1", controller: _mmolController, focusNode: _mmolFocus, onChanged: (value) { if (_isProgrammaticChange) return; - - provider.onBloodCholesterolChanged(value, 'mmol/L'); + provider.onCholesterolMmolChanged(value); }, ).paddingOnly(bottom: 16.h), const Divider(height: 1, color: Color(0xFFEEEEEE)), diff --git a/lib/presentation/health_calculators_and_converts/widgets/blood_sugar.dart b/lib/presentation/health_calculators_and_converts/widgets/blood_sugar.dart index 86b4c1e4..cf7cc61b 100644 --- a/lib/presentation/health_calculators_and_converts/widgets/blood_sugar.dart +++ b/lib/presentation/health_calculators_and_converts/widgets/blood_sugar.dart @@ -51,14 +51,16 @@ class _BloodSugarWidgetState extends State { _isProgrammaticChange = true; final mgdlText = provider.mgdlValue ?? ''; final mmolText = provider.mmolValue ?? ''; - if (_mgdlController.text != mgdlText) { + + // Only update if focus is not on this field (to avoid cursor jumping) + if (!_mgdlFocus.hasFocus && _mgdlController.text != mgdlText) { _mgdlController.text = mgdlText; _mgdlController.selection = TextSelection.fromPosition( TextPosition(offset: _mgdlController.text.length), ); } - if (_mmolController.text != mmolText) { + if (!_mmolFocus.hasFocus && _mmolController.text != mmolText) { _mmolController.text = mmolText; _mmolController.selection = TextSelection.fromPosition( TextPosition(offset: _mmolController.text.length), @@ -84,7 +86,7 @@ class _BloodSugarWidgetState extends State { focusNode: _mgdlFocus, onChanged: (value) { if (_isProgrammaticChange) return; - provider.onBloodSugarChanged(value, 'mg/dL'); + provider.onBloodSugarMgdlChanged(value); }, ).paddingOnly(top: 16.h), Row( @@ -99,12 +101,10 @@ class _BloodSugarWidgetState extends State { width: 40.h, height: 40.h, ).onPress(() { + // Unfocus both fields before switching + _mgdlFocus.unfocus(); + _mmolFocus.unfocus(); provider.switchBloodSugarValues(); - if (provider.activeUnit == 'mg/dL') { - _mgdlFocus.requestFocus(); - } else { - _mmolFocus.requestFocus(); - } }), ], ), @@ -115,8 +115,7 @@ class _BloodSugarWidgetState extends State { focusNode: _mmolFocus, onChanged: (value) { if (_isProgrammaticChange) return; - - provider.onBloodSugarChanged(value, 'mmol/L'); + provider.onBloodSugarMmolChanged(value); }, ).paddingOnly(bottom: 16.h), const Divider(height: 1, color: Color(0xFFEEEEEE)), diff --git a/lib/presentation/health_calculators_and_converts/widgets/bmr.dart b/lib/presentation/health_calculators_and_converts/widgets/bmr.dart index 138fd3ec..5f429ffc 100644 --- a/lib/presentation/health_calculators_and_converts/widgets/bmr.dart +++ b/lib/presentation/health_calculators_and_converts/widgets/bmr.dart @@ -3,7 +3,6 @@ import 'package:provider/provider.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/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'; diff --git a/lib/presentation/health_calculators_and_converts/widgets/calories.dart b/lib/presentation/health_calculators_and_converts/widgets/calories.dart index bfaad3ee..fbe15a6c 100644 --- a/lib/presentation/health_calculators_and_converts/widgets/calories.dart +++ b/lib/presentation/health_calculators_and_converts/widgets/calories.dart @@ -3,7 +3,6 @@ import 'package:provider/provider.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/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'; diff --git a/lib/presentation/health_calculators_and_converts/widgets/health_card.dart b/lib/presentation/health_calculators_and_converts/widgets/health_card.dart index c8603e90..d54d0378 100644 --- a/lib/presentation/health_calculators_and_converts/widgets/health_card.dart +++ b/lib/presentation/health_calculators_and_converts/widgets/health_card.dart @@ -1,7 +1,4 @@ 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'; diff --git a/lib/presentation/health_calculators_and_converts/widgets/triglycerides.dart b/lib/presentation/health_calculators_and_converts/widgets/triglycerides.dart index 17ad1f96..1c8c99ed 100644 --- a/lib/presentation/health_calculators_and_converts/widgets/triglycerides.dart +++ b/lib/presentation/health_calculators_and_converts/widgets/triglycerides.dart @@ -53,14 +53,15 @@ class _TriglyceridesWidgetState extends State { final mgdlText = provider.triMgdlValue ?? ''; final mmolText = provider.triMmolValue ?? ''; - if (_mgdlController.text != mgdlText) { + // Only update if focus is not on this field (to avoid cursor jumping) + if (!_mgdlFocus.hasFocus && _mgdlController.text != mgdlText) { _mgdlController.text = mgdlText; _mgdlController.selection = TextSelection.fromPosition( TextPosition(offset: _mgdlController.text.length), ); } - if (_mmolController.text != mmolText) { + if (!_mmolFocus.hasFocus && _mmolController.text != mmolText) { _mmolController.text = mmolText; _mmolController.selection = TextSelection.fromPosition( TextPosition(offset: _mmolController.text.length), @@ -85,7 +86,7 @@ class _TriglyceridesWidgetState extends State { focusNode: _mgdlFocus, onChanged: (value) { if (_isProgrammaticChange) return; - provider.onTriglyceridesChanged(value, 'mg/dL'); + provider.onTriglyceridesMgdlChanged(value); }, ).paddingOnly(top: 16.h), @@ -101,13 +102,10 @@ class _TriglyceridesWidgetState extends State { width: 40.h, height: 40.h, ).onPress(() { + // Unfocus both fields before switching + _mgdlFocus.unfocus(); + _mmolFocus.unfocus(); provider.switchTriglyceridesValues(); - - if (provider.triActiveUnit == 'mg/dL') { - _mgdlFocus.requestFocus(); - } else { - _mmolFocus.requestFocus(); - } }), ], ), @@ -119,7 +117,7 @@ class _TriglyceridesWidgetState extends State { focusNode: _mmolFocus, onChanged: (value) { if (_isProgrammaticChange) return; - provider.onTriglyceridesChanged(value, 'mmol/L'); + provider.onTriglyceridesMmolChanged(value); }, ).paddingOnly(bottom: 16.h), @@ -170,7 +168,6 @@ class _TriglyceridesWidgetState extends State { child: TextField( controller: controller, focusNode: focusNode, - keyboardType: const TextInputType.numberWithOptions(decimal: true), onChanged: onChanged, @@ -185,6 +182,7 @@ class _TriglyceridesWidgetState extends State { style: TextStyle( fontSize: 32.f, fontWeight: FontWeight.bold, + color: Colors.black87, ), ), ), diff --git a/lib/presentation/hmg_services/services_page.dart b/lib/presentation/hmg_services/services_page.dart index 7ae79165..87a0e0e5 100644 --- a/lib/presentation/hmg_services/services_page.dart +++ b/lib/presentation/hmg_services/services_page.dart @@ -89,48 +89,53 @@ class ServicesPage extends StatelessWidget { route: null, onTap: () async { LoaderBottomSheet.showLoader(loadingText: "Fetching Data..."); await bloodDonationViewModel.getRegionSelectedClinics(onSuccess: (val) async { - await bloodDonationViewModel.getPatientBloodGroupDetails(onSuccess: (val) { + // await bloodDonationViewModel.getPatientBloodGroupDetails(onSuccess: (val) { LoaderBottomSheet.hideLoader(); Navigator.of(GetIt.instance().navigatorKey.currentContext!).push( CustomPageRoute( page: BloodDonationPage(), ), ); - }); + // }, onError: (err) { + // LoaderBottomSheet.hideLoader(); + // }); }, onError: (err) { LoaderBottomSheet.hideLoader(); }); }), HmgServicesComponentModel( - 3, - "Home Health Care".needTranslation, + 11, + "Covid 19 Test".needTranslation, "".needTranslation, - AppAssets.homeBottom, - bgColor: AppColors.primaryRedColor, + AppAssets.covid19icon, + bgColor: AppColors.covid29Color, true, - route: AppRoutes.homeHealthCarePage, - ), + route: AppRoutes.covid19Test, + ) + // HmgServicesComponentModel( - // 12, - // "Latest News".needTranslation, + // 3, + // "Home Health Care".needTranslation, // "".needTranslation, - // AppAssets.news, + // AppAssets.homeBottom, + // bgColor: AppColors.primaryRedColor, // true, - // bgColor: AppColors.bgGreenColor, - // textColor: AppColors.blackColor, - // route: "https://twitter.com/HMG", - // isExternalLink: true, + // route: AppRoutes.homeHealthCarePage, // ), // HmgServicesComponentModel( - // 12, - // "Monthly Reports".needTranslation, + // 11, + // "Virtual Tour".needTranslation, // "".needTranslation, - // AppAssets.report_icon, + // AppAssets.my_address, + // bgColor: AppColors.quickLoginColor, // true, - // bgColor: AppColors.bgGreenColor, - // textColor: AppColors.blackColor, - // route: AppRoutes.monthlyReports, - // ), + // route: null, + // onTap:(){ + // Utils.openWebView( + // url: 'https://hmgwebservices.com/vt_mobile/html/index.html', + // ); + // }, + // ) ]; late final List hmgHealthToolServices = [ diff --git a/lib/presentation/home/data/landing_page_data.dart b/lib/presentation/home/data/landing_page_data.dart index cc3c8816..c6934790 100644 --- a/lib/presentation/home/data/landing_page_data.dart +++ b/lib/presentation/home/data/landing_page_data.dart @@ -1,4 +1,3 @@ -import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/presentation/home/data/service_card_data.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; diff --git a/lib/presentation/home/landing_page.dart b/lib/presentation/home/landing_page.dart index b457ad96..f51c10eb 100644 --- a/lib/presentation/home/landing_page.dart +++ b/lib/presentation/home/landing_page.dart @@ -42,8 +42,6 @@ import 'package:hmg_patient_app_new/presentation/home/widgets/small_service_card import 'package:hmg_patient_app_new/presentation/home/widgets/welcome_widget.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/medical_file_page.dart'; import 'package:hmg_patient_app_new/presentation/profile_settings/profile_settings.dart'; -import 'package:hmg_patient_app_new/presentation/tele_consultation/zoom/call_screen.dart'; -import 'package:hmg_patient_app_new/routes/app_routes.dart'; import 'package:hmg_patient_app_new/presentation/rate_appointment/rate_appointment_doctor.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; @@ -110,17 +108,23 @@ class _LandingPageState extends State { insuranceViewModel.initInsuranceProvider(); emergencyServicesViewModel.checkPatientERAdvanceBalance(); myAppointmentsViewModel.getPatientAppointmentQueueDetails(); + if(!appState.isRatedVisible) { appointmentRatingViewModel.getLastRatingAppointment(onSuccess: (response) { if (appointmentRatingViewModel.appointmentRatedList.isNotEmpty) { appointmentRatingViewModel.getAppointmentDetails(appointmentRatingViewModel.appointmentRatedList.last.appointmentNo!, appointmentRatingViewModel.appointmentRatedList.last.projectID!, onSuccess: ((response) { - appointmentRatingViewModel.setClinicOrDoctor(false); - appointmentRatingViewModel.setTitle("Rate Doctor".needTranslation); - appointmentRatingViewModel.setSubTitle("How was your last visit with doctor?".needTranslation); - openLastRating(); + + appointmentRatingViewModel.setClinicOrDoctor(false); + appointmentRatingViewModel.setTitle("Rate Doctor".needTranslation); + appointmentRatingViewModel.setSubTitle("How was your last visit with doctor?".needTranslation); + openLastRating(); + appState.setRatedVisible(true); + })); + } }); + } } }); super.initState(); @@ -407,15 +411,15 @@ class _LandingPageState extends State { SizedBox(height: 10.h), "Hala ${appState.getAuthenticatedUser()!.firstName}!!!".needTranslation.toText16(isBold: true), SizedBox(height: 8.h), - "Your turn is after ${immediateLiveCareVM.patientLiveCareHistoryList[0].patCount} patients.".toText14(isBold: true), - SizedBox(height: 8.h), - Column( + "Your turn is after ${immediateLiveCareVM.patientLiveCareHistoryList[0].patCount} patients.".needTranslation.toText14(isBold: true), + SizedBox(height: 8.h), + Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Expected waiting time: ".toText12(isBold: true), - SizedBox(height: 8.h), - ValueListenableBuilder( - valueListenable: immediateLiveCareVM.durationNotifier, + "Expected waiting time: ".needTranslation.toText12(isBold: true), + SizedBox(height: 7.h), + ValueListenableBuilder( + valueListenable: immediateLiveCareVM.durationNotifier, builder: (context, duration, child) { return Column( mainAxisAlignment: MainAxisAlignment.center, @@ -425,9 +429,8 @@ class _LandingPageState extends State { ); }, ), - SizedBox(height: 12.h), - ], - ), + ], + ), // CustomButton( // text: "View Details".needTranslation, // onPressed: () async { diff --git a/lib/presentation/home/widgets/habib_wallet_card.dart b/lib/presentation/home/widgets/habib_wallet_card.dart index 6ea45079..b2649f9c 100644 --- a/lib/presentation/home/widgets/habib_wallet_card.dart +++ b/lib/presentation/home/widgets/habib_wallet_card.dart @@ -9,7 +9,6 @@ import 'package:hmg_patient_app_new/presentation/habib_wallet/habib_wallet_page. import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; -import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:provider/provider.dart'; class HabibWalletCard extends StatelessWidget { diff --git a/lib/presentation/home/widgets/large_service_card.dart b/lib/presentation/home/widgets/large_service_card.dart index 0e02a5e9..5274d5b6 100644 --- a/lib/presentation/home/widgets/large_service_card.dart +++ b/lib/presentation/home/widgets/large_service_card.dart @@ -1,7 +1,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; -import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; diff --git a/lib/presentation/home/widgets/small_service_card.dart b/lib/presentation/home/widgets/small_service_card.dart index f54f442a..76ed3f76 100644 --- a/lib/presentation/home/widgets/small_service_card.dart +++ b/lib/presentation/home/widgets/small_service_card.dart @@ -10,7 +10,6 @@ import 'package:hmg_patient_app_new/presentation/lab/lab_orders_page.dart'; import 'package:hmg_patient_app_new/presentation/medical_file/patient_sickleaves_list_page.dart'; import 'package:hmg_patient_app_new/presentation/prescriptions/prescriptions_list_page.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; -import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:provider/provider.dart'; import '../../../core/utils/utils.dart'; diff --git a/lib/presentation/home/widgets/welcome_widget.dart b/lib/presentation/home/widgets/welcome_widget.dart index f710ab21..8ef0697d 100644 --- a/lib/presentation/home/widgets/welcome_widget.dart +++ b/lib/presentation/home/widgets/welcome_widget.dart @@ -1,7 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; -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/theme/colors.dart'; diff --git a/lib/presentation/insurance/insurance_home_page.dart b/lib/presentation/insurance/insurance_home_page.dart index bacf5e98..b005e42d 100644 --- a/lib/presentation/insurance/insurance_home_page.dart +++ b/lib/presentation/insurance/insurance_home_page.dart @@ -15,12 +15,10 @@ import 'package:hmg_patient_app_new/presentation/insurance/widgets/insurance_upd import 'package:hmg_patient_app_new/presentation/insurance/widgets/patient_insurance_card.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.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/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; -import 'package:hmg_patient_app_new/widgets/shimmer/common_shimmer_widget.dart'; import 'package:provider/provider.dart'; import 'widgets/insurance_history.dart'; diff --git a/lib/presentation/insurance/widgets/insurance_approval_card.dart b/lib/presentation/insurance/widgets/insurance_approval_card.dart index bea2e56a..ee31538f 100644 --- a/lib/presentation/insurance/widgets/insurance_approval_card.dart +++ b/lib/presentation/insurance/widgets/insurance_approval_card.dart @@ -8,11 +8,8 @@ import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/insurance/models/resp_models/patient_insurance_approval_response_model.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/utils/appointment_type.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; -import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; class InsuranceApprovalCard extends StatelessWidget { diff --git a/lib/presentation/insurance/widgets/insurance_history.dart b/lib/presentation/insurance/widgets/insurance_history.dart index 3e6ee861..341e2340 100644 --- a/lib/presentation/insurance/widgets/insurance_history.dart +++ b/lib/presentation/insurance/widgets/insurance_history.dart @@ -12,7 +12,6 @@ import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.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/shimmer/common_shimmer_widget.dart'; import 'package:provider/provider.dart'; class InsuranceHistory extends StatelessWidget { diff --git a/lib/presentation/insurance/widgets/insurance_update_details_card.dart b/lib/presentation/insurance/widgets/insurance_update_details_card.dart index 753a36ca..c3bbcd7d 100644 --- a/lib/presentation/insurance/widgets/insurance_update_details_card.dart +++ b/lib/presentation/insurance/widgets/insurance_update_details_card.dart @@ -1,7 +1,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.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/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'; @@ -12,7 +11,6 @@ import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.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/shimmer/common_shimmer_widget.dart'; import 'package:provider/provider.dart'; class PatientInsuranceCardUpdateCard extends StatelessWidget { diff --git a/lib/presentation/lab/alphabeticScroll.dart b/lib/presentation/lab/alphabeticScroll.dart index e610d713..29ded695 100644 --- a/lib/presentation/lab/alphabeticScroll.dart +++ b/lib/presentation/lab/alphabeticScroll.dart @@ -5,7 +5,6 @@ import 'package:flutter_staggered_animations/flutter_staggered_animations.dart' import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; -import 'package:hmg_patient_app_new/core/utils/debouncer.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart'; @@ -121,9 +120,7 @@ class _AlphabetScrollPageState extends State { @override Widget build(BuildContext context) { - return - - SizedBox( + return SizedBox( width: MediaQuery.sizeOf(context).width, child: Row( crossAxisAlignment: CrossAxisAlignment.start, // Add this diff --git a/lib/presentation/lab/lab_order_by_test.dart b/lib/presentation/lab/lab_order_by_test.dart index bd56df67..837f4822 100644 --- a/lib/presentation/lab/lab_order_by_test.dart +++ b/lib/presentation/lab/lab_order_by_test.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; -import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; @@ -12,7 +11,6 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; -import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart'; class LabOrderByTest extends StatelessWidget { final VoidCallback onTap; diff --git a/lib/presentation/lab/lab_orders_page.dart b/lib/presentation/lab/lab_orders_page.dart index ebcd2e28..c131275d 100644 --- a/lib/presentation/lab/lab_orders_page.dart +++ b/lib/presentation/lab/lab_orders_page.dart @@ -1 +1 @@ -import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/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_order_by_test.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/widgets/appbar/collapsing_toolbar.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 '../../widgets/appbar/collapsing_list_view.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 Scaffold( backgroundColor: AppColors.bgScaffoldColor, body: CollapsingToolbar( title: LocaleKeys.labResults.tr(), search: () async { final lavVM = Provider.of(context, listen: false); if (lavVM.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: lavVM.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; lavVM.filterLabReports(value); } } }, child: SingleChildScrollView( padding: EdgeInsets.all(24.h), physics: NeverScrollableScrollPhysics(), child: Consumer( builder: (context, model, child) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ CustomTabBar( activeTextColor: Color(0xffED1C2B), activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), tabs: [ CustomTabBarModel(null, "By Visit".needTranslation), CustomTabBarModel(null, "By Test".needTranslation), // CustomTabBarModel(null, "Completed".needTranslation), ], onTabChange: (index) { activeIndex = index; setState(() {}); }, ), SizedBox(height: 8.h), selectedFilterText!.isNotEmpty ? CustomChipWidget( chipText: selectedFilterText!, chipType: ChipTypeEnum.alert, isSelected: true, ) : SizedBox(), activeIndex == 0 ? ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: model.isLabOrdersLoading ? 5 : model.patientLabOrders.isNotEmpty ? model.patientLabOrders.length : 1, itemBuilder: (context, index) { final isExpanded = expandedIndex == index; return model.isLabOrdersLoading ? LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ) : model.patientLabOrders.isNotEmpty ? AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 500), child: SlideAnimation( verticalOffset: 100.0, child: FadeInAnimation( child: LabResultItemView( onTap: () { model.currentlySelectedPatientOrder = model.patientLabOrders[index]; labProvider.getPatientLabResultByHospital(model.patientLabOrders[index]); labProvider.getPatientSpecialResult(model.patientLabOrders[index]); Navigator.push( context, CustomPageRoute( page: LabResultByClinic(labOrder: model.patientLabOrders[index]), )); }, labOrder: model.patientLabOrders[index], index: index, isExpanded: isExpanded), ), ), ) : Utils.getNoDataWidget(context, noDataText: "You don't have any lab results yet.".needTranslation); }, ) // : ListView.builder( // shrinkWrap: true, // physics: NeverScrollableScrollPhysics(), // padding: EdgeInsets.zero, // itemCount: model.isLabOrdersLoading // ? 5 // : model.uniqueTests.toList().isNotEmpty // ? model.uniqueTests.toList().length // : 1, // itemBuilder: (context, index) { // final isExpanded = expandedIndex == index; // return model.isLabOrdersLoading // ? LabResultItemView( // onTap: () {}, // labOrder: null, // index: index, // isLoading: true, // ) // : model.uniqueTests.toList().isNotEmpty // ? AnimationConfiguration.staggeredList( // position: index, // duration: const Duration(milliseconds: 500), // child: SlideAnimation( // verticalOffset: 100.0, // child: FadeInAnimation( // child: LabOrderByTest( // appState: _appState, // onTap: () { // if (model.uniqueTests.toList()[index].model != null) { // rangeViewModel.flush(); // model.getPatientLabResult(model.uniqueTests.toList()[index].model!, model.uniqueTests.toList()[index].description!, // (_appState.isArabic() ? model.uniqueTests.toList()[index].testDescriptionAr! : model.uniqueTests.toList()[index].testDescriptionEn!)); // } // }, // tests: model.uniqueTests.toList()[index], // index: index, // isExpanded: isExpanded)), // ), // ) // : Utils.getNoDataWidget(context, noDataText: "You don't have any lab results yet.".needTranslation); // }, // ) : (model.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) :AlphabeticScroll( alpahbetsAvailable: model.indexedCharacterForUniqueTest, details: model.uniqueTestsList, labViewModel: model, rangeViewModel: rangeViewModel, appState: _appState, ) ], ); }, ), ), )); } Color getLabOrderStatusColor(num status) { switch (status) { case 44: return AppColors.warningColorYellow; case 45: return AppColors.warningColorYellow; case 16: return AppColors.successColor; case 17: return AppColors.successColor; default: return AppColors.greyColor; } } String getLabOrderStatusText(num status) { switch (status) { case 44: return LocaleKeys.resultsPending.tr(context: context); case 45: return LocaleKeys.resultsPending.tr(context: context); case 16: return LocaleKeys.resultsAvailable.tr(context: context); case 17: return LocaleKeys.resultsAvailable.tr(context: context); default: return ""; } } getLabSuggestions(LabViewModel model) { if (model.patientLabOrders.isEmpty) { return []; } return model.patientLabOrders.map((m) => m.testDetails).toList(); } } \ No newline at end of file +import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/lab/lab_view_model.dart'; import 'package:hmg_patient_app_new/features/lab/models/resp_models/patient_lab_orders_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_item_view.dart'; import 'package:hmg_patient_app_new/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart'; import 'package:hmg_patient_app_new/presentation/lab/search_lab_report.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_toolbar.dart'; import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart'; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/date_range_selector/viewmodel/date_range_view_model.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; import 'alphabeticScroll.dart'; class LabOrdersPage extends StatefulWidget { const LabOrdersPage({super.key}); @override State createState() => _LabOrdersPageState(); } class _LabOrdersPageState extends State { late LabViewModel labProvider; late DateRangeSelectorRangeViewModel rangeViewModel; late AppState _appState; List?> labSuggestions = []; int? expandedIndex; String? selectedFilterText = ''; int activeIndex = 0; @override void initState() { scheduleMicrotask(() { labProvider.initLabProvider(); }); super.initState(); } @override Widget build(BuildContext context) { labProvider = Provider.of(context, listen: false); rangeViewModel = Provider.of(context); _appState = getIt(); return CollapsingToolbar( title: LocaleKeys.labResults.tr(), search: () async { final lavVM = Provider.of(context, listen: false); if (lavVM.isLabOrdersLoading) { return; } else { String? value = await Navigator.of(context).push( CustomPageRoute( page: SearchLabResultsContent(labSuggestionsList: lavVM.labSuggestions), fullScreenDialog: true, direction: AxisDirection.down, ), ); if (value != null) { selectedFilterText = value; lavVM.filterLabReports(value); } } }, child: Consumer( builder: (context, model, child) { return SingleChildScrollView( physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.all(24.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: CustomTabBar( activeTextColor: Color(0xffED1C2B), activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), tabs: [ CustomTabBarModel(null, "By Visit".needTranslation), CustomTabBarModel(null, "By Test".needTranslation), // CustomTabBarModel(null, "Completed".needTranslation), ], onTabChange: (index) { activeIndex = index; setState(() {}); }, ), ), ], ), if (activeIndex == 0) Padding( padding: EdgeInsets.symmetric(vertical: 10.h), child: Row( children: [ CustomButton( text: LocaleKeys.byClinic.tr(context: context), onPressed: () { model.setIsSortByClinic(true); }, backgroundColor: model.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, borderColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), SizedBox(width: 8.h), CustomButton( text: LocaleKeys.byHospital.tr(context: context), onPressed: () { model.setIsSortByClinic(false); }, backgroundColor: model.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, borderColor: model.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, textColor: model.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, fontSize: 12, fontWeight: FontWeight.w500, borderRadius: 10, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, ), ], ), ), SizedBox(height: 8.h), selectedFilterText!.isNotEmpty ? CustomChipWidget( chipText: selectedFilterText!, chipType: ChipTypeEnum.alert, isSelected: true, ) : SizedBox(), activeIndex == 0 ? // By Visit - show grouped view when available model.isLabOrdersLoading ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: 5, itemBuilder: (context, index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, ), ) : (model.patientLabOrdersViewList.isNotEmpty ? ListView.builder( shrinkWrap: true, physics: AlwaysScrollableScrollPhysics(), padding: EdgeInsets.zero, itemCount: model.patientLabOrdersViewList.length, itemBuilder: (context, index) { final group = model.patientLabOrdersViewList[index]; final isExpanded = expandedIndex == index; return AnimationConfiguration.staggeredList( position: index, duration: const Duration(milliseconds: 500), child: SlideAnimation( verticalOffset: 100.0, child: FadeInAnimation( child: AnimatedContainer( duration: Duration(milliseconds: 300), curve: Curves.easeInOut, margin: EdgeInsets.symmetric(vertical: 8.h), decoration: RoundedRectangleBorder() .toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 20.h, hasShadow: true), child: InkWell( onTap: () { setState(() { expandedIndex = isExpanded ? null : index; }); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.all(16.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ CustomButton( text: "${group.length} ${'results'.needTranslation}", onPressed: () {}, backgroundColor: AppColors.greyColor, borderColor: AppColors.greyColor, textColor: AppColors.blackColor, fontSize: 10, fontWeight: FontWeight.w500, borderRadius: 8, padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 30.h, ), Icon(isExpanded ? Icons.expand_less : Icons.expand_more), ], ), SizedBox(height: 8.h), 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.h, vertical: 8.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ...group.map((order) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Image.network( order.doctorImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", width: 24.h, 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), 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: 8.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: "View Results".needTranslation, 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), ], ); }).toList(), ], ), ) : SizedBox.shrink(), ), ], ), ), ), ), )); }, ) : Utils.getNoDataWidget(context, noDataText: "You don't have any lab results yet.".needTranslation)) : // By Test or other tabs keep existing behavior (model.isLabOrdersLoading) ? Column( children: List.generate( 5, (index) => LabResultItemView( onTap: () {}, labOrder: null, index: index, isLoading: true, )), ) : AlphabeticScroll( alpahbetsAvailable: model.indexedCharacterForUniqueTest, details: model.uniqueTestsList, labViewModel: model, rangeViewModel: rangeViewModel, appState: _appState, ) ], ) ); }, ), ); } Color getLabOrderStatusColor(num status) { switch (status) { case 44: return AppColors.warningColorYellow; case 45: return AppColors.warningColorYellow; case 16: return AppColors.successColor; case 17: return AppColors.successColor; default: return AppColors.greyColor; } } String getLabOrderStatusText(num status) { switch (status) { case 44: return LocaleKeys.resultsPending.tr(context: context); case 45: return LocaleKeys.resultsPending.tr(context: context); case 16: return LocaleKeys.resultsAvailable.tr(context: context); case 17: return LocaleKeys.resultsAvailable.tr(context: context); default: return ""; } } getLabSuggestions(LabViewModel model) { if (model.patientLabOrders.isEmpty) { return []; } return model.patientLabOrders.map((m) => m.testDetails).toList(); } } \ No newline at end of file diff --git a/lib/presentation/lab/lab_result_item_view.dart b/lib/presentation/lab/lab_result_item_view.dart index 9269c6d2..db80918b 100644 --- a/lib/presentation/lab/lab_result_item_view.dart +++ b/lib/presentation/lab/lab_result_item_view.dart @@ -9,7 +9,6 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.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/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'; class LabResultItemView extends StatelessWidget { diff --git a/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart b/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart index a603ecbc..ad4a0320 100644 --- a/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart +++ b/lib/presentation/lab/lab_result_via_clinic/LabResultByClinic.dart @@ -1,7 +1,6 @@ import 'package:easy_localization/easy_localization.dart' show tr, StringTranslateExtension; import 'package:flutter/material.dart'; -import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; 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 bc1d6b17..c6841b34 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 @@ -2,19 +2,14 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; -import 'package:hmg_patient_app_new/core/enums.dart'; -import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/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' show LabViewModel; import 'package:hmg_patient_app_new/features/lab/models/resp_models/lab_result.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/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; -import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; -import 'package:hmg_patient_app_new/widgets/chip/custom_chip_widget.dart'; import 'package:provider/provider.dart'; class LabOrderResultItem extends StatelessWidget { diff --git a/lib/presentation/lab/lab_results/lab_result_list_item.dart b/lib/presentation/lab/lab_results/lab_result_list_item.dart index f90df7b8..6ccf7509 100644 --- a/lib/presentation/lab/lab_results/lab_result_list_item.dart +++ b/lib/presentation/lab/lab_results/lab_result_list_item.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart' ; -import 'package:flutter/src/widgets/framework.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; diff --git a/lib/presentation/lab/search_lab_report.dart b/lib/presentation/lab/search_lab_report.dart index f1fd389c..bf27b911 100644 --- a/lib/presentation/lab/search_lab_report.dart +++ b/lib/presentation/lab/search_lab_report.dart @@ -8,7 +8,6 @@ import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; -import 'package:sizer/sizer.dart'; class SearchLabResultsContent extends StatefulWidget { final List labSuggestionsList; diff --git a/lib/presentation/medical_file/eye_measurement_details_page.dart b/lib/presentation/medical_file/eye_measurement_details_page.dart index e69766a5..0662cb15 100644 --- a/lib/presentation/medical_file/eye_measurement_details_page.dart +++ b/lib/presentation/medical_file/eye_measurement_details_page.dart @@ -7,7 +7,6 @@ import 'package:hmg_patient_app_new/features/book_appointments/book_appointments import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/patient_appointment_history_response_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; -import 'package:hmg_patient_app_new/main.dart'; import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_card.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; diff --git a/lib/presentation/medical_file/medical_file_page.dart b/lib/presentation/medical_file/medical_file_page.dart index 1b60e03c..52dc9ff3 100644 --- a/lib/presentation/medical_file/medical_file_page.dart +++ b/lib/presentation/medical_file/medical_file_page.dart @@ -57,7 +57,6 @@ 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/custom_tab_bar.dart'; import 'package:hmg_patient_app_new/widgets/expandable_list_widget.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; diff --git a/lib/presentation/medical_file/patient_sickleaves_list_page.dart b/lib/presentation/medical_file/patient_sickleaves_list_page.dart index 709e4e30..ef5aaeb4 100644 --- a/lib/presentation/medical_file/patient_sickleaves_list_page.dart +++ b/lib/presentation/medical_file/patient_sickleaves_list_page.dart @@ -3,6 +3,10 @@ import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -12,6 +16,9 @@ import 'package:hmg_patient_app_new/features/medical_file/models/patient_sicklea import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; +import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; +import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; +import 'package:open_filex/open_filex.dart'; import 'package:provider/provider.dart'; import 'widgets/patient_sick_leave_card.dart'; @@ -24,6 +31,7 @@ class PatientSickleavesListPage extends StatefulWidget { } class _PatientSickleavesListPageState extends State { + int? expandedIndex; late MedicalFileViewModel medicalFileViewModel; @override @@ -37,53 +45,257 @@ class _PatientSickleavesListPageState extends State { @override Widget build(BuildContext context) { + AppState appState = getIt.get(); medicalFileViewModel = Provider.of(context, listen: false); return Scaffold( backgroundColor: AppColors.bgScaffoldColor, body: CollapsingListView( title: "${LocaleKeys.sick.tr(context: context)} ${LocaleKeys.sickSubtitle.tr(context: context)}", child: SingleChildScrollView( - child: Consumer(builder: (context, medicalFileVM, child) { + child: Consumer(builder: (context, model, child) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox(height: 24.h), - ListView.separated( - padding: EdgeInsets.zero, - scrollDirection: Axis.vertical, - itemCount: medicalFileVM.isPatientSickLeaveListLoading - ? 3 - : medicalFileVM.patientSickLeaveList.isNotEmpty - ? medicalFileVM.patientSickLeaveList.length + SizedBox(height: 16.h), + // Clinic & Hospital Sort + Row( + children: [ + CustomButton( + text: LocaleKeys.byClinic.tr(context: context), + onPressed: () { + model.setIsSickLeavesSortByClinic(true); + }, + backgroundColor: model.isSickLeavesSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderColor: model.isSickLeavesSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), + textColor: model.isSickLeavesSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, + fontSize: 12, + fontWeight: FontWeight.w500, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + SizedBox(width: 8.h), + CustomButton( + text: LocaleKeys.byHospital.tr(context: context), + onPressed: () { + model.setIsSickLeavesSortByClinic(false); + }, + backgroundColor: model.isSickLeavesSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, + borderColor: model.isSickLeavesSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, + textColor: model.isSickLeavesSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, + fontSize: 12, + fontWeight: FontWeight.w500, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + ], + ).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 20.h), + // Expandable list + ListView.builder( + itemCount: model.isPatientSickLeaveListLoading + ? 4 + : model.patientSickLeaveList.isNotEmpty + ? model.patientSickLeavesViewList.length : 1, - shrinkWrap: true, physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: const EdgeInsets.only(left: 0, right: 8), itemBuilder: (context, index) { - return medicalFileVM.isPatientSickLeaveListLoading + final isExpanded = expandedIndex == index; + return model.isPatientSickLeaveListLoading ? PatientSickLeaveCard( patientSickLeavesResponseModel: PatientSickLeavesResponseModel(), isLoading: true, - ).paddingSymmetrical(24.h, 0.0) - : medicalFileVM.patientSickLeaveList.isNotEmpty + ).paddingSymmetrical(0.h, 12.h) + : model.patientSickLeaveList.isNotEmpty ? AnimationConfiguration.staggeredList( position: index, - duration: const Duration(milliseconds: 1000), + duration: const Duration(milliseconds: 500), child: SlideAnimation( verticalOffset: 100.0, child: FadeInAnimation( - child: PatientSickLeaveCard( - patientSickLeavesResponseModel: medicalFileVM.patientSickLeaveList.first, - isLoading: false, - isSickLeaveListPage: true, - ).paddingSymmetrical(24.h, 0.0), + 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: [ + CustomButton( + text: "${model.patientSickLeavesViewList[index].sickLeavesList!.length} ${LocaleKeys.sickSubtitle.tr(context: context)} Available", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ), + Icon(isExpanded ? Icons.expand_less : Icons.expand_more), + ], + ), + SizedBox(height: 8.h), + model.patientSickLeavesViewList[index].filterName!.toText16(isBold: true) + ], + ), + ), + AnimatedSwitcher( + duration: Duration(milliseconds: 500), + switchInCurve: Curves.easeIn, + switchOutCurve: Curves.easeOut, + transitionBuilder: (Widget child, Animation animation) { + return FadeTransition( + opacity: animation, + child: SizeTransition( + sizeFactor: animation, + axisAlignment: 0.0, + child: child, + ), + ); + }, + child: isExpanded + ? Container( + key: ValueKey(index), + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 8.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ...model.patientSickLeavesViewList[index].sickLeavesList!.map((sickLeave) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Image.network( + sickLeave.doctorImageURL!, + width: 24.h, + height: 24.h, + fit: BoxFit.fill, + ).circle(100), + SizedBox(width: 8.h), + Expanded(child: sickLeave.doctorName!.toText14(weight: FontWeight.w500)), + ], + ), + SizedBox(height: 8.h), + Row( + children: [ + CustomButton( + text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(sickLeave.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, + ), + SizedBox(width: 8.h), + CustomButton( + text: model.isSickLeavesSortByClinic ? sickLeave.projectName! : sickLeave.clinicName!, + 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: "${sickLeave.sickLeaveDays} Days", + 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: [ + Expanded( + flex: 6, + child: CustomButton( + text: "Download Report".needTranslation, + onPressed: () async { + LoaderBottomSheet.showLoader(); + await medicalFileViewModel.getPatientSickLeavePDF(sickLeave, appState.getAuthenticatedUser()!).then((val) async { + LoaderBottomSheet.hideLoader(); + if (medicalFileViewModel.patientSickLeavePDFBase64.isNotEmpty) { + String path = await Utils.createFileFromString(medicalFileViewModel.patientSickLeavePDFBase64, "pdf"); + try { + OpenFilex.open(path); + } catch (ex) { + debugPrint("Error opening file: $ex"); + } + } + }); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + icon: AppAssets.download, + iconColor: AppColors.primaryRedColor, + iconSize: 14.h, + ), + ), + ], + ), + SizedBox(height: 12.h), + Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + SizedBox(height: 12.h), + ], + ); + }), + ], + ), + ) + : SizedBox.shrink(), + ), + ], + ), + ), + ), ), ), ) : Utils.getNoDataWidget(context, noDataText: "You don't have any sick leaves yet.".needTranslation); }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 8.h), - ), - SizedBox(height: 60.h), + ).paddingSymmetrical(24.h, 0.h), ], ); }), diff --git a/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart b/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart index a818ae53..6f9b8b51 100644 --- a/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart +++ b/lib/presentation/medical_file/widgets/patient_sick_leave_card.dart @@ -18,7 +18,6 @@ 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'; -import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:open_filex/open_filex.dart'; import 'package:provider/provider.dart'; diff --git a/lib/presentation/medical_report/medical_reports_page.dart b/lib/presentation/medical_report/medical_reports_page.dart index 4047a536..cb784796 100644 --- a/lib/presentation/medical_report/medical_reports_page.dart +++ b/lib/presentation/medical_report/medical_reports_page.dart @@ -2,6 +2,9 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; +import 'package:hmg_patient_app_new/core/app_state.dart'; +import 'package:hmg_patient_app_new/core/dependencies.dart'; +import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; @@ -17,6 +20,7 @@ import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; +import 'package:open_filex/open_filex.dart'; import 'package:provider/provider.dart'; class MedicalReportsPage extends StatefulWidget { @@ -27,10 +31,12 @@ class MedicalReportsPage extends StatefulWidget { } class _MedicalReportsPageState extends State { + int? expandedIndex; late MedicalFileViewModel medicalFileViewModel; @override Widget build(BuildContext context) { + AppState appState = getIt.get(); medicalFileViewModel = Provider.of(context, listen: false); return Scaffold( backgroundColor: AppColors.bgScaffoldColor, @@ -44,16 +50,53 @@ class _MedicalReportsPageState extends State { return Column( children: [ SizedBox(height: 16.h), + // Status filter tabs + // Row( + // children: [ + // CustomButton( + // text: LocaleKeys.byClinic.tr(context: context), + // onPressed: () { + // medicalFileVM.setIsMedicalReportsSortByClinic(true); + // }, + // backgroundColor: medicalFileVM.isMedicalReportsSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, + // borderColor: medicalFileVM.isMedicalReportsSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), + // textColor: medicalFileVM.isMedicalReportsSortByClinic ? 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: () { + // medicalFileVM.setIsMedicalReportsSortByClinic(false); + // }, + // backgroundColor: medicalFileVM.isMedicalReportsSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, + // borderColor: medicalFileVM.isMedicalReportsSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, + // textColor: medicalFileVM.isMedicalReportsSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, + // fontSize: 12, + // fontWeight: FontWeight.w500, + // borderRadius: 10, + // padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + // height: 40.h, + // ), + // ], + // ).paddingSymmetrical(24.h, 0.h), + SizedBox(height: 20.h), Row( children: [ CustomButton( text: "Requested".needTranslation, onPressed: () { + setState(() { + expandedIndex = null; + }); medicalFileViewModel.onMedicalReportTabChange(0); }, backgroundColor: medicalFileVM.selectedMedicalReportsTabIndex == 0 ? AppColors.bgRedLightColor : AppColors.whiteColor, - borderColor: - medicalFileVM.selectedMedicalReportsTabIndex == 0 ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2), + borderColor: medicalFileVM.selectedMedicalReportsTabIndex == 0 ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: medicalFileVM.selectedMedicalReportsTabIndex == 0 ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12, fontWeight: FontWeight.w500, @@ -65,11 +108,13 @@ class _MedicalReportsPageState extends State { CustomButton( text: LocaleKeys.ready.tr(context: context), onPressed: () { + setState(() { + expandedIndex = null; + }); medicalFileViewModel.onMedicalReportTabChange(1); }, backgroundColor: medicalFileVM.selectedMedicalReportsTabIndex == 1 ? AppColors.bgRedLightColor : AppColors.whiteColor, - borderColor: - medicalFileVM.selectedMedicalReportsTabIndex == 1 ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2), + borderColor: medicalFileVM.selectedMedicalReportsTabIndex == 1 ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: medicalFileVM.selectedMedicalReportsTabIndex == 1 ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12, fontWeight: FontWeight.w500, @@ -81,11 +126,13 @@ class _MedicalReportsPageState extends State { CustomButton( text: LocaleKeys.cancelled.tr(context: context), onPressed: () { + setState(() { + expandedIndex = null; + }); medicalFileViewModel.onMedicalReportTabChange(2); }, backgroundColor: medicalFileVM.selectedMedicalReportsTabIndex == 2 ? AppColors.bgRedLightColor : AppColors.whiteColor, - borderColor: - medicalFileVM.selectedMedicalReportsTabIndex == 2 ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2), + borderColor: medicalFileVM.selectedMedicalReportsTabIndex == 2 ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), textColor: medicalFileVM.selectedMedicalReportsTabIndex == 2 ? AppColors.primaryRedColor : AppColors.blackColor, fontSize: 12, fontWeight: FontWeight.w500, @@ -95,34 +142,27 @@ class _MedicalReportsPageState extends State { ), ], ).paddingSymmetrical(24.h, 0.h), - // CustomTabBar( - // activeTextColor: Color(0xffED1C2B), - // activeBackgroundColor: Color(0xffED1C2B).withValues(alpha: .1), - // tabs: [ - // CustomTabBarModel(null, "Requested".needTranslation), - // CustomTabBarModel(null, "Ready".needTranslation), - // CustomTabBarModel(null, "Cancelled".needTranslation), - // ], - // onTabChange: (index) { - // medicalFileViewModel.onMedicalReportTabChange(index); - // }, - // ).paddingSymmetrical(24.h, 0.h), - ListView.separated( - padding: EdgeInsets.only(top: 24.h), - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), + SizedBox(height: 12.h), + // Clinic & Hospital Sort + + // Expandable list + ListView.builder( itemCount: medicalFileViewModel.isPatientMedicalReportsListLoading - ? 3 + ? 4 : medicalFileViewModel.patientMedicalReportList.isNotEmpty - ? medicalFileViewModel.patientMedicalReportList.length + ? medicalFileViewModel.patientMedicalReportsViewList.length : 1, + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: const EdgeInsets.only(left: 0, right: 8), itemBuilder: (context, index) { + final isExpanded = expandedIndex == index; return medicalFileViewModel.isPatientMedicalReportsListLoading ? PatientMedicalReportCard( patientMedicalReportResponseModel: PatientMedicalReportResponseModel(), medicalFileViewModel: medicalFileVM, isLoading: true, - ).paddingSymmetrical(24.h, 0.h) + ).paddingSymmetrical(24.h, 8.h) : medicalFileViewModel.patientMedicalReportList.isNotEmpty ? AnimationConfiguration.staggeredList( position: index, @@ -133,22 +173,185 @@ class _MedicalReportsPageState extends State { child: AnimatedContainer( duration: Duration(milliseconds: 300), curve: Curves.easeInOut, - decoration: RoundedRectangleBorder() - .toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true), - child: PatientMedicalReportCard( - patientMedicalReportResponseModel: medicalFileVM.patientMedicalReportList[index], - medicalFileViewModel: medicalFileVM, - isLoading: false, + 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: [ + CustomButton( + text: "${medicalFileVM.patientMedicalReportsViewList[index].medicalReportsList!.length} Reports Available", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ), + Icon(isExpanded ? Icons.expand_less : Icons.expand_more), + ], + ), + SizedBox(height: 8.h), + medicalFileVM.patientMedicalReportsViewList[index].filterName!.toText16(isBold: true) + ], + ), + ), + AnimatedSwitcher( + duration: Duration(milliseconds: 500), + switchInCurve: Curves.easeIn, + switchOutCurve: Curves.easeOut, + transitionBuilder: (Widget child, Animation animation) { + return FadeTransition( + opacity: animation, + child: SizeTransition( + sizeFactor: animation, + axisAlignment: 0.0, + child: child, + ), + ); + }, + child: isExpanded + ? Container( + key: ValueKey(index), + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 8.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ...medicalFileVM.patientMedicalReportsViewList[index].medicalReportsList!.map((report) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Image.network( + report.doctorImageURL!, + width: 24.h, + height: 24.h, + fit: BoxFit.fill, + ).circle(100), + SizedBox(width: 8.h), + Expanded(child: report.doctorName!.toText14(weight: FontWeight.w500)), + ], + ), + SizedBox(height: 8.h), + Row( + 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, + ), + 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, + ), + ], + ), + SizedBox(height: 8.h), + Row( + children: [ + if (medicalFileVM.selectedMedicalReportsTabIndex == 1) + Expanded( + flex: 6, + child: CustomButton( + text: "Download Report".needTranslation, + onPressed: () async { + LoaderBottomSheet.showLoader(); + await medicalFileViewModel.getPatientMedicalReportPDF(report, appState.getAuthenticatedUser()!).then((val) async { + LoaderBottomSheet.hideLoader(); + if (medicalFileViewModel.patientMedicalReportPDFBase64.isNotEmpty) { + String path = await Utils.createFileFromString(medicalFileViewModel.patientMedicalReportPDFBase64, "pdf"); + try { + OpenFilex.open(path); + } catch (ex) { + debugPrint("Error opening file: $ex"); + } + } + }); + }, + backgroundColor: AppColors.secondaryLightRedColor, + borderColor: AppColors.secondaryLightRedColor, + textColor: AppColors.primaryRedColor, + fontSize: 14, + fontWeight: FontWeight.w500, + borderRadius: 12, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + icon: AppAssets.download, + iconColor: AppColors.primaryRedColor, + iconSize: 14.h, + ), + ), + ], + ), + SizedBox(height: 12.h), + Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + SizedBox(height: 12.h), + ], + ); + }), + ], + ), + ) + : SizedBox.shrink(), + ), + ], + ), ), - ).paddingSymmetrical(24.h, 0.h), + ), ), ), ) : Utils.getNoDataWidget(context, noDataText: "You don't have any medical reports yet.".needTranslation) .paddingSymmetrical(24.h, 24.h); }, - separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h), - ), + ).paddingSymmetrical(24.h, 0.h), SizedBox(height: 24.h), ], ); diff --git a/lib/presentation/medical_report/widgets/patient_medical_report_card.dart b/lib/presentation/medical_report/widgets/patient_medical_report_card.dart index 1762886c..413858d7 100644 --- a/lib/presentation/medical_report/widgets/patient_medical_report_card.dart +++ b/lib/presentation/medical_report/widgets/patient_medical_report_card.dart @@ -1,4 +1,3 @@ -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; @@ -10,7 +9,6 @@ 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/medical_file/medical_file_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/patient_medical_response_model.dart'; -import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; diff --git a/lib/presentation/my_family/my_family.dart b/lib/presentation/my_family/my_family.dart index 781624af..07f1a4f3 100644 --- a/lib/presentation/my_family/my_family.dart +++ b/lib/presentation/my_family/my_family.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -7,10 +6,8 @@ import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/enums.dart'; -import 'package:hmg_patient_app_new/core/utils/validation_utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; -import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.dart'; import 'package:hmg_patient_app_new/features/medical_file/models/family_file_response_model.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; @@ -19,10 +16,7 @@ import 'package:hmg_patient_app_new/services/dialog_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; -import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart'; import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart'; -import 'package:hmg_patient_app_new/widgets/dropdown/country_dropdown_widget.dart'; -import 'package:hmg_patient_app_new/widgets/input_widget.dart'; import 'package:provider/provider.dart'; class FamilyMedicalScreen extends StatefulWidget { diff --git a/lib/presentation/onboarding/splash_animation_screen.dart b/lib/presentation/onboarding/splash_animation_screen.dart index 7acd0785..105922bb 100644 --- a/lib/presentation/onboarding/splash_animation_screen.dart +++ b/lib/presentation/onboarding/splash_animation_screen.dart @@ -1,10 +1,8 @@ -import 'dart:async'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; -import 'package:hmg_patient_app_new/presentation/authentication/login.dart'; import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; diff --git a/lib/presentation/prescriptions/prescription_delivery_orders_list_page.dart b/lib/presentation/prescriptions/prescription_delivery_orders_list_page.dart index 9f2b2a2e..e2ce865d 100644 --- a/lib/presentation/prescriptions/prescription_delivery_orders_list_page.dart +++ b/lib/presentation/prescriptions/prescription_delivery_orders_list_page.dart @@ -2,7 +2,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/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; diff --git a/lib/presentation/prescriptions/prescriptions_list_page.dart b/lib/presentation/prescriptions/prescriptions_list_page.dart index 3d631ce7..2cf2fcce 100644 --- a/lib/presentation/prescriptions/prescriptions_list_page.dart +++ b/lib/presentation/prescriptions/prescriptions_list_page.dart @@ -6,7 +6,6 @@ import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; -import 'package:hmg_patient_app_new/core/location_util.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; @@ -21,10 +20,7 @@ import 'package:hmg_patient_app_new/presentation/prescriptions/prescription_deta 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/loader/bottomsheet_loader.dart'; -import 'package:hmg_patient_app_new/widgets/map/map_utility_screen.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; -import 'package:hmg_patient_app_new/widgets/shimmer/common_shimmer_widget.dart'; -import 'package:hmg_patient_app_new/widgets/transitions/fade_page.dart'; import 'package:provider/provider.dart'; class PrescriptionsListPage extends StatefulWidget { @@ -130,125 +126,125 @@ class _PrescriptionsListPageState extends State { 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, + 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: [ - CustomButton( - text: "${model.patientPrescriptionOrdersViewList[index].prescriptionsList!.length} Prescriptions Available", - onPressed: () {}, - backgroundColor: AppColors.greyColor, - borderColor: AppColors.greyColor, - textColor: AppColors.blackColor, - fontSize: 10, - fontWeight: FontWeight.w500, - borderRadius: 8, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 30.h, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + CustomButton( + text: "${model.patientPrescriptionOrdersViewList[index].prescriptionsList!.length} Prescriptions Available", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ), + Icon(isExpanded ? Icons.expand_less : Icons.expand_more), + ], ), - Icon(isExpanded ? Icons.expand_less : Icons.expand_more), + SizedBox(height: 8.h), + model.patientPrescriptionOrdersViewList[index].filterName!.toText16(isBold: true) ], ), - SizedBox(height: 8.h), - model.patientPrescriptionOrdersViewList[index].filterName!.toText16(isBold: true) - ], - ), - ), - AnimatedSwitcher( - duration: Duration(milliseconds: 500), - switchInCurve: Curves.easeIn, - switchOutCurve: Curves.easeOut, - transitionBuilder: (Widget child, Animation animation) { - return FadeTransition( - opacity: animation, - child: SizeTransition( - sizeFactor: animation, - axisAlignment: 0.0, - child: child, - ), - ); - }, - child: isExpanded - ? Container( - key: ValueKey(index), - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 8.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ...model.patientPrescriptionOrdersViewList[index].prescriptionsList!.map((prescription) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisSize: MainAxisSize.min, - children: [ - Image.network( - prescription.doctorImageURL!, - width: 24.h, - height: 24.h, - fit: BoxFit.fill, - ).circle(100), - SizedBox(width: 8.h), - Expanded(child: prescription.doctorName!.toText14(weight: FontWeight.w500)), - ], - ), - SizedBox(height: 8.h), - Row( + ), + AnimatedSwitcher( + duration: Duration(milliseconds: 500), + switchInCurve: Curves.easeIn, + switchOutCurve: Curves.easeOut, + transitionBuilder: (Widget child, Animation animation) { + return FadeTransition( + opacity: animation, + child: SizeTransition( + sizeFactor: animation, + axisAlignment: 0.0, + child: child, + ), + ); + }, + child: isExpanded + ? Container( + key: ValueKey(index), + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 8.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ...model.patientPrescriptionOrdersViewList[index].prescriptionsList!.map((prescription) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - CustomButton( - text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(prescription.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, + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Image.network( + prescription.doctorImageURL!, + width: 24.h, + height: 24.h, + fit: BoxFit.fill, + ).circle(100), + SizedBox(width: 8.h), + Expanded(child: prescription.doctorName!.toText14(weight: FontWeight.w500)), + ], ), - SizedBox(width: 8.h), - CustomButton( - text: model.isSortByClinic ? prescription.name! : prescription.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(height: 8.h), + Row( + children: [ + CustomButton( + text: DateUtil.formatDateToDate(DateUtil.convertStringToDate(prescription.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, + ), + SizedBox(width: 8.h), + CustomButton( + text: model.isSortByClinic ? prescription.name! : prescription.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(height: 8.h), - Row( - children: [ - Expanded( - flex: 6, - child: CustomButton( - text: prescription.isHomeMedicineDeliverySupported! - ? LocaleKeys.resendOrder.tr(context: context) - : LocaleKeys.prescriptionDeliveryError.tr(context: context), + SizedBox(height: 8.h), + Row( + children: [ + Expanded( + flex: 6, + child: CustomButton( + text: prescription.isHomeMedicineDeliverySupported! + ? LocaleKeys.resendOrder.tr(context: context) + : LocaleKeys.prescriptionDeliveryError.tr(context: context), onPressed: () async { if (prescription.isHomeMedicineDeliverySupported!) { LoaderBottomSheet.showLoader(loadingText: "Fetching prescription details...".needTranslation); @@ -269,62 +265,62 @@ class _PrescriptionsListPageState extends State { padding: EdgeInsets.fromLTRB(10, 0, 10, 0), height: 40.h, icon: AppAssets.prescription_refill_icon, - iconColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35), - iconSize: 14.h, - ), - ), - SizedBox(width: 8.h), - Expanded( - flex: 1, - child: Container( + iconColor: prescription.isHomeMedicineDeliverySupported! ? AppColors.successColor : AppColors.textColor.withOpacity(0.35), + iconSize: 14.h, + ), + ), + SizedBox(width: 8.h), + Expanded( + flex: 1, + child: Container( height: 40.h, width: 40.w, decoration: RoundedRectangleBorder().toSmoothCornerDecoration( - color: AppColors.textColor, + color: AppColors.textColor, borderRadius: 12, ), - child: Padding( + 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, + flipX: appState.isArabic(), + child: Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon_small, + iconColor: AppColors.whiteColor, fit: BoxFit.contain, + ), + ), ), - ), - ), - ).onPress(() { - model.setPrescriptionsDetailsLoading(); - Navigator.of(context).push( - CustomPageRoute( + ).onPress(() { + model.setPrescriptionsDetailsLoading(); + Navigator.of(context).push( + CustomPageRoute( page: PrescriptionDetailPage( prescriptionsResponseModel: prescription, isFromAppointments: false, ), ), ); - }), + }), + ), + ], ), + SizedBox(height: 12.h), + Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), + SizedBox(height: 12.h), ], - ), - SizedBox(height: 12.h), - Divider(color: AppColors.borderOnlyColor.withValues(alpha: 0.05), height: 1.h), - SizedBox(height: 12.h), - ], - ); - }).toList(), - ], - ), - ) - : SizedBox.shrink(), + ); + }).toList(), + ], + ), + ) + : SizedBox.shrink(), + ), + ], ), - ], + ), ), ), ), - ), - ), ) : Utils.getNoDataWidget(context, noDataText: "You don't have any prescriptions yet.".needTranslation); }, diff --git a/lib/presentation/radiology/radiology_orders_page.dart b/lib/presentation/radiology/radiology_orders_page.dart index cb925ef9..c0eb782e 100644 --- a/lib/presentation/radiology/radiology_orders_page.dart +++ b/lib/presentation/radiology/radiology_orders_page.dart @@ -3,13 +3,13 @@ import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; -import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; 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/radiology/models/resp_models/patient_radiology_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/radiology/radiology_result_page.dart'; @@ -22,6 +22,7 @@ import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:provider/provider.dart'; import '../../features/radiology/radiology_view_model.dart'; +import 'package:hmg_patient_app_new/core/app_assets.dart'; class RadiologyOrdersPage extends StatefulWidget { const RadiologyOrdersPage({super.key}); @@ -34,226 +35,401 @@ class _RadiologyOrdersPageState extends State { late RadiologyViewModel radiologyViewModel; String selectedFilterText = ''; int? expandedIndex; + // Scroll controller to ensure expanded group is visible + late ScrollController _scrollController; + final Map _groupKeys = {}; @override void initState() { + _scrollController = ScrollController(); scheduleMicrotask(() { radiologyViewModel.initRadiologyViewModel(); }); super.initState(); } + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { radiologyViewModel = Provider.of(context); return Scaffold( - backgroundColor: AppColors.bgScaffoldColor, - body: CollapsingListView( - title: LocaleKeys.radiology.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: SearchRadiologyContent(radiologySuggestionsList: radiologyViewModel.radiologySuggestions), - fullScreenDialog: true, - direction: AxisDirection.down, - ), - ); - if (value != null) { - selectedFilterText = value; - radiologyViewModel.filterRadiologyReports(value); + backgroundColor: AppColors.bgScaffoldColor, + body: CollapsingListView( + title: LocaleKeys.radiology.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: SearchRadiologyContent(radiologySuggestionsList: radiologyViewModel.radiologySuggestions), + fullScreenDialog: true, + direction: AxisDirection.down, + ), + ); + if (value != null) { + selectedFilterText = value; + radiologyViewModel.filterRadiologyReports(value); + } } - } - }, - child: SingleChildScrollView( - child: Consumer( - builder: (context, model, child) { - return Padding( - padding: EdgeInsets.symmetric(horizontal: 24.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - selectedFilterText!.isNotEmpty - ? AppCustomChipWidget( - padding: EdgeInsets.symmetric(horizontal: 5.h), - labelText: selectedFilterText!, - deleteIcon: 'assets/images/svg/cross_circle.svg', - backgroundColor: AppColors.alertColor, - textColor: AppColors.whiteColor, - deleteIconColor: AppColors.whiteColor, - deleteIconHasColor: true, - onDeleteTap: () { - setState(() { - selectedFilterText = ''; - model.filterRadiologyReports(''); - }); + }, + child: SingleChildScrollView( + controller: _scrollController, + physics: NeverScrollableScrollPhysics(), + 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), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Clinic / Hospital toggle + SizedBox(height: 16.h), + Row( + children: [ + CustomButton( + text: LocaleKeys.byClinic.tr(context: context), + onPressed: () { + model.setIsSortByClinic(true); + }, + backgroundColor: model.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor, + borderColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withValues(alpha: 0.2), + textColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor, + fontSize: 12, + fontWeight: FontWeight.w500, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + SizedBox(width: 8.h), + CustomButton( + text: LocaleKeys.byHospital.tr(context: context), + onPressed: () { + model.setIsSortByClinic(false); }, - // chipType: ChipTypeEnum.alert, - // isSelected: true, - ) - : SizedBox(), - ListView.builder( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemCount: model.isRadiologyOrdersLoading - ? 5 - : model.patientRadiologyOrders.isNotEmpty - ? model.patientRadiologyOrders.length - : 1, - itemBuilder: (context, index) { - final isExpanded = expandedIndex == index; - return model.isRadiologyOrdersLoading - ? LabResultItemView( - onTap: () {}, - labOrder: null, - index: index, - isLoading: true, - ) - : model.patientRadiologyOrders.isNotEmpty - ? 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; + backgroundColor: model.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor, + borderColor: model.isSortByClinic ? AppColors.textColor.withValues(alpha: 0.2) : AppColors.primaryRedColor, + textColor: model.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor, + fontSize: 12, + fontWeight: FontWeight.w500, + borderRadius: 10, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 40.h, + ), + ], + ), + + SizedBox(height: 8.h), + selectedFilterText.isNotEmpty + ? AppCustomChipWidget( + padding: EdgeInsets.symmetric(horizontal: 5.h), + labelText: selectedFilterText, + deleteIcon: 'assets/images/svg/cross_circle.svg', + backgroundColor: AppColors.alertColor, + textColor: AppColors.whiteColor, + deleteIconColor: AppColors.whiteColor, + deleteIconHasColor: true, + onDeleteTap: () { + setState(() { + selectedFilterText = ''; + model.filterRadiologyReports(''); + }); + }, + // chipType: ChipTypeEnum.alert, + // isSelected: true, + ) + : SizedBox(), + + // Grouped view when available + Builder(builder: (ctx) { + if (model.isRadiologyOrdersLoading) { + return ListView.builder( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.zero, + itemCount: 5, + itemBuilder: (context, index) => LabResultItemView( + onTap: () {}, + labOrder: null, + index: index, + isLoading: true, + ), + ); + } + + if (model.patientRadiologyOrdersViewList.isEmpty) { + return Utils.getNoDataWidget(ctx, noDataText: "You don't have any radiology results yet.".needTranslation); + } + + return ListView.builder( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.zero, + itemCount: model.patientRadiologyOrdersViewList.length, + itemBuilder: (context, index) { + final group = model.patientRadiologyOrdersViewList[index]; + final displayName = model.isSortByClinic ? (group.first.clinicDescription ?? 'Unknown') : (group.first.projectName ?? 'Unknown'); + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 400), + child: SlideAnimation( + verticalOffset: 50.0, + child: FadeInAnimation( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Group header container with key so we can scroll to it + GestureDetector( + onTap: () { + setState(() { + expandedIndex = expandedIndex == index ? null : index; + }); + WidgetsBinding.instance.addPostFrameCallback((_) { + final key = _groupKeys.putIfAbsent(index, () => GlobalKey()); + if (key.currentContext != null && expandedIndex == index) { + // Delay scrolling to wait for expansion animation + Future.delayed(Duration(milliseconds: 450), () { + if (key.currentContext != null) { + Scrollable.ensureVisible( + key.currentContext!, + duration: Duration(milliseconds: 350), + curve: Curves.easeInOut, + alignment: 0.0, + ); + } }); - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.all(16.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - AppCustomChipWidget( - labelText: LocaleKeys.resultsAvailable.tr(context: context), - backgroundColor: AppColors.successColor.withOpacity(0.15), - textColor: AppColors.successColor, - ).toShimmer2(isShow: model.isRadiologyOrdersLoading, width: 100), - SizedBox(height: 8.h), - Row( - children: [ - Image.network( - model.isRadiologyOrdersLoading - ? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png" - : model.patientRadiologyOrders[index].doctorImageURL!, - width: 24.h, - height: 24.h, - fit: BoxFit.fill, - ).circle(100).toShimmer2(isShow: model.isRadiologyOrdersLoading), - SizedBox(width: 4.h), - (model.isRadiologyOrdersLoading - ? "Dr John Smith" - : model.patientRadiologyOrders[index].doctorName!) - .toText16(isBold: true) - .toShimmer2(isShow: model.isRadiologyOrdersLoading) - ], + } + }); + }, + child: Container( + key: _groupKeys.putIfAbsent(index, () => GlobalKey()), + margin: EdgeInsets.only(bottom: 8.h), + padding: EdgeInsets.all(12.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8.h), + boxShadow: [ + BoxShadow( + color: AppColors.blackColor.withValues(alpha: 0.03), + blurRadius: 6, + offset: Offset(0, 2), + ) + ], + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + CustomButton( + text: "${group.length} ${'results'.needTranslation}", + onPressed: () {}, + backgroundColor: AppColors.greyColor, + borderColor: AppColors.greyColor, + textColor: AppColors.blackColor, + fontSize: 10, + fontWeight: FontWeight.w500, + borderRadius: 8, + padding: EdgeInsets.fromLTRB(10, 0, 10, 0), + height: 30.h, + ), + Icon(expandedIndex == index ? Icons.expand_less : Icons.expand_more), + ], + ), + SizedBox(height: 8.h), + Text( + displayName, + style: TextStyle(fontSize: 16.h, fontWeight: FontWeight.w600), + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ], + ), + ), + ), + AnimatedSwitcher( + duration: Duration(milliseconds: 400), + child: expandedIndex == index + ? Container( + key: ValueKey(index), + padding: EdgeInsets.only(top: 12.h), + child: Column( + children: group.map((order) { + return Container( + margin: EdgeInsets.only(bottom: 12.h), + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.whiteColor, + borderRadius: 12.h, + hasShadow: true, ), - SizedBox(height: 8.h), - Wrap( - direction: Axis.horizontal, - spacing: 3.h, - runSpacing: 4.h, - children: [ - AppCustomChipWidget( - icon: AppAssets.doctor_calendar_icon, - labelText: model.isRadiologyOrdersLoading - ? "01 Jan 2025" - : DateUtil.formatDateToDate(model.patientRadiologyOrders[index].orderDate!, false), - ).toShimmer2(isShow: model.isRadiologyOrdersLoading), - AppCustomChipWidget( - labelText: model.isRadiologyOrdersLoading - ? "01 Jan 2025" - : model.patientRadiologyOrders[index].clinicDescription!, - ).toShimmer2(isShow: model.isRadiologyOrdersLoading), + child: Padding( + padding: EdgeInsets.all(14.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Image.network( + order.doctorImageURL ?? "https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png", + width: 24.h, + height: 24.h, + fit: BoxFit.cover, + ).circle(100), + SizedBox(width: 8.h), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, - // AppCustomChipWidget(labelText: "").toShimmer2(isShow: model.isRadiologyOrdersLoading, width: 16.h), - // AppCustomChipWidget(labelText: "").toShimmer2(isShow: model.isRadiologyOrdersLoading, width: 16.h), - ], - ), - ], - ), - ), - model.isRadiologyOrdersLoading - ? SizedBox.shrink() - : AnimatedCrossFade( - firstChild: SizedBox.shrink(), - secondChild: Padding( - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 8.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(bottom: 8.h), - child: '● ${model.patientRadiologyOrders[index].description}' - .toText14(weight: FontWeight.w500), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox(), - CustomButton( - icon: AppAssets.view_report_icon, - iconColor: AppColors.primaryRedColor, - iconSize: 16.h, - text: LocaleKeys.viewReport.tr(context: context), - onPressed: () { - Navigator.of(context).push( - CustomPageRoute( - page: RadiologyResultPage( - patientRadiologyResponseModel: model.patientRadiologyOrders[index]), - ), - ); - }, - backgroundColor: AppColors.secondaryLightRedColor, - borderColor: AppColors.secondaryLightRedColor, - textColor: AppColors.primaryRedColor, - fontSize: 14, - fontWeight: FontWeight.bold, - borderRadius: 12, - padding: EdgeInsets.fromLTRB(10, 0, 10, 0), - height: 40.h, + children: [ + (order.doctorName ?? "").toString().toText14(weight: FontWeight.w500), + SizedBox(height: 6.h), + + + ], ), - ], - ), - ], - ), + ), + ], + ), + SizedBox(height: 8.h), + Row(children: [ + CustomButton( + text: order.description!, + 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: 6.h), + + Row( + children: [ + CustomButton( + text: DateUtil.formatDateToDate(order.orderDate ?? order.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, + ), + SizedBox(width: 8.h), + 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: 8.h), + Row( + children: [ + Expanded( + flex: 6, + child: SizedBox(), + ), + SizedBox(width: 8.h), + Expanded( + flex: 1, + child: Container( + height: 40.h, + width: 40.w, + decoration: RoundedRectangleBorder().toSmoothCornerDecoration( + color: AppColors.textColor, + borderRadius: 12, + ), + child: Padding( + padding: EdgeInsets.all(12.h), + child: Transform.flip( + flipX: false, + child: Utils.buildSvgWithAssets( + icon: AppAssets.forward_arrow_icon_small, + iconColor: AppColors.whiteColor, + fit: BoxFit.contain, + ), + ), + ), + ).onPress(() { + model.navigationService.push( + CustomPageRoute( + page: RadiologyResultPage(patientRadiologyResponseModel: order), + ), + ); + }), + ), + ], + ), + ], ), - crossFadeState: isExpanded ? CrossFadeState.showSecond : CrossFadeState.showFirst, - duration: Duration(milliseconds: 300), ), - ], - ), - ), - ), + ); + }).toList(), + ), + ) + : SizedBox.shrink(), ), - ), - ) - : Utils.getNoDataWidget(context, noDataText: "You don't have any radiology results yet.".needTranslation); - }, - ), - ], - ), - ); - }, + ], + ), + ), + ), + ); + }, + ); + }), + ], + ), + ); + }, + ), ), ), - ), - ); + ); } Color getLabOrderStatusColor(num status) { diff --git a/lib/presentation/radiology/radiology_result_page.dart b/lib/presentation/radiology/radiology_result_page.dart index df341647..1fc2d9f1 100644 --- a/lib/presentation/radiology/radiology_result_page.dart +++ b/lib/presentation/radiology/radiology_result_page.dart @@ -10,7 +10,6 @@ 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/radiology/models/resp_models/patient_radiology_response_model.dart'; import 'package:hmg_patient_app_new/features/radiology/radiology_view_model.dart'; -import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; diff --git a/lib/presentation/radiology/search_radiology.dart b/lib/presentation/radiology/search_radiology.dart index 98f5c901..8d63a59a 100644 --- a/lib/presentation/radiology/search_radiology.dart +++ b/lib/presentation/radiology/search_radiology.dart @@ -8,7 +8,6 @@ import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart'; import 'package:hmg_patient_app_new/widgets/input_widget.dart'; -import 'package:sizer/sizer.dart'; class SearchRadiologyContent extends StatefulWidget { final List radiologySuggestionsList; diff --git a/lib/presentation/rate_appointment/rate_appointment_clinic.dart b/lib/presentation/rate_appointment/rate_appointment_clinic.dart index 09132974..5fb1fa3c 100644 --- a/lib/presentation/rate_appointment/rate_appointment_clinic.dart +++ b/lib/presentation/rate_appointment/rate_appointment_clinic.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; diff --git a/lib/presentation/rate_appointment/rate_appointment_doctor.dart b/lib/presentation/rate_appointment/rate_appointment_doctor.dart index 782927df..ac79744e 100644 --- a/lib/presentation/rate_appointment/rate_appointment_doctor.dart +++ b/lib/presentation/rate_appointment/rate_appointment_doctor.dart @@ -1,17 +1,13 @@ -import 'package:flutter/cupertino.dart'; 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/book_appointments/book_appointments_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/appointment_rating_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/my_appointments_view_model.dart'; -import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_card.dart'; import 'package:hmg_patient_app_new/presentation/rate_appointment/rate_appointment_clinic.dart'; import 'package:hmg_patient_app_new/presentation/rate_appointment/widget/doctor_row.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/transitions/fade_page.dart'; import 'package:provider/provider.dart'; class RateAppointmentDoctor extends StatefulWidget { diff --git a/lib/presentation/rate_appointment/widget/doctor_row.dart b/lib/presentation/rate_appointment/widget/doctor_row.dart index f38e15d1..725ac7c3 100644 --- a/lib/presentation/rate_appointment/widget/doctor_row.dart +++ b/lib/presentation/rate_appointment/widget/doctor_row.dart @@ -5,9 +5,7 @@ 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/my_appointments/appointment_rating_view_model.dart'; import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/appointment_details_resp_model.dart'; -import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/rate_appointment_resp_model.dart'; import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; class BuildDoctorRow extends StatelessWidget { diff --git a/lib/presentation/smartwatches/health_dashboard/health_dashboard.dart b/lib/presentation/smartwatches/health_dashboard/health_dashboard.dart index 7ede2017..7c537ba7 100644 --- a/lib/presentation/smartwatches/health_dashboard/health_dashboard.dart +++ b/lib/presentation/smartwatches/health_dashboard/health_dashboard.dart @@ -11,12 +11,9 @@ import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/smartwatches/widgets/health_metric.dart'; import 'package:hmg_patient_app_new/presentation/smartwatches/widgets/health_metric_card.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/custom_tab_bar.dart'; -import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:health/health.dart'; -import 'package:intl/intl.dart'; class HealthDashboard extends StatefulWidget { const HealthDashboard({Key? key}) : super(key: key); diff --git a/lib/presentation/smartwatches/smartwatch_instructions_page.dart b/lib/presentation/smartwatches/smartwatch_instructions_page.dart index 1c3644bb..7f17f5a3 100644 --- a/lib/presentation/smartwatches/smartwatch_instructions_page.dart +++ b/lib/presentation/smartwatches/smartwatch_instructions_page.dart @@ -3,11 +3,9 @@ import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:health/health.dart'; -import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; import 'package:hmg_patient_app_new/core/utils/size_utils.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; -import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/presentation/smartwatches/health_dashboard/health_dashboard.dart'; import 'package:hmg_patient_app_new/services/dialog_service.dart'; diff --git a/lib/presentation/smartwatches/widgets/health_metric.dart b/lib/presentation/smartwatches/widgets/health_metric.dart index 13e65ad9..53759666 100644 --- a/lib/presentation/smartwatches/widgets/health_metric.dart +++ b/lib/presentation/smartwatches/widgets/health_metric.dart @@ -1,10 +1,8 @@ import 'dart:io'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:health/health.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; -import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; class HealthMetricInfo { diff --git a/lib/presentation/tele_consultation/zoom/call_screen.dart b/lib/presentation/tele_consultation/zoom/call_screen.dart index 21ad42f4..59b5ce4c 100644 --- a/lib/presentation/tele_consultation/zoom/call_screen.dart +++ b/lib/presentation/tele_consultation/zoom/call_screen.dart @@ -16,7 +16,6 @@ import 'package:flutter_zoom_videosdk/native/zoom_videosdk_event_listener.dart'; import 'package:flutter_zoom_videosdk/native/zoom_videosdk_live_transcription_message_info.dart'; import 'package:flutter_zoom_videosdk/native/zoom_videosdk_share_action.dart'; import 'package:flutter_zoom_videosdk/native/zoom_videosdk_user.dart'; -import 'package:get_it/get_it.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/cache_consts.dart'; import 'package:hmg_patient_app_new/core/utils/jwt.dart'; @@ -24,7 +23,6 @@ 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/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/presentation/tele_consultation/zoom/video_view.dart'; -import 'package:hmg_patient_app_new/services/cache_service.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart'; import 'package:image_picker/image_picker.dart'; diff --git a/lib/presentation/todo_section/ancillary_procedures_details_page.dart b/lib/presentation/todo_section/ancillary_procedures_details_page.dart index 2755ac06..b7515afb 100644 --- a/lib/presentation/todo_section/ancillary_procedures_details_page.dart +++ b/lib/presentation/todo_section/ancillary_procedures_details_page.dart @@ -22,7 +22,6 @@ 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/routes/custom_page_route.dart'; -import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; class AncillaryOrderDetailsList extends StatefulWidget { diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index db38e78f..dd381809 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -24,6 +24,8 @@ import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_sele import 'package:hmg_patient_app_new/presentation/tele_consultation/zoom/call_screen.dart'; import 'package:hmg_patient_app_new/splashPage.dart'; +import '../presentation/covid19test/covid19_landing_page.dart'; + import '../core/dependencies.dart'; import '../features/monthly_reports/monthly_reports_repo.dart'; import '../features/monthly_reports/monthly_reports_view_model.dart'; @@ -47,7 +49,7 @@ class AppRoutes { static const String bloodDonationPage = '/bloodDonationPage'; static const String smartWatches = '/smartWatches'; static const String huaweiHealthExample = '/huaweiHealthExample'; - + static const String covid19Test = '/covid19Test'; //appointments static const String bookAppointmentPage = '/bookAppointmentPage'; @@ -87,7 +89,7 @@ class AppRoutes { userInfoFlowManager: (context) => UserInfoFlowManager(), smartWatches: (context) => SmartwatchInstructionsPage(), huaweiHealthExample: (context) => HuaweiHealthExample(), - + covid19Test: (context) => Covid19LandingPage(), // // healthCalculatorsPage: (context) => HealthCalculatorsPage(), // monthlyReports: (context) => MonthlyReportsPage() diff --git a/lib/services/analytics/analytics_service.dart b/lib/services/analytics/analytics_service.dart index 3411157a..c8f2e483 100644 --- a/lib/services/analytics/analytics_service.dart +++ b/lib/services/analytics/analytics_service.dart @@ -1,8 +1,5 @@ import 'package:firebase_analytics/firebase_analytics.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:geolocator/geolocator.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/features/authentication/models/resp_models/authenticated_user_resp_model.dart'; import 'package:hmg_patient_app_new/services/analytics/flows/advance_payments.dart'; @@ -15,7 +12,6 @@ import 'package:hmg_patient_app_new/services/analytics/flows/live_care.dart'; import 'package:hmg_patient_app_new/services/analytics/flows/login_registration.dart'; import 'package:hmg_patient_app_new/services/analytics/flows/offers_promotions.dart'; import 'package:hmg_patient_app_new/services/analytics/flows/todo_list.dart'; -import 'package:http/http.dart' as AnalyticEvents; typedef GALogger = Function(String name, {Map parameters}); diff --git a/lib/services/analytics/flows/advance_payments.dart b/lib/services/analytics/flows/advance_payments.dart index 9c8baa14..133e2413 100644 --- a/lib/services/analytics/flows/advance_payments.dart +++ b/lib/services/analytics/flows/advance_payments.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart'; class AdvancePayments{ diff --git a/lib/services/analytics/flows/appointments.dart b/lib/services/analytics/flows/appointments.dart index 57c45e6b..d9991a6d 100644 --- a/lib/services/analytics/flows/appointments.dart +++ b/lib/services/analytics/flows/appointments.dart @@ -1,8 +1,5 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart'; -import 'package:intl/intl.dart'; class Appointment { final GALogger logger; diff --git a/lib/services/analytics/flows/live_care.dart b/lib/services/analytics/flows/live_care.dart index 5e7f3301..c5fac58c 100644 --- a/lib/services/analytics/flows/live_care.dart +++ b/lib/services/analytics/flows/live_care.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart'; class LiveCare{ diff --git a/lib/services/analytics/flows/login_registration.dart b/lib/services/analytics/flows/login_registration.dart index 94883246..611cc47a 100644 --- a/lib/services/analytics/flows/login_registration.dart +++ b/lib/services/analytics/flows/login_registration.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:hmg_patient_app_new/services/analytics/analytics_service.dart'; class LoginRegistration{ diff --git a/lib/splashPage.dart b/lib/splashPage.dart index 2327ab5a..87d81654 100644 --- a/lib/splashPage.dart +++ b/lib/splashPage.dart @@ -1,15 +1,10 @@ import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_callkit_incoming/entities/call_event.dart'; import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_zoom_videosdk/native/zoom_videosdk.dart'; import 'package:get_it/get_it.dart'; -import 'package:hmg_patient_app_new/presentation/lab/lab_orders_page.dart'; import 'package:hmg_patient_app_new/presentation/onboarding/onboarding_screen.dart'; import 'package:hmg_patient_app_new/presentation/onboarding/splash_animation_screen.dart'; import 'package:hmg_patient_app_new/core/api_consts.dart'; @@ -20,7 +15,6 @@ import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart'; // import 'package:hmg_patient_app_new/presentation/authantication/login.dart'; -import 'package:hmg_patient_app_new/presentation/home/landing_page.dart'; import 'package:hmg_patient_app_new/presentation/home/navigation_screen.dart'; import 'package:hmg_patient_app_new/presentation/tele_consultation/zoom/call_screen.dart'; import 'package:hmg_patient_app_new/services/cache_service.dart'; @@ -33,7 +27,6 @@ import 'package:provider/provider.dart'; import 'core/cache_consts.dart'; import 'core/utils/local_notifications.dart'; import 'core/utils/push_notification_handler.dart'; -import 'widgets/routes/custom_page_route.dart'; class SplashPage extends StatefulWidget { diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart index 37815e75..2ce5dc1d 100644 --- a/lib/theme/colors.dart +++ b/lib/theme/colors.dart @@ -96,6 +96,7 @@ static const Color lightRedButtonColor = Color(0x1AED1C2B); static const Color eReferralCardColor = Color(0xFFFF8012); static const Color bloodDonationCardColor = Color(0xFFFF5662); static const Color bookAppointment = Color(0xFF415364); + static const Color covid29Color = Color(0xff2563EB); static const Color lightGreyTextColor = Color(0xFF959595); static const Color labelColorYellow = Color(0xFFFBCB6E); } diff --git a/lib/widgets/appbar/collapsing_list_view.dart b/lib/widgets/appbar/collapsing_list_view.dart index ca40c328..c1ab6d4c 100644 --- a/lib/widgets/appbar/collapsing_list_view.dart +++ b/lib/widgets/appbar/collapsing_list_view.dart @@ -1,4 +1,3 @@ -import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -6,7 +5,6 @@ import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; import 'package:hmg_patient_app_new/core/app_state.dart'; import 'package:hmg_patient_app_new/core/utils/utils.dart'; -import 'package:hmg_patient_app_new/extensions/context_extensions.dart'; import 'package:hmg_patient_app_new/extensions/route_extensions.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; @@ -209,8 +207,8 @@ class ScrollAnimatedTitle extends StatefulWidget implements PreferredSizeWidget } class _ScrollAnimatedTitleState extends State { - static const double _maxFont = 24; - static const double _minFont = 14; + static const double _maxFont = 26; + static const double _minFont = 18; static const double _maxHeight = 80; static const double _minHeight = 56; diff --git a/lib/widgets/common_bottom_sheet.dart b/lib/widgets/common_bottom_sheet.dart index 93125197..6ff5cc59 100644 --- a/lib/widgets/common_bottom_sheet.dart +++ b/lib/widgets/common_bottom_sheet.dart @@ -108,11 +108,11 @@ class ButtonSheetContent extends StatelessWidget { @override Widget build(BuildContext context) { return Column( - crossAxisAlignment: CrossAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - // SizedBox( - // height: 20.h, - // ), + SizedBox( + height: 20.h, + ), // Center( // child: Container( // margin: const EdgeInsets.only(top: 18, bottom: 12), @@ -127,10 +127,9 @@ class ButtonSheetContent extends StatelessWidget { // Close button isCloseButtonVisible && isFullScreen - ? Column(children: [ - SizedBox( - height: 40.h, - ), + ? Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ Padding( padding: EdgeInsets.symmetric( horizontal: 16, @@ -145,7 +144,7 @@ class ButtonSheetContent extends StatelessWidget { isFullScreen ? Column( children: [ - SizedBox(height: 20.h), + // SizedBox(height: 20.h), Padding(padding: EdgeInsets.symmetric(horizontal: 16.h), child: title.toText24(isBold: true)), SizedBox(height: 16.h), ], diff --git a/lib/widgets/date_range_selector/date_range_calender.dart b/lib/widgets/date_range_selector/date_range_calender.dart index 8620ab56..debc0692 100644 --- a/lib/widgets/date_range_selector/date_range_calender.dart +++ b/lib/widgets/date_range_selector/date_range_calender.dart @@ -14,7 +14,6 @@ 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/date_range_selector/viewmodel/date_range_view_model.dart' show DateRangeSelectorRangeViewModel; import 'package:provider/provider.dart'; -import 'package:syncfusion_flutter_calendar/calendar.dart'; import 'package:syncfusion_flutter_datepicker/datepicker.dart'; typedef OnRangeSelected = void Function(DateTime? start, DateTime? end); diff --git a/lib/widgets/date_range_selector/viewmodel/date_range_view_model.dart b/lib/widgets/date_range_selector/viewmodel/date_range_view_model.dart index d2959872..3f67b6a6 100644 --- a/lib/widgets/date_range_selector/viewmodel/date_range_view_model.dart +++ b/lib/widgets/date_range_selector/viewmodel/date_range_view_model.dart @@ -1,4 +1,3 @@ -import 'package:dartz/dartz.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/utils/date_util.dart'; import 'package:hmg_patient_app_new/features/lab/models/Range.dart'; diff --git a/lib/widgets/datepicker_widget.dart b/lib/widgets/datepicker_widget.dart index 47c4de66..6ca9fe1f 100644 --- a/lib/widgets/datepicker_widget.dart +++ b/lib/widgets/datepicker_widget.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; class DatePickerWidget extends StatelessWidget { diff --git a/lib/widgets/family_files/family_file_add_widget.dart b/lib/widgets/family_files/family_file_add_widget.dart index 8e57f913..4840ba77 100644 --- a/lib/widgets/family_files/family_file_add_widget.dart +++ b/lib/widgets/family_files/family_file_add_widget.dart @@ -1,5 +1,4 @@ import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/dependencies.dart'; diff --git a/lib/widgets/loading_dialog.dart b/lib/widgets/loading_dialog.dart index 3c2440a8..dc860b58 100644 --- a/lib/widgets/loading_dialog.dart +++ b/lib/widgets/loading_dialog.dart @@ -3,10 +3,7 @@ import 'package:hmg_patient_app_new/extensions/int_extensions.dart'; import 'package:hmg_patient_app_new/extensions/string_extensions.dart'; import 'package:hmg_patient_app_new/generated/locale_keys.g.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; import 'package:lottie/lottie.dart'; class LoadingDialog extends StatefulWidget { diff --git a/lib/widgets/map/HMSMap.dart b/lib/widgets/map/HMSMap.dart index 7b9c5533..96b2facd 100644 --- a/lib/widgets/map/HMSMap.dart +++ b/lib/widgets/map/HMSMap.dart @@ -1,9 +1,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:hmg_patient_app_new/core/app_assets.dart'; import 'package:hmg_patient_app_new/core/app_export.dart'; -import 'package:hmg_patient_app_new/core/utils/utils.dart'; import 'package:hmg_patient_app_new/extensions/widget_extensions.dart'; import 'package:hmg_patient_app_new/theme/colors.dart'; import 'package:huawei_map/huawei_map.dart' ; diff --git a/lib/widgets/map/gms_map.dart b/lib/widgets/map/gms_map.dart index 6d046921..f4c3ad54 100644 --- a/lib/widgets/map/gms_map.dart +++ b/lib/widgets/map/gms_map.dart @@ -2,9 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; -import 'package:hmg_patient_app_new/core/app_assets.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/widget_extensions.dart'; import 'package:hmg_patient_app_new/theme/colors.dart';