diff --git a/lib/models/Appointments/DoctorListResponse.dart b/lib/models/Appointments/DoctorListResponse.dart index 241f014a..80af2683 100644 --- a/lib/models/Appointments/DoctorListResponse.dart +++ b/lib/models/Appointments/DoctorListResponse.dart @@ -239,10 +239,13 @@ class PatientDoctorAppointmentList { class PatientDoctorAppointmentListByRegion { List? hmgDoctorList = []; List? hmcDoctorList = []; + int hmcSize = 0; + int hmgSize = 0; + double distance = double.infinity; } class RegionList { - Map? registeredDoctorMap; + Map? registeredDoctorMap = {}; } /// dummy data diff --git a/lib/pages/BookAppointment/SearchResultsByRegion.dart b/lib/pages/BookAppointment/SearchResultsByRegion.dart index 87ae896e..f8d6b5eb 100644 --- a/lib/pages/BookAppointment/SearchResultsByRegion.dart +++ b/lib/pages/BookAppointment/SearchResultsByRegion.dart @@ -2,6 +2,7 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/OBGyneProcedureListResponse.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy_module_page.dart'; import 'package:diplomaticquarterapp/theme/colors.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; @@ -55,8 +56,17 @@ class SearchResultsByRegion extends StatelessWidget { .registeredDoctorMap?.keys .toList()[index] ?? ''; + + print(' the key is $key'); return AppExpandableNotifier( - title: key, + headerWidget: RegionTitle( + title: key, + hmcCount: + "${patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmcSize ?? 0}", + hmgCount: + "${patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmgSize ?? 0}", + ), + showDropDownIconWithCustomHeader: true, isTitleSingleLine: false, isDoctorSearchResult: isDoctorSearchResult, bodyWidget: Column( @@ -66,6 +76,8 @@ class SearchResultsByRegion extends StatelessWidget { iconUrl: 'assets/images/svg/HMG.svg', title: TranslationBase.of(context).hmgHospital, isHMC: false, + itemCount: + "${patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmgSize ?? 0}", ), showDropDownIconWithCustomHeader: true, bodyWidget: HospitalBodyWidget( @@ -86,6 +98,8 @@ class SearchResultsByRegion extends StatelessWidget { iconUrl: 'assets/images/svg/HMC.svg', title: TranslationBase.of(context).hmcHospital, isHMC: true, + itemCount: + "${patientDoctorAppointmentListHospital.registeredDoctorMap?[key]?.hmcSize ?? 0}", ), showDropDownIconWithCustomHeader: true, bodyWidget: HospitalBodyWidget( @@ -212,11 +226,11 @@ class HospitalBodyWidget extends StatelessWidget { padding: EdgeInsets.only(bottom: 10, top: 10, left: 21, right: 21), itemBuilder: (context, _index) { - print("the index of patientDoctorAppointmentList is ${_index}"); - print("the index of parent is ${index}"); + // print("the index of patientDoctorAppointmentList is ${_index}"); + // print("the index of parent is ${index}"); final doctor = patientDoctorAppointmentListHospital![index] .patientDoctorAppointmentList![_index]; - print('the doctor is ${doctor.toJson()}'); + // print('the doctor is ${doctor.toJson()}'); return DoctorView( doctor: doctor, isLiveCareAppointment: isLiveCareAppointment, @@ -241,25 +255,103 @@ class HospitalBodyWidget extends StatelessWidget { } } +class RegionTitle extends StatelessWidget { + final String title; + final String hmcCount; + final String hmgCount; + + const RegionTitle( + {super.key, + required this.title, + required this.hmcCount, + required this.hmgCount}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 18, color: Colors.black, fontWeight: FontWeight.w700), + ), + SizedBox( + height: 8, + ), + Row( + children: [ + Text( + "${TranslationBase.of(context).hmgHospitalCount.replaceAll("@", hmgCount)} ,", + style: TextStyle( + fontSize: 12, + color: Colors.red, + fontWeight: FontWeight.w400), + ), + SizedBox( + width: 8, + ), + Text( + "${TranslationBase.of(context).hmcHospitalCount.replaceAll("@", hmcCount)}", + style: TextStyle( + fontSize: 12, + color: Colors.greenAccent, + fontWeight: FontWeight.w400), + ), + ], + ), + ], + ), + ); + } +} + class HospitalTitle extends StatelessWidget { final String title; final String iconUrl; final bool isHMC; + final String itemCount; - const HospitalTitle({super.key, required this.title, required this.iconUrl, required this.isHMC}); + const HospitalTitle( + {super.key, + required this.title, + required this.iconUrl, + required this.isHMC, + required this.itemCount}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(8.0), - child: Row( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - SvgPicture.asset(iconUrl), - SizedBox(width: 8,), + Row( + children: [ + SvgPicture.asset(iconUrl), + SizedBox( + width: 8, + ), + Text( + title, + style: TextStyle( + fontSize: 18, + color: isHMC ? Colors.greenAccent : Colors.red, + fontWeight: FontWeight.w600), + ), + ], + ), + SizedBox( + height: 6, + ), Text( - title, + isHMC + ? "${TranslationBase.of(context).hmcHospitalCount.replaceAll("@", itemCount)}" + : "${TranslationBase.of(context).hmgHospitalCount.replaceAll("@", itemCount)} ,", style: TextStyle( - fontSize: 18, color:isHMC? Colors.greenAccent : Colors.red, fontWeight: FontWeight.w600), + fontSize: 12, color: Colors.black, fontWeight: FontWeight.w600), ), ], ), diff --git a/lib/pages/BookAppointment/components/SearchByDoctor.dart b/lib/pages/BookAppointment/components/SearchByDoctor.dart index 30b8ea1c..93daa573 100644 --- a/lib/pages/BookAppointment/components/SearchByDoctor.dart +++ b/lib/pages/BookAppointment/components/SearchByDoctor.dart @@ -100,21 +100,27 @@ class _SearchByDoctorState extends State { List _patientDoctorAppointmentListHospital = []; - service.getDoctorsListByName(doctorNameController.text, languageID, context).then((res) { + service.getDoctorsListByName(doctorNameController.text, languageID, context).then((res) async { // GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { RegionList regionHospitalList = RegionList(); - setState(() { + setState(() async { if (res['DoctorList'].length != 0) { res['DoctorList'].forEach((v) { var reg = region[counter%4]; + counter++; doctorsList.add(new DoctorList.fromJson(v, region: reg,isHMC: isHmc)); isHmc = !isHmc; }); + print('the counter is ${ + counter + }'); - regionHospitalList = DoctorMapper.getMappedDoctor(doctorsList); + regionHospitalList = await DoctorMapper.getMappedDoctor(doctorsList); + DoctorMapper.sortList(false, regionHospitalList); + // doctorsList.forEach((element) { // List doctorByHospital = diff --git a/lib/services/appointment_services/doctor_response_mapper.dart b/lib/services/appointment_services/doctor_response_mapper.dart index 6cfa1068..60ec05f6 100644 --- a/lib/services/appointment_services/doctor_response_mapper.dart +++ b/lib/services/appointment_services/doctor_response_mapper.dart @@ -1,42 +1,105 @@ +import 'dart:math'; + +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; class DoctorMapper{ - static RegionList getMappedDoctor( List doctorList ){ + static Future getMappedDoctor(List doctorList) async { RegionList regionList = RegionList(); + AppSharedPreferences sharedPref = AppSharedPreferences(); + + for (var element in doctorList) { + if (element.region == null) continue; + + var regionDoctorList = regionList.registeredDoctorMap?.putIfAbsent( + element.region!, () => PatientDoctorAppointmentListByRegion()); + + List? targetList = element.isHMC == true + ? regionDoctorList?.hmcDoctorList + : regionDoctorList?.hmgDoctorList; + + var doctorByHospital = targetList + ?.where((clinic) => + clinic.filterName == element.getProjectCompleteName()) + .toList() ?? + []; + + if (doctorByHospital.isNotEmpty) { + doctorByHospital.first.patientDoctorAppointmentList?.add(element); + } else { + var newAppointment = PatientDoctorAppointmentList( + filterName: element.getProjectCompleteName(), + distanceInKMs: element.projectDistanceInKiloMeters.toString(), + projectTopName: element.projectTopName, + projectBottomName: element.projectBottomName, + patientDoctorAppointment: element, + ); + if(element.projectDistanceInKiloMeters!= null ){ + if(regionDoctorList!.distance>element.projectDistanceInKiloMeters){ + regionDoctorList!.distance = element.projectDistanceInKiloMeters; + } + }else + if (await sharedPref.getDouble(USER_LAT) != null && await sharedPref.getDouble(USER_LONG) != null && element.latitude != null && element.longitude != null) { + var lat = await sharedPref.getDouble(USER_LAT); + var long = await sharedPref.getDouble(USER_LONG); + + double distance = calculateDistance(lat, long, double.parse(element.latitude!), double.parse(element.longitude!)); + if(distance<0){ + distance *= -1; + } + if(regionDoctorList!.distance>distance){ + regionDoctorList!.distance = distance; + } + print("the distance is $distance"); + } + targetList?.add(newAppointment); + } + + + + + regionDoctorList?.hmcSize = regionDoctorList.hmcDoctorList?.length ?? 0; + regionDoctorList?.hmgSize = regionDoctorList.hmgDoctorList?.length ?? 0; + + regionList.registeredDoctorMap?[element.region!] = regionDoctorList; + } - doctorList.forEach((element) { - var regionDoctorList = regionList.registeredDoctorMap?[element.region]; - regionDoctorList ??= PatientDoctorAppointmentListByRegion(); - List doctorByHospital = []; - if(element.isHMC == true ){ - doctorByHospital = regionDoctorList.hmcDoctorList?.where((elementClinic) => elementClinic.filterName == element.getProjectCompleteName()).toList() ?? []; - }else{ - doctorByHospital = regionDoctorList.hmcDoctorList?.where((elementClinic) => elementClinic.filterName == element.getProjectCompleteName()).toList() ?? []; - } - - if(doctorByHospital.isNotEmpty){ - doctorByHospital.first.patientDoctorAppointmentList?.add(element); - }else{ - doctorByHospital.add( - PatientDoctorAppointmentList( - filterName: element.getProjectCompleteName(), - distanceInKMs: element.projectDistanceInKiloMeters.toString(), - projectTopName: element.projectTopName, - projectBottomName: element.projectBottomName, - patientDoctorAppointment: element) - ); - } - - if(element.isHMC == true ){ - regionDoctorList.hmcDoctorList = doctorByHospital; - }else{ - regionDoctorList.hmgDoctorList = doctorByHospital; - } - - regionList.registeredDoctorMap?[element.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 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? keys = unsorted.registeredDoctorMap?.keys.toList(); + keys?.sort(); + + if (keys == null) return unsorted; + Map sortedMap = {}; + for (var key in keys) { + sortedMap[key] = unsorted.registeredDoctorMap![key]!; + } + unsorted.registeredDoctorMap = sortedMap; + return unsorted; + } } \ No newline at end of file diff --git a/lib/services/appointment_services/mock_doctor_response.dart b/lib/services/appointment_services/mock_doctor_response.dart index 8900f340..a661d5c8 100644 --- a/lib/services/appointment_services/mock_doctor_response.dart +++ b/lib/services/appointment_services/mock_doctor_response.dart @@ -8026,4 +8026,4 @@ var response = { -var region = ['A','B','C','D','E']; \ No newline at end of file +var region = ['UAE Region','Eastern Region','Central Region','Western Region',]; \ No newline at end of file diff --git a/lib/uitl/location_util.dart b/lib/uitl/location_util.dart index 90119490..e0ecc8e3 100644 --- a/lib/uitl/location_util.dart +++ b/lib/uitl/location_util.dart @@ -75,6 +75,29 @@ class LocationUtils { } } + Future checkIfGPSIsEnabled() async { + if (Platform.isAndroid && isHuawei) { + FusedLocationProviderClient locationService = + FusedLocationProviderClient(); + LocationRequest locationRequest = LocationRequest(); + locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY; + locationRequest.interval = 1000; + List locationRequestList = [ + locationRequest + ]; + LocationSettingsRequest locationSettingsRequest = + LocationSettingsRequest(requests: locationRequestList); + bool success = false; + locationService + .checkLocationSettings(locationSettingsRequest) + .then((settings) { + success = true; + }); + return success; + } + return await Geolocator.isLocationServiceEnabled(); + } + Future _handlePermission() async { bool serviceEnabled; LocationPermission permission; diff --git a/lib/widgets/others/app_expandable_notifier.dart b/lib/widgets/others/app_expandable_notifier.dart index 2c4168c3..2054f969 100644 --- a/lib/widgets/others/app_expandable_notifier.dart +++ b/lib/widgets/others/app_expandable_notifier.dart @@ -89,7 +89,7 @@ class _AppExpandableNotifier extends State { color: widget.widgetColor != null ? widget.widgetColor : Colors.white, child: Column( children: [ - if(widget.showDropDownIconWithCustomHeader == false) + if(widget.showDropDownIconWithCustomHeader == false && widget.headerWidget != null) ...{ SizedBox( child: widget.headerWidget, ),}, @@ -116,12 +116,13 @@ class _AppExpandableNotifier extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if(widget.showDropDownIconWithCustomHeader) + if(widget.showDropDownIconWithCustomHeader && widget.headerWidget != null) ...{ Expanded( child: SizedBox( child: widget.headerWidget, - ))} else + ))} + else ...{ //todo use the custom header to show the drop down Expanded(