Merge branch 'master' into haroon_dev
						commit
						71a07eed8e
					
				| @ -0,0 +1,5 @@ | |||||||
|  | <svg width="10" height="13" viewBox="0 0 10 13" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||||
|  | <path fill-rule="evenodd" clip-rule="evenodd" d="M5 2.85449C3.79188 2.85449 2.8125 3.83387 2.8125 5.04199C2.8125 6.25011 3.79188 7.22949 5 7.22949C6.20812 7.22949 7.1875 6.25011 7.1875 5.04199C7.1875 3.83387 6.20812 2.85449 5 2.85449ZM3.6875 5.04199C3.6875 4.31712 4.27513 3.72949 5 3.72949C5.72487 3.72949 6.3125 4.31712 6.3125 5.04199C6.3125 5.76687 5.72487 6.35449 5 6.35449C4.27513 6.35449 3.6875 5.76687 3.6875 5.04199Z" fill="#ED1C2B"/> | ||||||
|  | <path fill-rule="evenodd" clip-rule="evenodd" d="M5 0.229492C2.38798 0.229492 0.1875 2.42783 0.1875 5.09268C0.1875 7.8228 2.43772 9.64709 4.31579 10.8329L4.32334 10.8377L4.33107 10.8422C4.5346 10.9593 4.76514 11.0212 5 11.0212C5.23486 11.0212 5.4654 10.9593 5.66893 10.8422L5.67567 10.8383L5.68227 10.8342C7.56769 9.65737 9.8125 7.81358 9.8125 5.09268C9.8125 2.42783 7.61202 0.229492 5 0.229492ZM1.0625 5.09268C1.0625 2.90553 2.87676 1.10449 5 1.10449C7.12324 1.10449 8.9375 2.90553 8.9375 5.09268C8.9375 7.29808 7.10717 8.91207 5.22662 10.0871C5.15694 10.1259 5.079 10.1462 5 10.1462C4.92132 10.1462 4.84369 10.1261 4.77422 10.0876C2.89372 8.89884 1.0625 7.30546 1.0625 5.09268Z" fill="#ED1C2B"/> | ||||||
|  | <path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 10.7295C1.73936 10.7295 1.93382 10.9217 1.93745 11.1602C1.94159 11.1712 1.96197 11.2114 2.04585 11.2775C2.16816 11.3739 2.37227 11.4798 2.66348 11.5769C3.24132 11.7695 4.06744 11.8962 5 11.8962C5.93256 11.8962 6.75868 11.7695 7.33652 11.5769C7.62773 11.4798 7.83184 11.3739 7.95415 11.2775C8.03803 11.2114 8.05841 11.1712 8.06255 11.1602C8.06618 10.9217 8.26064 10.7295 8.5 10.7295C8.74162 10.7295 8.9375 10.9254 8.9375 11.167C8.9375 11.5196 8.72273 11.7859 8.49575 11.9647C8.26385 12.1475 7.95539 12.2929 7.61322 12.407C6.92432 12.6366 6.00044 12.7712 5 12.7712C3.99956 12.7712 3.07568 12.6366 2.38678 12.407C2.04461 12.2929 1.73615 12.1475 1.50425 11.9647C1.27727 11.7859 1.0625 11.5196 1.0625 11.167C1.0625 10.9254 1.25838 10.7295 1.5 10.7295ZM8.06349 11.1572C8.06349 11.1571 8.06349 11.1572 8.06349 11.1572V11.1572Z" fill="#ED1C2B"/> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 2.1 KiB | 
| @ -0,0 +1,5 @@ | |||||||
|  | <svg width="14" height="13" viewBox="0 0 14 13" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||||
|  | <path fill-rule="evenodd" clip-rule="evenodd" d="M1.47635 0.357633C1.3055 0.186779 1.02849 0.186779 0.857633 0.357633C0.686779 0.528487 0.686779 0.805497 0.857633 0.976351L2.46119 2.57991C1.74908 3.50857 1.31283 4.60696 1.31283 5.87371C1.31283 7.46181 1.98475 8.7894 2.92684 9.88512C3.86488 10.9761 5.08602 11.856 6.2293 12.5637L6.23681 12.5684L6.24451 12.5727C6.47506 12.7029 6.73552 12.7712 7.00033 12.7712C7.26514 12.7712 7.52559 12.7029 7.75614 12.5727L7.76285 12.5689L7.76943 12.5649C8.63521 12.0351 9.66148 11.3872 10.4965 10.6152L12.5243 12.643C12.6952 12.8139 12.9722 12.8139 13.143 12.643C13.3139 12.4722 13.3139 12.1952 13.143 12.0243L8.48292 7.3642C8.47847 7.35955 8.47393 7.35501 8.46931 7.35059L5.56673 4.44802C5.5623 4.44339 5.55776 4.43884 5.5531 4.43438L1.47635 0.357633ZM4.72223 4.84095L3.08613 3.20485C2.51802 3.9791 2.18783 4.86436 2.18783 5.87371C2.18783 7.19521 2.74204 8.32806 3.59032 9.31467C4.44051 10.3035 5.57042 11.1262 6.68141 11.8145C6.77877 11.868 6.88851 11.8962 7.00033 11.8962C7.11248 11.8962 7.22255 11.8678 7.32013 11.814C8.18224 11.2864 9.12483 10.6862 9.87729 9.99601L8.07636 8.19508C7.73263 8.32898 7.33404 8.39615 7.00033 8.39615C5.63112 8.39615 4.52116 7.28619 4.52116 5.91698C4.52116 5.58326 4.58833 5.18468 4.72223 4.84095ZM7.36809 7.48681L5.4305 5.54922C5.40846 5.67294 5.39616 5.79917 5.39616 5.91698C5.39616 6.80294 6.11437 7.52115 7.00033 7.52115C7.11814 7.52115 7.24437 7.50884 7.36809 7.48681Z" fill="#2E3039"/> | ||||||
|  | <path d="M7.0004 1.10449C6.13419 1.10449 5.31049 1.34359 4.59613 1.76103C4.38751 1.88294 4.11957 1.81265 3.99766 1.60403C3.87575 1.39541 3.94605 1.12747 4.15466 1.00556C4.99638 0.513701 5.97157 0.229492 7.0004 0.229492C10.0778 0.229492 12.6879 2.77256 12.6879 5.87369C12.6879 6.94853 12.3781 7.91037 11.8817 8.76226C11.76 8.97103 11.4922 9.04165 11.2834 8.92C11.0746 8.79834 11.004 8.53049 11.1257 8.32172C11.5556 7.58384 11.8129 6.77241 11.8129 5.87369C11.8129 3.26657 9.60535 1.10449 7.0004 1.10449Z" fill="#2E3039"/> | ||||||
|  | <path d="M7.00038 4.31283C6.92215 4.31283 6.84547 4.31839 6.77066 4.32909C6.53147 4.36331 6.30984 4.19714 6.27562 3.95795C6.24141 3.71876 6.40758 3.49712 6.64677 3.46291C6.76248 3.44636 6.88056 3.43783 7.00038 3.43783C8.36959 3.43783 9.47955 4.54779 9.47955 5.91699C9.47955 6.03681 9.47102 6.15489 9.45446 6.27061C9.42025 6.5098 9.19861 6.67596 8.95942 6.64175C8.72023 6.60754 8.55407 6.3859 8.58828 6.14671C8.59898 6.07191 8.60455 5.99523 8.60455 5.91699C8.60455 5.03103 7.88634 4.31283 7.00038 4.31283Z" fill="#2E3039"/> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 2.5 KiB | 
| @ -0,0 +1,207 @@ | |||||||
|  | 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/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; | ||||||
|  | 
 | ||||||
|  | class DoctorMapper{ | ||||||
|  |   static Future<RegionList> getMappedDoctor(List<DoctorList> doctorList, | ||||||
|  |       {bool isArabic = false}) async { | ||||||
|  |     RegionList regionList = RegionList(); | ||||||
|  |     final lat = await Utils.getNumFromPrefs(CacheConst.userLat); | ||||||
|  |     final long = await Utils.getNumFromPrefs(CacheConst.userLat); | ||||||
|  | 
 | ||||||
|  |     for (var element in doctorList) { | ||||||
|  |       String? region = element.getRegionName(isArabic); | ||||||
|  |       if (region == null) continue; | ||||||
|  | 
 | ||||||
|  |       var regionDoctorList = regionList.registeredDoctorMap?.putIfAbsent(region, () => PatientDoctorAppointmentListByRegion()); | ||||||
|  | 
 | ||||||
|  |       List<PatientDoctorAppointmentList>? targetList = element.isHMC == true | ||||||
|  |           ? regionDoctorList?.hmcDoctorList | ||||||
|  |           : regionDoctorList?.hmgDoctorList; | ||||||
|  | 
 | ||||||
|  |       var doctorByHospital = targetList | ||||||
|  |               ?.where((clinic) => | ||||||
|  |                   clinic.filterName == | ||||||
|  |                   element.getProjectCompleteNameWithLocale(isArabic: isArabic)) | ||||||
|  |               .toList() ?? | ||||||
|  |           []; | ||||||
|  | 
 | ||||||
|  |       if (doctorByHospital.isNotEmpty) { | ||||||
|  |         doctorByHospital.first.patientDoctorAppointmentList?.add(element); | ||||||
|  |       } else { | ||||||
|  |         var newAppointment = PatientDoctorAppointmentList( | ||||||
|  |           filterName: | ||||||
|  |               element.getProjectCompleteNameWithLocale(isArabic: isArabic), | ||||||
|  |           distanceInKMs: element.projectDistanceInKiloMeters.toString(), | ||||||
|  |           projectTopName: element.projectTopName, | ||||||
|  |           projectBottomName: element.projectBottomName, | ||||||
|  |           patientDoctorAppointment: element, | ||||||
|  |           isHMC: element.isHMC | ||||||
|  |         ); | ||||||
|  |         if(element.projectDistanceInKiloMeters!= null ){ | ||||||
|  |           if(regionDoctorList!.distance>element.projectDistanceInKiloMeters){ | ||||||
|  |             regionDoctorList.distance = element.projectDistanceInKiloMeters; | ||||||
|  |           } | ||||||
|  |           if (element.isHMC == true && | ||||||
|  |               element.projectDistanceInKiloMeters < | ||||||
|  |                   regionDoctorList.hmcDistance) { | ||||||
|  |             regionDoctorList.hmcDistance = element.projectDistanceInKiloMeters; | ||||||
|  |           } else if (element.projectDistanceInKiloMeters < | ||||||
|  |               regionDoctorList.hmgDistance) { | ||||||
|  |             regionDoctorList.hmgDistance = element.projectDistanceInKiloMeters; | ||||||
|  |           } | ||||||
|  |         }else | ||||||
|  |         if (lat != 0&& | ||||||
|  |             long != 0 && element.latitude != null && element.longitude != null) { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |           double distance =  calculateDistance(lat.toDouble(), long.toDouble(), double.parse(element.latitude!), double.parse(element.longitude!)); | ||||||
|  |           if(distance<0){ | ||||||
|  |             distance *= -1; | ||||||
|  |           } | ||||||
|  |           if(regionDoctorList!.distance>distance){ | ||||||
|  |             regionDoctorList.distance = distance; | ||||||
|  |           } | ||||||
|  |           if (element.isHMC == true && | ||||||
|  |               element.projectDistanceInKiloMeters < | ||||||
|  |                   regionDoctorList.hmcDistance) { | ||||||
|  |             regionDoctorList.hmcDistance = element.projectDistanceInKiloMeters; | ||||||
|  |           } else if (element.projectDistanceInKiloMeters < | ||||||
|  |               regionDoctorList.hmgDistance) { | ||||||
|  |             regionDoctorList.hmgDistance = element.projectDistanceInKiloMeters; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         targetList?.add(newAppointment); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |       regionDoctorList?.hmcSize = regionDoctorList.hmcDoctorList?.length ?? 0; | ||||||
|  |       regionDoctorList?.hmgSize = regionDoctorList.hmgDoctorList?.length ?? 0; | ||||||
|  | 
 | ||||||
|  |       regionList.registeredDoctorMap?[region] = regionDoctorList; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return regionList; | ||||||
|  |   } | ||||||
|  |   static double calculateDistance(double lat1, double lon1, double lat2, double lon2) { | ||||||
|  |     var pi = 3.142; | ||||||
|  |     const double R = 6371; | ||||||
|  |     double dLat = (lat2 - lat1) * pi / 180; | ||||||
|  |     double dLon = (lon2 - lon1) * pi / 180; | ||||||
|  |     double a = sin(dLat / 2) * sin(dLat / 2) + | ||||||
|  |         cos(lat1 * pi / 180) * cos(lat2 * pi / 180) * sin(dLon / 2) * sin(dLon / 2); | ||||||
|  |     double c = 2 * atan2(sqrt(a), sqrt(1 - a)); | ||||||
|  |     return R * c; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static Future<RegionList> sortList(bool isGPSEnabled, RegionList unsorted, )  async { | ||||||
|  |     if(isGPSEnabled){ | ||||||
|  |       if(unsorted.registeredDoctorMap == null) return unsorted; | ||||||
|  |       var sortedMap = Map.fromEntries( | ||||||
|  |         unsorted.registeredDoctorMap!.entries.toList() | ||||||
|  |           ..sort((a, b) => a.value!.distance.compareTo(b.value!.distance)), | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |       unsorted.registeredDoctorMap = sortedMap; | ||||||
|  |       return unsorted; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     List<String>? keys = unsorted.registeredDoctorMap?.keys.toList(); | ||||||
|  |     keys?.sort(); | ||||||
|  | 
 | ||||||
|  |     if (keys == null) return unsorted; | ||||||
|  |     Map<String, PatientDoctorAppointmentListByRegion> sortedMap = {}; | ||||||
|  |     for (var key in keys) { | ||||||
|  |       sortedMap[key] = unsorted.registeredDoctorMap![key]!; | ||||||
|  |     } | ||||||
|  |     unsorted.registeredDoctorMap = sortedMap; | ||||||
|  |     return unsorted; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static Future<RegionList> getMappedHospitals( | ||||||
|  |     List<HospitalsModel> hospitalList, { | ||||||
|  |     bool isArabic = false, | ||||||
|  |   }) async { | ||||||
|  |     final regionList = RegionList(); | ||||||
|  |     final lat = await Utils.getNumFromPrefs(CacheConst.userLat); | ||||||
|  |     final long = await Utils.getNumFromPrefs(CacheConst.userLat); | ||||||
|  |     for (final hospital in hospitalList) { | ||||||
|  |       final region = hospital.getRegionName(isArabic); | ||||||
|  |       if (region == null) continue; | ||||||
|  | 
 | ||||||
|  |       final regionData = regionList.registeredDoctorMap?.putIfAbsent( | ||||||
|  |         region, | ||||||
|  |         () => PatientDoctorAppointmentListByRegion(), | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |       List<PatientDoctorAppointmentList>? targetList = hospital.isHMC == true | ||||||
|  |           ? regionData?.hmcDoctorList | ||||||
|  |           : regionData?.hmgDoctorList; | ||||||
|  | 
 | ||||||
|  |       List<PatientDoctorAppointmentList> existingEntry = targetList | ||||||
|  |               ?.where( | ||||||
|  |                 (entry) => entry.filterName == hospital.getName(isArabic), | ||||||
|  |               ) | ||||||
|  |               .toList() ?? | ||||||
|  |           []; | ||||||
|  | 
 | ||||||
|  |       if (existingEntry.isNotEmpty) { | ||||||
|  |         existingEntry.first.hospitalList.add(hospital); | ||||||
|  |       } else { | ||||||
|  |         final newEntry = PatientDoctorAppointmentList( | ||||||
|  |             filterName: hospital.name, | ||||||
|  |             distanceInKMs: hospital.distanceInKilometers?.toString(), | ||||||
|  |             projectTopName: hospital.name, | ||||||
|  |             projectBottomName: hospital.name, | ||||||
|  |             model: hospital, | ||||||
|  |         isHMC: hospital.isHMC); | ||||||
|  | 
 | ||||||
|  |         final distance = hospital.distanceInKilometers; | ||||||
|  | 
 | ||||||
|  |         if (distance != null) { | ||||||
|  |           if (regionData!.distance > distance) { | ||||||
|  |             regionData.distance = distance; | ||||||
|  |           } | ||||||
|  |           if (hospital.isHMC == true && distance < regionData.hmcDistance) { | ||||||
|  |             regionData.hmcDistance = distance; | ||||||
|  |           } else if (distance < regionData.hmgDistance) { | ||||||
|  |             regionData.hmgDistance = distance; | ||||||
|  |           } | ||||||
|  |         } else if ( lat != 0&& | ||||||
|  |             long != 0 && | ||||||
|  |             hospital.latitude != null && | ||||||
|  |             hospital.longitude != null) { | ||||||
|  |           double calculatedDistance = calculateDistance( | ||||||
|  |             lat.toDouble(), | ||||||
|  |             long.toDouble(), | ||||||
|  |             double.parse(hospital.latitude!), | ||||||
|  |             double.parse(hospital.longitude!), | ||||||
|  |           ).abs(); | ||||||
|  | 
 | ||||||
|  |           if (regionData!.distance > calculatedDistance) { | ||||||
|  |             regionData.distance = calculatedDistance; | ||||||
|  |           } | ||||||
|  |           if (hospital.isHMC == true && | ||||||
|  |               calculatedDistance < regionData.hmcDistance) { | ||||||
|  |             regionData.hmcDistance = calculatedDistance; | ||||||
|  |           } else if (calculatedDistance < regionData.hmgDistance) { | ||||||
|  |             regionData.hmgDistance = calculatedDistance; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         targetList?.add(newEntry); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       regionData?.hmcSize = regionData.hmcDoctorList?.length ?? 0; | ||||||
|  |       regionData?.hmgSize = regionData.hmgDoctorList?.length ?? 0; | ||||||
|  |       regionList.registeredDoctorMap?[region] = regionData; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return regionList; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,66 @@ | |||||||
|  | import 'package:flutter/foundation.dart' show ChangeNotifier; | ||||||
|  | 
 | ||||||
|  | enum AppointmentViaRegionState { | ||||||
|  |   REGION_SELECTION, | ||||||
|  |   TYPE_SELECTION, | ||||||
|  |   HOSPITAL_SELECTION, | ||||||
|  |   CLINIC_SELECTION, | ||||||
|  |   DOCTOR_SELECTION | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class AppointmentViaRegionViewmodel extends ChangeNotifier { | ||||||
|  |   String? selectedRegionId; | ||||||
|  |   String? selectedFacilityType; | ||||||
|  |   AppointmentViaRegionState bottomSheetState = | ||||||
|  |       AppointmentViaRegionState.REGION_SELECTION; | ||||||
|  | 
 | ||||||
|  |   void setSelectedRegionId(String? regionId) { | ||||||
|  |     selectedRegionId = regionId; | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   void setFacility(String? facility) { | ||||||
|  |     selectedFacilityType = facility; | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   void setBottomSheetState(AppointmentViaRegionState state) { | ||||||
|  |     bottomSheetState = state; | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   void handleBackPress() { | ||||||
|  |     switch (bottomSheetState) { | ||||||
|  |       case AppointmentViaRegionState.REGION_SELECTION: | ||||||
|  |         // Do nothing or exit the bottom sheet | ||||||
|  |         break; | ||||||
|  |       case AppointmentViaRegionState.TYPE_SELECTION: | ||||||
|  |         setBottomSheetState(AppointmentViaRegionState.REGION_SELECTION); | ||||||
|  |         setSelectedRegionId(null); | ||||||
|  |         break; | ||||||
|  |       case AppointmentViaRegionState.HOSPITAL_SELECTION: | ||||||
|  |         setBottomSheetState(AppointmentViaRegionState.TYPE_SELECTION); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |       // case AppointmentViaRegionState.HOSPITAL_SELECTION: | ||||||
|  |       // case AppointmentViaRegionState.CLINIC_SELECTION: | ||||||
|  |       //   setBottomSheetState(AppointmentViaRegionState.TYPE_SELECTION); | ||||||
|  |       //   setFacility(null); | ||||||
|  |       //   break; | ||||||
|  |       // case AppointmentViaRegionState.DOCTOR_SELECTION: | ||||||
|  |       //   if (selectedFacilityType == 'Hospital') { | ||||||
|  |       //     setBottomSheetState(AppointmentViaRegionState.HOSPITAL_SELECTION); | ||||||
|  |       //   } else if (selectedFacilityType == 'Medical Center') { | ||||||
|  |       //     setBottomSheetState(AppointmentViaRegionState.CLINIC_SELECTION); | ||||||
|  |       //   } | ||||||
|  |       //   break; | ||||||
|  |       default: | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   void flush() { | ||||||
|  |     setSelectedRegionId(null); | ||||||
|  |     setFacility(null); | ||||||
|  |     setBottomSheetState(AppointmentViaRegionState.REGION_SELECTION); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,8 @@ | |||||||
|  | enum FacilitySelection{ | ||||||
|  | ALL('ALL'), | ||||||
|  | HMG('hmg'), | ||||||
|  | HMC('hmc'); | ||||||
|  | 
 | ||||||
|  | final String value; | ||||||
|  | const FacilitySelection(this.value); | ||||||
|  | } | ||||||
| @ -0,0 +1,274 @@ | |||||||
|  | 
 | ||||||
|  | import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart' show HospitalsModel; | ||||||
|  | 
 | ||||||
|  | class DoctorList { | ||||||
|  |   int? clinicID; | ||||||
|  |   dynamic appointmentNo; | ||||||
|  |   String? clinicName; | ||||||
|  |   String? doctorTitle; | ||||||
|  |   num? iD; | ||||||
|  |   String? name; | ||||||
|  |   int? projectID; | ||||||
|  |   String? projectName; | ||||||
|  |   int? actualDoctorRate; | ||||||
|  |   num? clinicRoomNo; | ||||||
|  |   dynamic date; | ||||||
|  |   dynamic appointmentDate; | ||||||
|  |   dynamic dayName; | ||||||
|  |   int? doctorID; | ||||||
|  |   String? doctorImageURL; | ||||||
|  |   dynamic doctorProfile; | ||||||
|  |   dynamic doctorProfileInfo; | ||||||
|  |   int? doctorRate; | ||||||
|  |   num? gender; | ||||||
|  |   String? genderDescription; | ||||||
|  |   bool? isAppointmentAllowed; | ||||||
|  |   bool? isDoctorAllowVedioCall; | ||||||
|  |   bool? isDoctorDummy; | ||||||
|  |   bool? isLiveCare; | ||||||
|  |   bool? isLiveCareClinic; | ||||||
|  |   bool? isDoctorHasPrePostImages; | ||||||
|  |   String? latitude; | ||||||
|  |   String? longitude; | ||||||
|  |   String? nationalityFlagURL; | ||||||
|  |   String? nationalityID; | ||||||
|  |   String? nationalityName; | ||||||
|  |   dynamic nearestFreeSlot; | ||||||
|  |   int? noOfPatientsRate; | ||||||
|  |   num? originalClinicID; | ||||||
|  |   num? personRate; | ||||||
|  |   dynamic projectDistanceInKiloMeters; | ||||||
|  |   String? qR; | ||||||
|  |   dynamic qRString; | ||||||
|  |   num? rateNumber; | ||||||
|  |   dynamic serviceID; | ||||||
|  |   String? setupID; | ||||||
|  |   List<String>? speciality; | ||||||
|  |   List<String>? specialityN; | ||||||
|  |   dynamic workingHours; | ||||||
|  |   dynamic decimalDoctorRate; | ||||||
|  |   String? projectBottomName; | ||||||
|  |   String? projectTopName; | ||||||
|  |   bool? isHMC; | ||||||
|  |   String? region; | ||||||
|  |   String? regionArabic; | ||||||
|  |   String? regionEnglish; | ||||||
|  |   String? regionID; | ||||||
|  | 
 | ||||||
|  |   DoctorList( | ||||||
|  |       {this.clinicID, | ||||||
|  |       this.appointmentNo, | ||||||
|  |       this.clinicName, | ||||||
|  |       this.doctorTitle, | ||||||
|  |       this.iD, | ||||||
|  |       this.name, | ||||||
|  |       this.projectID, | ||||||
|  |       this.projectName, | ||||||
|  |       this.actualDoctorRate, | ||||||
|  |       this.clinicRoomNo, | ||||||
|  |       this.date, | ||||||
|  |       this.appointmentDate, | ||||||
|  |       this.dayName, | ||||||
|  |       this.doctorID, | ||||||
|  |       this.doctorImageURL, | ||||||
|  |       this.doctorProfile, | ||||||
|  |       this.doctorProfileInfo, | ||||||
|  |       this.doctorRate, | ||||||
|  |       this.gender, | ||||||
|  |       this.genderDescription, | ||||||
|  |       this.isAppointmentAllowed, | ||||||
|  |       this.isDoctorAllowVedioCall, | ||||||
|  |       this.isDoctorDummy, | ||||||
|  |       this.isLiveCare, | ||||||
|  |       this.isLiveCareClinic, | ||||||
|  |       this.isDoctorHasPrePostImages, | ||||||
|  |       this.latitude, | ||||||
|  |       this.longitude, | ||||||
|  |       this.nationalityFlagURL, | ||||||
|  |       this.nationalityID, | ||||||
|  |       this.nationalityName, | ||||||
|  |       this.nearestFreeSlot, | ||||||
|  |       this.noOfPatientsRate, | ||||||
|  |       this.originalClinicID, | ||||||
|  |       this.personRate, | ||||||
|  |       this.projectDistanceInKiloMeters, | ||||||
|  |       this.qR, | ||||||
|  |       this.qRString, | ||||||
|  |       this.rateNumber, | ||||||
|  |       this.serviceID, | ||||||
|  |       this.setupID, | ||||||
|  |       this.speciality, | ||||||
|  |       this.specialityN, | ||||||
|  |       this.workingHours, | ||||||
|  |       this.decimalDoctorRate, | ||||||
|  |       this.projectBottomName, | ||||||
|  |       this.projectTopName, | ||||||
|  |       this.isHMC, | ||||||
|  |       this.region, | ||||||
|  |     this.regionArabic, | ||||||
|  |     this.regionEnglish, | ||||||
|  |     this.regionID, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |   DoctorList.fromJson( | ||||||
|  |     Map<String, dynamic> json, | ||||||
|  |   ) { | ||||||
|  |     clinicID = json['ClinicID']; | ||||||
|  |     appointmentNo = json['AppointmentNo']; | ||||||
|  |     clinicName = json['ClinicName']; | ||||||
|  |     doctorTitle = json['DoctorTitle']; | ||||||
|  |     iD = json['ID']; | ||||||
|  |     name = json['DoctorName'] ?? json['Name']; | ||||||
|  |     projectID = json['ProjectID']; | ||||||
|  |     projectName = json['ProjectName']; | ||||||
|  |     actualDoctorRate = json['ActualDoctorRate']; | ||||||
|  |     clinicRoomNo = json['ClinicRoomNo']; | ||||||
|  |     date = json['Date']; | ||||||
|  |     appointmentDate = json['AppointmentDate']; | ||||||
|  |     dayName = json['DayName']; | ||||||
|  |     doctorID = json['DoctorID']; | ||||||
|  |     doctorImageURL = json['DoctorImageURL']; | ||||||
|  |     doctorProfile = json['DoctorProfile']; | ||||||
|  |     doctorProfileInfo = json['DoctorProfileInfo']; | ||||||
|  |     doctorRate = json['DoctorRate']; | ||||||
|  |     gender = json['Gender']; | ||||||
|  |     genderDescription = json['GenderDescription']; | ||||||
|  |     isAppointmentAllowed = json['IsAppointmentAllowed']; | ||||||
|  |     isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; | ||||||
|  |     isDoctorDummy = json['IsDoctorDummy']; | ||||||
|  |     isLiveCare = json['IsLiveCare']; | ||||||
|  |     isLiveCareClinic = json['IsLiveCareClinic']; | ||||||
|  |     isDoctorHasPrePostImages = json['IsDoctorHasPrePostImages']; | ||||||
|  |     latitude = json['Latitude']; | ||||||
|  |     longitude = json['Longitude']; | ||||||
|  |     nationalityFlagURL = json['NationalityFlagURL']; | ||||||
|  |     nationalityID = json['NationalityID']; | ||||||
|  |     nationalityName = json['NationalityName']; | ||||||
|  |     nearestFreeSlot = json['NearestFreeSlot']; | ||||||
|  |     noOfPatientsRate = json['NoOfPatientsRate']; | ||||||
|  |     originalClinicID = json['OriginalClinicID']; | ||||||
|  |     personRate = json['PersonRate']; | ||||||
|  |     projectDistanceInKiloMeters = json['ProjectDistanceInKiloMeters']; | ||||||
|  |     qR = json['QR']; | ||||||
|  |     qRString = json['QRString']; | ||||||
|  |     rateNumber = json['RateNumber']; | ||||||
|  |     serviceID = json['ServiceID']; | ||||||
|  |     setupID = json['SetupID']; | ||||||
|  |     if (json.containsKey('Speciality') && json['Speciality'] != null) speciality = json['Speciality'].cast<String>(); | ||||||
|  |     if (json.containsKey('SpecialityN') && json['SpecialityN'] != null) specialityN = json['SpecialityN'].cast<String>(); | ||||||
|  |     workingHours = json['WorkingHours']; | ||||||
|  |     decimalDoctorRate = json['DecimalDoctorRate']; | ||||||
|  |     projectBottomName = json['ProjectNameBottom']; | ||||||
|  |     projectTopName = json['ProjectNameTop']; | ||||||
|  |     this.isHMC = json["IsHMC"]; | ||||||
|  |     this.regionArabic = json['RegionNameN']; | ||||||
|  |     this.regionEnglish = json['RegionName']; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   String? getRegionName(bool isArabic) { | ||||||
|  |     if (isArabic) { | ||||||
|  |       return regionArabic; | ||||||
|  |     } | ||||||
|  |     return regionEnglish; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Map<String, dynamic> toJson() { | ||||||
|  |     final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||||
|  |     data['ClinicID'] = this.clinicID; | ||||||
|  |     data['AppointmentNo'] = this.appointmentNo; | ||||||
|  |     data['ClinicName'] = this.clinicName; | ||||||
|  |     data['DoctorTitle'] = this.doctorTitle; | ||||||
|  |     data['ID'] = this.iD; | ||||||
|  |     data['Name'] = this.name; | ||||||
|  |     data['ProjectID'] = this.projectID; | ||||||
|  |     data['ProjectName'] = this.projectName; | ||||||
|  |     data['ActualDoctorRate'] = this.actualDoctorRate; | ||||||
|  |     data['ClinicRoomNo'] = this.clinicRoomNo; | ||||||
|  |     data['Date'] = this.date; | ||||||
|  |     data['DayName'] = this.dayName; | ||||||
|  |     data['DoctorID'] = this.doctorID; | ||||||
|  |     data['DoctorImageURL'] = this.doctorImageURL; | ||||||
|  |     data['DoctorProfile'] = this.doctorProfile; | ||||||
|  |     data['DoctorProfileInfo'] = this.doctorProfileInfo; | ||||||
|  |     data['DoctorRate'] = this.doctorRate; | ||||||
|  |     data['Gender'] = this.gender; | ||||||
|  |     data['GenderDescription'] = this.genderDescription; | ||||||
|  |     data['IsAppointmentAllowed'] = this.isAppointmentAllowed; | ||||||
|  |     data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; | ||||||
|  |     data['IsDoctorDummy'] = this.isDoctorDummy; | ||||||
|  |     data['IsLiveCare'] = this.isLiveCare; | ||||||
|  |     data['IsLiveCareClinic'] = this.isLiveCareClinic; | ||||||
|  |     data['IsDoctorHasPrePostImages'] = this.isDoctorHasPrePostImages; | ||||||
|  |     data['Latitude'] = this.latitude; | ||||||
|  |     data['Longitude'] = this.longitude; | ||||||
|  |     data['NationalityFlagURL'] = this.nationalityFlagURL; | ||||||
|  |     data['NationalityID'] = this.nationalityID; | ||||||
|  |     data['NationalityName'] = this.nationalityName; | ||||||
|  |     data['NearestFreeSlot'] = this.nearestFreeSlot; | ||||||
|  |     data['NoOfPatientsRate'] = this.noOfPatientsRate; | ||||||
|  |     data['OriginalClinicID'] = this.originalClinicID; | ||||||
|  |     data['PersonRate'] = this.personRate; | ||||||
|  |     data['ProjectDistanceInKiloMeters'] = this.projectDistanceInKiloMeters; | ||||||
|  |     data['QR'] = this.qR; | ||||||
|  |     data['QRString'] = this.qRString; | ||||||
|  |     data['RateNumber'] = this.rateNumber; | ||||||
|  |     data['ServiceID'] = this.serviceID; | ||||||
|  |     data['SetupID'] = this.setupID; | ||||||
|  |     data['Speciality'] = this.speciality; | ||||||
|  |     data['SpecialityN'] = this.specialityN; | ||||||
|  |     data['WorkingHours'] = this.workingHours; | ||||||
|  |     data['DecimalDoctorRate'] = this.decimalDoctorRate; | ||||||
|  |     return data; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   String getProjectCompleteName(){ | ||||||
|  |     return "${this.projectTopName} ${this.projectBottomName}"; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   String getProjectCompleteNameWithLocale({bool isArabic = false}) { | ||||||
|  |     if (isArabic) { | ||||||
|  |       return "${this.projectBottomName} ${this.projectTopName}"; | ||||||
|  |     } | ||||||
|  |     return "${this.projectTopName} ${this.projectBottomName}"; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class PatientDoctorAppointmentList { | ||||||
|  |   String? filterName = ""; | ||||||
|  |   String? distanceInKMs = ""; | ||||||
|  |   List<DoctorList>? patientDoctorAppointmentList = []; | ||||||
|  |   String? projectTopName = ""; | ||||||
|  |   String? projectBottomName = ""; | ||||||
|  |   bool? isHMC; | ||||||
|  |   List<HospitalsModel> hospitalList = []; | ||||||
|  | 
 | ||||||
|  |   PatientDoctorAppointmentList( | ||||||
|  |       {this.filterName, | ||||||
|  |       this.distanceInKMs, | ||||||
|  |       this.projectTopName, | ||||||
|  |       this.projectBottomName, | ||||||
|  |       DoctorList? patientDoctorAppointment, | ||||||
|  |       HospitalsModel? model, | ||||||
|  |       this.isHMC = false}) { | ||||||
|  |     if (model != null) { | ||||||
|  |       hospitalList.add(model); | ||||||
|  |     } | ||||||
|  |     if (patientDoctorAppointment != null) { | ||||||
|  |       patientDoctorAppointmentList!.add(patientDoctorAppointment!); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class PatientDoctorAppointmentListByRegion { | ||||||
|  |   List<PatientDoctorAppointmentList>? hmgDoctorList = []; | ||||||
|  |   List<PatientDoctorAppointmentList>? hmcDoctorList = []; | ||||||
|  |   int hmcSize = 0; | ||||||
|  |   int hmgSize = 0; | ||||||
|  |   num distance = double.infinity; | ||||||
|  |   num hmgDistance = double.infinity; | ||||||
|  |   num hmcDistance = double.infinity; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class RegionList { | ||||||
|  |   Map<String, PatientDoctorAppointmentListByRegion?>? registeredDoctorMap = {}; | ||||||
|  | } | ||||||
| @ -0,0 +1,104 @@ | |||||||
|  | class HospitalsModel { | ||||||
|  |   String? desciption; | ||||||
|  |   dynamic desciptionN; | ||||||
|  |   dynamic iD; | ||||||
|  |   String? legalName; | ||||||
|  |   String? legalNameN; | ||||||
|  |   String? name; | ||||||
|  |   dynamic nameN; | ||||||
|  |   String? phoneNumber; | ||||||
|  |   String? setupID; | ||||||
|  |   dynamic distanceInKilometers; | ||||||
|  |   bool? isActive; | ||||||
|  |   String? latitude; | ||||||
|  |   String? longitude; | ||||||
|  |   dynamic mainProjectID; | ||||||
|  |   bool? projectOutSA; | ||||||
|  |   bool? usingInDoctorApp; | ||||||
|  |   bool? isHMC; | ||||||
|  |   String? region; | ||||||
|  |   String? regionArabic; | ||||||
|  |   String? regionEnglish; | ||||||
|  |   String? regionID; | ||||||
|  | 
 | ||||||
|  |   HospitalsModel({ | ||||||
|  |     this.desciption, | ||||||
|  |     this.desciptionN, | ||||||
|  |     this.iD, | ||||||
|  |     this.legalName, | ||||||
|  |     this.legalNameN, | ||||||
|  |     this.name, | ||||||
|  |     this.nameN, | ||||||
|  |     this.phoneNumber, | ||||||
|  |     this.setupID, | ||||||
|  |     this.distanceInKilometers, | ||||||
|  |     this.isActive, | ||||||
|  |     this.latitude, | ||||||
|  |     this.longitude, | ||||||
|  |     this.mainProjectID, | ||||||
|  |     this.projectOutSA, | ||||||
|  |     this.usingInDoctorApp, | ||||||
|  |     this.isHMC, | ||||||
|  |     this.region, | ||||||
|  |     this.regionArabic, | ||||||
|  |     this.regionEnglish, | ||||||
|  |     this.regionID, | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   HospitalsModel.fromJson(Map<String, dynamic> json) { | ||||||
|  |     desciption = json['Desciption']; | ||||||
|  |     desciptionN = json['DesciptionN']; | ||||||
|  |     iD = json['ID']; | ||||||
|  |     legalName = json['LegalName']; | ||||||
|  |     legalNameN = json['LegalNameN']; | ||||||
|  |     name = json['Name']; | ||||||
|  |     nameN = json['NameN']; | ||||||
|  |     phoneNumber = json['PhoneNumber']; | ||||||
|  |     setupID = json['SetupID']; | ||||||
|  |     distanceInKilometers = json['DistanceInKilometers']; | ||||||
|  |     isActive = json['IsActive']; | ||||||
|  |     latitude = json['Latitude']; | ||||||
|  |     longitude = json['Longitude']; | ||||||
|  |     mainProjectID = json['MainProjectID']; | ||||||
|  |     projectOutSA = json['ProjectOutSA']; | ||||||
|  |     usingInDoctorApp = json['UsingInDoctorApp']; | ||||||
|  |     this.isHMC = json["IsHMC"]; | ||||||
|  |     this.regionArabic = json['RegionNameN']; | ||||||
|  |     this.regionEnglish = json['RegionName']; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   String? getRegionName(bool isArabic) { | ||||||
|  |     if (isArabic) { | ||||||
|  |       return regionArabic; | ||||||
|  |     } | ||||||
|  |     return regionEnglish; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   String? getName(bool isArabic) { | ||||||
|  |     if (isArabic) { | ||||||
|  |       return "$nameN"; | ||||||
|  |     } | ||||||
|  |     return name; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Map<String, dynamic> toJson() { | ||||||
|  |     final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||||
|  |     data['Desciption'] = this.desciption; | ||||||
|  |     data['DesciptionN'] = this.desciptionN; | ||||||
|  |     data['ID'] = this.iD; | ||||||
|  |     data['LegalName'] = this.legalName; | ||||||
|  |     data['LegalNameN'] = this.legalNameN; | ||||||
|  |     data['Name'] = this.name; | ||||||
|  |     data['NameN'] = this.nameN; | ||||||
|  |     data['PhoneNumber'] = this.phoneNumber; | ||||||
|  |     data['SetupID'] = this.setupID; | ||||||
|  |     data['DistanceInKilometers'] = this.distanceInKilometers; | ||||||
|  |     data['IsActive'] = this.isActive; | ||||||
|  |     data['Latitude'] = this.latitude; | ||||||
|  |     data['Longitude'] = this.longitude; | ||||||
|  |     data['MainProjectID'] = this.mainProjectID; | ||||||
|  |     data['ProjectOutSA'] = this.projectOutSA; | ||||||
|  |     data['UsingInDoctorApp'] = this.usingInDoctorApp; | ||||||
|  |     return data; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,88 @@ | |||||||
|  | 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' 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 { | ||||||
|  |   final String svgPath; | ||||||
|  |   final String title; | ||||||
|  |   final String subTitle; | ||||||
|  | 
 | ||||||
|  |   const FacilitySelectionItem( | ||||||
|  |       {super.key, | ||||||
|  |       required this.svgPath, | ||||||
|  |       required this.subTitle, | ||||||
|  |       required this.title}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return Container( | ||||||
|  |       decoration: RoundedRectangleBorder().toSmoothCornerDecoration( | ||||||
|  |         color: AppColors.whiteColor, | ||||||
|  |         borderRadius: 20.h, | ||||||
|  |         hasShadow: false, | ||||||
|  |       ), | ||||||
|  |       child: Column( | ||||||
|  |         mainAxisAlignment: MainAxisAlignment.start, | ||||||
|  |         crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |         children: [ | ||||||
|  |       Utils.buildSvgWithAssets( | ||||||
|  |       icon:  svgPath, | ||||||
|  |         width: 32, | ||||||
|  |         height: 32, | ||||||
|  |         fit: BoxFit.contain, | ||||||
|  |       ), | ||||||
|  |           SizedBox(height: 16,), | ||||||
|  |           Row( | ||||||
|  |             mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |             children: [ | ||||||
|  |               info, | ||||||
|  |               Utils.buildSvgWithAssets( | ||||||
|  |                 icon: AppAssets.forward_arrow_icon, | ||||||
|  |                 iconColor: AppColors.blackColor, | ||||||
|  |                 width: 18, | ||||||
|  |                 height: 13, | ||||||
|  |                 fit: BoxFit.contain, | ||||||
|  |               ), | ||||||
|  |             ], | ||||||
|  |           ) | ||||||
|  |         ], | ||||||
|  |       ).paddingAll(16.h), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |  Widget get info => Column( | ||||||
|  |         mainAxisAlignment: MainAxisAlignment.start, | ||||||
|  |         crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |         children: [ | ||||||
|  |           Align( | ||||||
|  |             alignment: Alignment.centerLeft, | ||||||
|  |             child: Text( | ||||||
|  |               title, | ||||||
|  |               style: TextStyle( | ||||||
|  |                 fontSize: 16.h, | ||||||
|  |                 fontWeight: FontWeight.w600, | ||||||
|  |                 color: AppColors.blackColor, | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |           Align( | ||||||
|  |             alignment: Alignment.centerLeft, | ||||||
|  |             child: Text( | ||||||
|  |               subTitle, | ||||||
|  |               style: TextStyle( | ||||||
|  |                 fontSize: 12.h, | ||||||
|  |                 fontWeight: FontWeight.w500, | ||||||
|  |                 color: AppColors.greyTextColor, | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |         ], | ||||||
|  |       ); | ||||||
|  | } | ||||||
| @ -0,0 +1,79 @@ | |||||||
|  | import 'package:easy_localization/easy_localization.dart' | ||||||
|  |     show tr, StringTranslateExtension; | ||||||
|  | import 'package:flutter/cupertino.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/string_extensions.dart'; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/widget_extensions.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'; | ||||||
|  | import 'package:provider/provider.dart' show Provider; | ||||||
|  | 
 | ||||||
|  | class FacilityTypeSelectionWidget extends StatelessWidget { | ||||||
|  |   late MyAppointmentsViewModel myAppointmentsViewModel; | ||||||
|  |   late AppointmentViaRegionViewmodel regionalViewModel; | ||||||
|  |   final String selectedRegion; | ||||||
|  | 
 | ||||||
|  |   FacilityTypeSelectionWidget({super.key, required this.selectedRegion}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context); | ||||||
|  |     regionalViewModel = Provider.of<AppointmentViaRegionViewmodel>(context); | ||||||
|  |     return Column( | ||||||
|  |       crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |       children: [ | ||||||
|  |         Text( | ||||||
|  |           LocaleKeys.selectFacility.tr(), | ||||||
|  |           style: TextStyle( | ||||||
|  |             fontSize: 21, | ||||||
|  |             fontWeight: FontWeight.w600, | ||||||
|  |             color: AppColors.blackColor, | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         Text( | ||||||
|  |           LocaleKeys.selectFacilitiesSubTitle, | ||||||
|  |           style: TextStyle( | ||||||
|  |             fontSize: 16, | ||||||
|  |             fontWeight: FontWeight.w500, | ||||||
|  |             color: AppColors.greyTextColor, | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         SizedBox(height: 24.h), | ||||||
|  |         FacilitySelectionItem( | ||||||
|  |           svgPath: AppAssets.hmg, | ||||||
|  |           title: "HMG".needTranslation, | ||||||
|  |           subTitle: LocaleKeys.hospitalsWithCount.tr(namedArgs: { | ||||||
|  |             'count': | ||||||
|  |                 "${myAppointmentsViewModel.hospitalList?.registeredDoctorMap?[selectedRegion]?.hmgSize ?? 0}" | ||||||
|  |           }), | ||||||
|  |         ).onPress( | ||||||
|  |           () { | ||||||
|  |             regionalViewModel.setFacility(FacilitySelection.HMG.name); | ||||||
|  |             regionalViewModel.setBottomSheetState( | ||||||
|  |                 AppointmentViaRegionState.HOSPITAL_SELECTION); | ||||||
|  |           }, | ||||||
|  |         ), | ||||||
|  |         SizedBox(height: 16.h), | ||||||
|  |         FacilitySelectionItem( | ||||||
|  |             svgPath: AppAssets.hmc, | ||||||
|  |             title: "HMC".needTranslation, | ||||||
|  |             subTitle: LocaleKeys.medicalCentersWithCount.tr(namedArgs: { | ||||||
|  |               'count': | ||||||
|  |                   "${myAppointmentsViewModel.hospitalList?.registeredDoctorMap?[selectedRegion]?.hmcSize ?? 0}" | ||||||
|  |             })).onPress( | ||||||
|  |           () { | ||||||
|  |             regionalViewModel.setFacility(FacilitySelection.HMC.name); | ||||||
|  |             regionalViewModel.setBottomSheetState( | ||||||
|  |                 AppointmentViaRegionState.HOSPITAL_SELECTION); | ||||||
|  |           }, | ||||||
|  |         ), | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,109 @@ | |||||||
|  | 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/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/lab/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 { | ||||||
|  |   late MyAppointmentsViewModel appointmentsViewModel; | ||||||
|  |   late AppointmentViaRegionViewmodel regionalViewModel; | ||||||
|  |   final TextEditingController searchText = TextEditingController(); | ||||||
|  | 
 | ||||||
|  |   HospitalBottomSheetBody({super.key}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     appointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context); | ||||||
|  |     regionalViewModel = Provider.of<AppointmentViaRegionViewmodel>(context); | ||||||
|  |     return Column( | ||||||
|  |       crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |       children: [ | ||||||
|  |         Text( | ||||||
|  |           LocaleKeys.selectHospital.tr(), | ||||||
|  |           style: TextStyle( | ||||||
|  |             fontSize: 21, | ||||||
|  |             fontWeight: FontWeight.w600, | ||||||
|  |             color: AppColors.blackColor, | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         Text( | ||||||
|  |           LocaleKeys.selectHospitalSubTitle.tr(), | ||||||
|  |           style: TextStyle( | ||||||
|  |             fontSize: 16, | ||||||
|  |             fontWeight: FontWeight.w500, | ||||||
|  |             color: AppColors.greyTextColor, | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         SizedBox(height: 16.h), | ||||||
|  |         TextInputWidget( | ||||||
|  |           labelText: LocaleKeys.search.tr(), | ||||||
|  |           hintText: "Search Hospital".tr(), | ||||||
|  |           controller: searchText, | ||||||
|  |           onChange: (value) { | ||||||
|  |             appointmentsViewModel.filterHospitalListByString(value, regionalViewModel.selectedRegionId , regionalViewModel.selectedFacilityType == | ||||||
|  |                 FacilitySelection.HMG.name); | ||||||
|  |           }, | ||||||
|  |           isEnable: true, | ||||||
|  |           prefix: null, | ||||||
|  |           autoFocus: false, | ||||||
|  |           isBorderAllowed: false, | ||||||
|  |           keyboardType: TextInputType.text, | ||||||
|  |           isAllowLeadingIcon: true, | ||||||
|  |           selectionType: SelectionTypeEnum.search, | ||||||
|  |           padding: EdgeInsets.symmetric( | ||||||
|  |             vertical: ResponsiveExtension(10).h, | ||||||
|  |             horizontal: ResponsiveExtension(15).h, | ||||||
|  |           ), | ||||||
|  |         ), | ||||||
|  |         SizedBox(height: 24.h), | ||||||
|  |         // TypeSelectionWidget( | ||||||
|  |         //   hmcCount: "0", | ||||||
|  |         //   hmgCount: "0", | ||||||
|  |         // ), | ||||||
|  |         // SizedBox(height: 21.h), | ||||||
|  |         SizedBox( | ||||||
|  |           height: MediaQuery.sizeOf(context).height * .4, | ||||||
|  |           child: ListView.separated( | ||||||
|  |               itemBuilder: (_, index) => HospitalListItem( | ||||||
|  |                     hospitalData: regionalViewModel.selectedFacilityType == | ||||||
|  |                             FacilitySelection.HMG.name | ||||||
|  |                         ? appointmentsViewModel | ||||||
|  |                             .filteredHospitalList! | ||||||
|  |                             .registeredDoctorMap![ | ||||||
|  |                                 regionalViewModel.selectedRegionId!]! | ||||||
|  |                             .hmgDoctorList![index] | ||||||
|  |                         : appointmentsViewModel | ||||||
|  |                             .filteredHospitalList | ||||||
|  |                             ?.registeredDoctorMap?[ | ||||||
|  |                                 regionalViewModel.selectedRegionId!] | ||||||
|  |                             ?.hmcDoctorList?[index], | ||||||
|  |                     isLocationEnabled:  appointmentsViewModel.getLocationStatus(), | ||||||
|  |                   ), | ||||||
|  |               separatorBuilder: (_, __) => SizedBox( | ||||||
|  |                     height: 16.h, | ||||||
|  |                   ), | ||||||
|  |               itemCount: (regionalViewModel.selectedFacilityType == | ||||||
|  |                               FacilitySelection.HMG.name | ||||||
|  |                           ? (appointmentsViewModel.filteredHospitalList?.registeredDoctorMap?[ | ||||||
|  |                                   regionalViewModel.selectedRegionId]?.hmgDoctorList) | ||||||
|  |                           : (appointmentsViewModel | ||||||
|  |                               .filteredHospitalList | ||||||
|  |                               ?.registeredDoctorMap?[ | ||||||
|  |                                   regionalViewModel.selectedRegionId]?.hmcDoctorList))?.length ?? | ||||||
|  |                   0), | ||||||
|  |         ) | ||||||
|  |       ], | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,113 @@ | |||||||
|  | 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/dependencies.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/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'; | ||||||
|  | 
 | ||||||
|  | class HospitalListItem extends StatelessWidget { | ||||||
|  |   final PatientDoctorAppointmentList? hospitalData; | ||||||
|  |   final bool isLocationEnabled; | ||||||
|  | 
 | ||||||
|  |   late AppState appState; | ||||||
|  | 
 | ||||||
|  |   HospitalListItem( | ||||||
|  |       {super.key, required this.hospitalData, required this.isLocationEnabled}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     appState = getIt.get<AppState>(); | ||||||
|  |     return DecoratedBox( | ||||||
|  |       decoration: RoundedRectangleBorder().toSmoothCornerDecoration( | ||||||
|  |         color: AppColors.whiteColor, | ||||||
|  |         borderRadius: 20.h, | ||||||
|  |         hasShadow: false, | ||||||
|  |       ), | ||||||
|  |       child: Row( | ||||||
|  |         mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |         children: [ | ||||||
|  |           Expanded( | ||||||
|  |             child: Column( | ||||||
|  |               crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |               spacing: 8.h, | ||||||
|  |               children: [hospitalName, distanceInfo], | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |           Utils.buildSvgWithAssets( | ||||||
|  |             icon: AppAssets.forward_arrow_icon, | ||||||
|  |             iconColor: AppColors.blackColor, | ||||||
|  |             width: 18, | ||||||
|  |             height: 13, | ||||||
|  |             fit: BoxFit.contain, | ||||||
|  |           ), | ||||||
|  |         ], | ||||||
|  |       ).paddingSymmetrical(16.h, 16.h), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Widget get hospitalName => Row( | ||||||
|  |         children: [ | ||||||
|  |           Utils.buildSvgWithAssets( | ||||||
|  |             icon: (hospitalData?.isHMC == true) ? AppAssets.hmc : AppAssets.hmg, | ||||||
|  |           ).paddingOnly(right: 10), | ||||||
|  |           Expanded( | ||||||
|  |             child: Text( | ||||||
|  |               hospitalData?.filterName ?? "", | ||||||
|  |               style: TextStyle( | ||||||
|  |                 fontWeight: FontWeight.w600, | ||||||
|  |                 fontSize: 16, | ||||||
|  |                 color: AppColors.blackColor, | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |           ) | ||||||
|  |         ], | ||||||
|  |       ); | ||||||
|  | 
 | ||||||
|  |   Widget get distanceInfo => Row( | ||||||
|  | 
 | ||||||
|  |         children: [ | ||||||
|  |           Visibility( | ||||||
|  |               visible: (hospitalData?.distanceInKMs != "0"), | ||||||
|  |               child: | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                 AppCustomChipWidget( | ||||||
|  |                     labelText: | ||||||
|  |                         "${hospitalData?.distanceInKMs ?? ""} km".needTranslation, | ||||||
|  |                     deleteIcon: AppAssets.location_red, | ||||||
|  |                     deleteIconSize: Size(9, 12), | ||||||
|  |                     backgroundColor: AppColors.secondaryLightRedColor, | ||||||
|  |                     textColor: AppColors.errorColor, | ||||||
|  |                   ), | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   ), | ||||||
|  |           Visibility( | ||||||
|  |               visible: (hospitalData?.distanceInKMs == "0"), | ||||||
|  |               child: Row( | ||||||
|  |                 children: [ | ||||||
|  |                   AppCustomChipWidget( | ||||||
|  |                     labelText: "Distance not available".needTranslation, | ||||||
|  |                     textColor: AppColors.blackColor, | ||||||
|  |                   ), | ||||||
|  |                   SizedBox(width: 8.h,) | ||||||
|  | 
 | ||||||
|  |                 ], | ||||||
|  |               )), | ||||||
|  |           Visibility( | ||||||
|  |               visible: !isLocationEnabled, | ||||||
|  |               child: AppCustomChipWidget( | ||||||
|  |                 labelText: "Location turned off".needTranslation, | ||||||
|  |                 deleteIcon: AppAssets.location_unavailable, | ||||||
|  |                 deleteIconSize: Size(9, 12), | ||||||
|  |                 textColor: AppColors.blackColor, | ||||||
|  |               )), | ||||||
|  |         ], | ||||||
|  |       ); | ||||||
|  | } | ||||||
| @ -0,0 +1,93 @@ | |||||||
|  | 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/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; | ||||||
|  |   final String hmgCount; | ||||||
|  | 
 | ||||||
|  |   const TypeSelectionWidget( | ||||||
|  |       {super.key, required this.hmcCount, required this.hmgCount}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return Consumer<MyAppointmentsViewModel>( | ||||||
|  |       builder: (_, data, __) => Row( | ||||||
|  |         spacing: 8, | ||||||
|  |         mainAxisSize: MainAxisSize.max, | ||||||
|  |         children: [ | ||||||
|  |           AppCustomChipWidget( | ||||||
|  |             labelText: "All Facilities".needTranslation, | ||||||
|  |             shape: RoundedRectangleBorder( | ||||||
|  |                 side: BorderSide( | ||||||
|  |                   color: data.currentlySelectedFacility == FacilitySelection.ALL | ||||||
|  |                       ? AppColors.errorColor | ||||||
|  |                       : AppColors.chipBorderColorOpacity20, | ||||||
|  |                   width: 1, | ||||||
|  |                 ), | ||||||
|  |                 borderRadius: BorderRadius.circular(10)), | ||||||
|  |             backgroundColor: | ||||||
|  |                 data.currentlySelectedFacility == FacilitySelection.ALL | ||||||
|  |                     ? AppColors.secondaryLightRedColor | ||||||
|  |                     : AppColors.whiteColor, | ||||||
|  |             textColor: data.currentlySelectedFacility == FacilitySelection.ALL | ||||||
|  |                 ? AppColors.errorColor | ||||||
|  |                 : AppColors.blackColor, | ||||||
|  |           ).onPress((){ | ||||||
|  |             data.setSelectedFacility(FacilitySelection.ALL); | ||||||
|  |           }), | ||||||
|  |           AppCustomChipWidget( | ||||||
|  |             icon: AppAssets.hmg, | ||||||
|  |             iconHasColor: false, | ||||||
|  |             labelText: "Hospitals".needTranslation, | ||||||
|  |             shape: RoundedRectangleBorder( | ||||||
|  |                 side: BorderSide( | ||||||
|  |                   color: data.currentlySelectedFacility == FacilitySelection.HMG | ||||||
|  |                       ? AppColors.errorColor | ||||||
|  |                       : AppColors.chipBorderColorOpacity20, | ||||||
|  |                   width: 1, | ||||||
|  |                 ), | ||||||
|  |                 borderRadius: BorderRadius.circular(10)), | ||||||
|  |             backgroundColor: | ||||||
|  |                 data.currentlySelectedFacility == FacilitySelection.HMG | ||||||
|  |                     ? AppColors.secondaryLightRedColor | ||||||
|  |                     : AppColors.whiteColor, | ||||||
|  |             textColor: data.currentlySelectedFacility == FacilitySelection.HMG | ||||||
|  |                 ? AppColors.errorColor | ||||||
|  |                 : AppColors.blackColor, | ||||||
|  |           ).onPress((){ | ||||||
|  |             data.setSelectedFacility(FacilitySelection.HMG); | ||||||
|  |           }), | ||||||
|  |           AppCustomChipWidget( | ||||||
|  |             icon: AppAssets.hmc, | ||||||
|  |             iconHasColor: false, | ||||||
|  |             labelText: "Medical Centers".needTranslation, | ||||||
|  |             shape: RoundedRectangleBorder( | ||||||
|  |                 side: BorderSide( | ||||||
|  |                   color: data.currentlySelectedFacility == FacilitySelection.HMC | ||||||
|  |                       ? AppColors.errorColor | ||||||
|  |                       : AppColors.chipBorderColorOpacity20, | ||||||
|  |                   width: 1, | ||||||
|  |                 ), | ||||||
|  |                 borderRadius: BorderRadius.circular(10)), | ||||||
|  |             backgroundColor: | ||||||
|  |             data.currentlySelectedFacility == FacilitySelection.HMC | ||||||
|  |                 ? AppColors.secondaryLightRedColor | ||||||
|  |                 : AppColors.whiteColor, | ||||||
|  |             textColor: data.currentlySelectedFacility == FacilitySelection.HMC | ||||||
|  |                 ? AppColors.errorColor | ||||||
|  |                 : AppColors.blackColor, | ||||||
|  |           ).onPress((){ | ||||||
|  |             data.setSelectedFacility(FacilitySelection.HMC); | ||||||
|  |           }), | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,114 @@ | |||||||
|  | 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/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; | ||||||
|  | import 'package:hmg_patient_app_new/widgets/chip/app_custom_chip_widget.dart'; | ||||||
|  | 
 | ||||||
|  | class RegionListItem extends StatelessWidget { | ||||||
|  |   final String title; | ||||||
|  |   final String hmcCount; | ||||||
|  |   final String hmgCount; | ||||||
|  |   final String subTitle; | ||||||
|  | 
 | ||||||
|  |   const RegionListItem( | ||||||
|  |       {super.key, | ||||||
|  |       required this.title, | ||||||
|  |       required this.subTitle, | ||||||
|  |       required this.hmcCount, | ||||||
|  |       required this.hmgCount}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return Container( | ||||||
|  |       decoration: RoundedRectangleBorder().toSmoothCornerDecoration( | ||||||
|  |         color: AppColors.whiteColor, | ||||||
|  |         borderRadius: 20.h, | ||||||
|  |         hasShadow: false, | ||||||
|  |       ), | ||||||
|  |       child: Column( | ||||||
|  |         mainAxisAlignment: MainAxisAlignment.start, | ||||||
|  |         children: [ | ||||||
|  |           header, | ||||||
|  |           Row( | ||||||
|  |             mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |             children: [ | ||||||
|  |               Row( | ||||||
|  |                 spacing: 8.h, | ||||||
|  |                 children: [ | ||||||
|  |                   placesCountItem( | ||||||
|  |                       AppAssets.hmg, hmgCount, " ${LocaleKeys.hospital.tr()}"), | ||||||
|  |                   placesCountItem(AppAssets.hmc, hmcCount, | ||||||
|  |                       " ${LocaleKeys.medicalCenters.tr()}"), | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|  |               Utils.buildSvgWithAssets( | ||||||
|  |                 icon: AppAssets.forward_arrow_icon, | ||||||
|  |                 iconColor: AppColors.blackColor, | ||||||
|  |                 width: 18, | ||||||
|  |                 height: 13, | ||||||
|  |                 fit: BoxFit.contain, | ||||||
|  |               ), | ||||||
|  |             ], | ||||||
|  |           ) | ||||||
|  |         ], | ||||||
|  |       ).paddingAll(16.h), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Widget placesCountItem(String svgPath, String count, String title) { | ||||||
|  |     return AppCustomChipWidget( | ||||||
|  |       iconSize: 14, | ||||||
|  |       icon: svgPath, | ||||||
|  |       iconHasColor: false, | ||||||
|  |       richText: RichText( | ||||||
|  |                   text: TextSpan( | ||||||
|  |                       text: count, | ||||||
|  |                       style: TextStyle( | ||||||
|  |                           fontSize: 12.h, | ||||||
|  |                           fontWeight: FontWeight.w700, | ||||||
|  |                           color: AppColors.blackColor), | ||||||
|  |                       children: [ | ||||||
|  |                     TextSpan( | ||||||
|  |                         text: title, | ||||||
|  |                         style: TextStyle( | ||||||
|  |                             fontSize: 12.h, | ||||||
|  |                             fontWeight: FontWeight.w500, | ||||||
|  |                             color: AppColors.blackColor)) | ||||||
|  |                   ])), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |  Widget get header => Column( | ||||||
|  |         mainAxisAlignment: MainAxisAlignment.start, | ||||||
|  |         crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |         children: [ | ||||||
|  |           Align( | ||||||
|  |             alignment: Alignment.centerLeft, | ||||||
|  |             child: Text( | ||||||
|  |               title, | ||||||
|  |               style: TextStyle( | ||||||
|  |                 fontSize: 16.h, | ||||||
|  |                 fontWeight: FontWeight.w600, | ||||||
|  |                 color: AppColors.blackColor, | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |           Align( | ||||||
|  |             alignment: Alignment.centerLeft, | ||||||
|  |             child: Text( | ||||||
|  |               subTitle, | ||||||
|  |               style: TextStyle( | ||||||
|  |                 fontSize: 12.h, | ||||||
|  |                 fontWeight: FontWeight.w500, | ||||||
|  |                 color: AppColors.greyTextColor, | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |           ), | ||||||
|  |         ], | ||||||
|  |       ); | ||||||
|  | } | ||||||
| @ -0,0 +1,86 @@ | |||||||
|  | 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/core/utils/utils.dart' show Utils; | ||||||
|  | import 'package:hmg_patient_app_new/extensions/widget_extensions.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'; | ||||||
|  | 
 | ||||||
|  | class RegionBottomSheetBody extends StatefulWidget { | ||||||
|  | 
 | ||||||
|  |   const RegionBottomSheetBody({super.key}); | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   State<RegionBottomSheetBody> createState() => _RegionBottomSheetBodyState(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class _RegionBottomSheetBodyState extends State<RegionBottomSheetBody> { | ||||||
|  |   late MyAppointmentsViewModel myAppointmentsViewModel; | ||||||
|  |   late AppointmentViaRegionViewmodel regionalViewModel; | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   void initState() { | ||||||
|  |     scheduleMicrotask(() { | ||||||
|  |       myAppointmentsViewModel.getRegionMappedProjectList(); | ||||||
|  |     }); | ||||||
|  |     super.initState(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     myAppointmentsViewModel = Provider.of<MyAppointmentsViewModel>(context); | ||||||
|  |     regionalViewModel = Provider.of<AppointmentViaRegionViewmodel>(context); | ||||||
|  |     return Consumer<MyAppointmentsViewModel>( | ||||||
|  |       builder: (context, myAppointmentsVM, child) { | ||||||
|  |         if (myAppointmentsVM.isRegionListLoading) { | ||||||
|  |           return Container( | ||||||
|  |             height: MediaQuery.of(context).size.height * 0.3, | ||||||
|  |             decoration: const BoxDecoration( | ||||||
|  |               color: Colors.white, | ||||||
|  |               borderRadius: BorderRadius.vertical(top: Radius.circular(16)), | ||||||
|  |             ), | ||||||
|  |             child: Center( | ||||||
|  |               child: Utils.getLoadingWidget(), | ||||||
|  |             ), | ||||||
|  |           ); | ||||||
|  |         } else { | ||||||
|  |           return SizedBox( | ||||||
|  |             height: MediaQuery.of(context).size.height * 0.5, | ||||||
|  |             child: ListView.separated( | ||||||
|  |               itemCount: | ||||||
|  |                   myAppointmentsVM.hospitalList?.registeredDoctorMap?.length ?? | ||||||
|  |                       0, | ||||||
|  |               separatorBuilder: (_, __) { | ||||||
|  |                 return SizedBox( | ||||||
|  |                   height: 16.h, | ||||||
|  |                 ); | ||||||
|  |               }, | ||||||
|  |               itemBuilder: (_, index) { | ||||||
|  |                 String key = myAppointmentsVM | ||||||
|  |                         .hospitalList?.registeredDoctorMap?.keys | ||||||
|  |                         .toList()[index] ?? | ||||||
|  |                     ''; | ||||||
|  |                 return RegionListItem( | ||||||
|  |                   title: key, | ||||||
|  |                   subTitle: "", | ||||||
|  |                   hmcCount: | ||||||
|  |                       "${myAppointmentsVM.hospitalList?.registeredDoctorMap?[key]?.hmcSize ?? 0}", | ||||||
|  |                   hmgCount: | ||||||
|  |                       "${myAppointmentsVM.hospitalList?.registeredDoctorMap?[key]?.hmgSize ?? 0}", | ||||||
|  |                 ).onPress(() { | ||||||
|  |                   regionalViewModel.setSelectedRegionId(key); | ||||||
|  |                   regionalViewModel.setBottomSheetState(AppointmentViaRegionState.TYPE_SELECTION); | ||||||
|  |                 }); | ||||||
|  |               }, | ||||||
|  |             ), | ||||||
|  |           ); | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
					Loading…
					
					
				
		Reference in New Issue