Merge branch 'master' into haroon_dev
# Conflicts: # lib/core/dependencies.dart # lib/features/emergency_services/emergency_services_repo.dart # lib/features/emergency_services/emergency_services_view_model.dart # lib/presentation/emergency_services/emergency_services_page.dartpull/85/head
						commit
						1c3ed8f2e1
					
				| @ -0,0 +1,3 @@ | ||||
| <svg width="14" height="15" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
|     <path fill-rule="evenodd" clip-rule="evenodd" d="M6.99996 1.22925C3.53667 1.22925 0.729126 4.0368 0.729126 7.50008C0.729126 10.9634 3.53667 13.7709 6.99996 13.7709C10.4632 13.7709 13.2708 10.9634 13.2708 7.50008C13.2708 4.0368 10.4632 1.22925 6.99996 1.22925ZM9.74577 5.57923C9.97358 5.35142 9.97358 4.98207 9.74577 4.75427C9.51797 4.52646 9.14862 4.52646 8.92081 4.75427L7 6.67509L5.95409 5.62925C5.72628 5.40146 5.35693 5.40147 5.12913 5.62928C4.90133 5.8571 4.90135 6.22644 5.12916 6.45424L6.17504 7.50004L6.00415 7.67094C5.77634 7.89874 5.77634 8.26809 6.00415 8.49589C6.23195 8.7237 6.6013 8.7237 6.8291 8.49589L7.00002 8.32497L7.17076 8.49569C7.39857 8.72349 7.76792 8.72348 7.99571 8.49567C8.22351 8.26785 8.2235 7.89851 7.99569 7.67071L7.82498 7.50002L9.74577 5.57923Z" fill="#2E3039"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 902 B | 
| @ -0,0 +1,19 @@ | ||||
| import 'dart:async'; | ||||
| import 'dart:ui'; | ||||
| 
 | ||||
| class Debouncer { | ||||
|   final int milliseconds; | ||||
|   VoidCallback? action; | ||||
|   Timer? _timer; | ||||
| 
 | ||||
|   Debouncer({required this.milliseconds}); | ||||
| 
 | ||||
|   void run(VoidCallback action) { | ||||
|     _timer?.cancel(); | ||||
|     _timer = Timer(Duration(milliseconds: milliseconds), action); | ||||
|   } | ||||
| 
 | ||||
|   void dispose() { | ||||
|     _timer?.cancel(); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,114 @@ | ||||
| class ProjectAvgERWaitingTime { | ||||
|   int? iD; | ||||
|   int? projectID; | ||||
|   int? avgTimeInMinutes; | ||||
|   String? avgTimeInHHMM; | ||||
|   dynamic distanceInKilometers; | ||||
|   String? latitude; | ||||
|   String? longitude; | ||||
|   String? phonenumber; | ||||
|   String? projectImageURL; | ||||
|   String? projectName; | ||||
| 
 | ||||
|   ProjectAvgERWaitingTime( | ||||
|       {this.iD, | ||||
|         this.projectID, | ||||
|         this.avgTimeInMinutes, | ||||
|         this.avgTimeInHHMM, | ||||
|         this.distanceInKilometers, | ||||
|         this.latitude, | ||||
|         this.longitude, | ||||
|         this.phonenumber, | ||||
|         this.projectImageURL, | ||||
|         this.projectName}); | ||||
| 
 | ||||
|   ProjectAvgERWaitingTime.fromJson(Map<String, dynamic> json) { | ||||
|     iD = json['ID']; | ||||
|     projectID = json['ProjectID']; | ||||
|     avgTimeInMinutes = json['AvgTimeInMinutes']; | ||||
|     avgTimeInHHMM = json['AvgTimeInHHMM']; | ||||
|     distanceInKilometers = json['DistanceInKilometers']; | ||||
|     latitude = json['Latitude']; | ||||
|     longitude = json['Longitude']; | ||||
|     phonenumber = json['PhoneNumber']; | ||||
|     projectImageURL = json['ProjectImageURL']; | ||||
|     projectName = json['ProjectName']; | ||||
|   } | ||||
| 
 | ||||
|   String getTime(){ | ||||
|     print("the name is $projectName"); | ||||
|     print("the avgTimeInMinutes is $avgTimeInMinutes"); | ||||
|     if(avgTimeInMinutes == null) return ""; | ||||
|     int hours = avgTimeInMinutes! ~/ 60; | ||||
|     int minutes = avgTimeInMinutes! % 60; | ||||
|     print("the time is ${"${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}"}"); | ||||
|     return "${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}"; | ||||
|   } | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() { | ||||
|     final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||
|     data['ID'] = this.iD; | ||||
|     data['ProjectID'] = this.projectID; | ||||
|     data['AvgTimeInMinutes'] = this.avgTimeInMinutes; | ||||
|     data['AvgTimeInHHMM'] = this.avgTimeInHHMM; | ||||
|     data['DistanceInKilometers'] = this.distanceInKilometers; | ||||
|     data['Latitude'] = this.latitude; | ||||
|     data['Longitude'] = this.longitude; | ||||
|     data['PhoneNumber'] = this.phonenumber; | ||||
|     data['ProjectImageURL'] = this.projectImageURL; | ||||
|     data['ProjectName'] = this.projectName; | ||||
|     return data; | ||||
|   } | ||||
| } | ||||
| //class ProjectAvgERWaitingTime { | ||||
| //  int? iD; | ||||
| //  int? projectID; | ||||
| //  int? avgTimeInMinutes; | ||||
| //  String? avgTimeInHHMM; | ||||
| //  String? distanceInKilometers; | ||||
| //  String? latitude; | ||||
| //  String? longitude; | ||||
| //  String? phonenum?ber; | ||||
| //  String? projectImageURL; | ||||
| //  String? projectName; | ||||
| // | ||||
| //  ProjectAvgERWaitingTime( | ||||
| //      {this.iD, | ||||
| //        this.projectID, | ||||
| //        this.avgTimeInMinutes, | ||||
| //        this.avgTimeInHHMM, | ||||
| //        this.distanceInKilometers, | ||||
| //        this.latitude, | ||||
| //        this.longitude, | ||||
| //        this.phonenum?ber, | ||||
| //        this.projectImageURL, | ||||
| //        this.projectName}); | ||||
| // | ||||
| //  ProjectAvgERWaitingTime.fromJson(Map<String, dynamic> json) { | ||||
| //    iD = json['ID']; | ||||
| //    projectID = json['ProjectID']; | ||||
| //    avgTimeInMinutes = json['AvgTimeInMinutes']; | ||||
| //    avgTimeInHHMM = json['AvgTimeInHHMM']; | ||||
| //    distanceInKilometers = json['DistanceInKilometers']; | ||||
| //    latitude = json['Latitude']; | ||||
| //    longitude = json['Longitude']; | ||||
| //    phonenum?ber = json['Phonenum?ber']; | ||||
| //    projectImageURL = json['ProjectImageURL']; | ||||
| //    projectName = json['ProjectName']; | ||||
| //  } | ||||
| // | ||||
| //  Map<String, dynamic> toJson() { | ||||
| //    final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||
| //    data['ID'] = this.iD; | ||||
| //    data['ProjectID'] = this.projectID; | ||||
| //    data['AvgTimeInMinutes'] = this.avgTimeInMinutes; | ||||
| //    data['AvgTimeInHHMM'] = this.avgTimeInHHMM; | ||||
| //    data['DistanceInKilometers'] = this.distanceInKilometers; | ||||
| //    data['Latitude'] = this.latitude; | ||||
| //    data['Longitude'] = this.longitude; | ||||
| //    data['Phonenum?ber'] = this.phonenum?ber; | ||||
| //    data['ProjectImageURL'] = this.projectImageURL; | ||||
| //    data['ProjectName'] = this.projectName; | ||||
| //    return data; | ||||
| //  } | ||||
| //} | ||||
| @ -0,0 +1,130 @@ | ||||
| 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/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/model/resp_model/ProjectAvgERWaitingTime.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:provider/provider.dart'; | ||||
| 
 | ||||
| class NearestERItem extends StatelessWidget { | ||||
|   final ProjectAvgERWaitingTime nearestERItem; | ||||
|   final bool isLoading; | ||||
| 
 | ||||
| 
 | ||||
|   const NearestERItem({ super.key, | ||||
|     required this.nearestERItem, | ||||
|     required this.isLoading | ||||
|   }) ; | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Container( | ||||
|       decoration: RoundedRectangleBorder().toSmoothCornerDecoration( | ||||
|         color: Colors.white, | ||||
|         customBorder: BorderRadius.only( | ||||
|           topLeft: Radius.circular(24.h), | ||||
|           topRight: Radius.circular(24.h), | ||||
|         ), | ||||
|       ), | ||||
|       child: Padding( | ||||
|         padding: EdgeInsets.all(16.h), | ||||
|         child: Column( | ||||
|           crossAxisAlignment: CrossAxisAlignment.start, | ||||
|           children: [ | ||||
|             Row( | ||||
|               children: [ | ||||
|                 (isLoading || nearestERItem.projectImageURL?.isEmpty == true) | ||||
|                     ? Container( | ||||
|                   width: 24.h, | ||||
|                   height: 24.h, | ||||
|                   decoration: BoxDecoration( | ||||
|                     color: Colors.grey.shade300, | ||||
|                     shape: BoxShape.circle, | ||||
|                   ), | ||||
|                 ).toShimmer2(isShow: isLoading) | ||||
|                     : Utils.buildImgWithNetwork( | ||||
|                   url: nearestERItem.projectImageURL ?? '', | ||||
|                   iconColor: Colors.transparent, | ||||
|                 ).circle(24.h).toShimmer2(isShow: isLoading), | ||||
|                 const SizedBox(width: 12), | ||||
|                 Expanded( | ||||
|                   child: (nearestERItem.projectName?.toText16( | ||||
|                     color: AppColors.textColor, | ||||
|                     weight: FontWeight.w600, | ||||
|                   ) ?? | ||||
|                       SizedBox.shrink()).toShimmer2(isShow: isLoading), | ||||
|                 ), | ||||
|                 // TODO: Add hospital icon logic here if needed | ||||
|               ], | ||||
|             ), | ||||
|             SizedBox(height: 8.h), | ||||
|             Row( | ||||
|               spacing: 8.h, | ||||
|               children: [ | ||||
|                 AppCustomChipWidget( | ||||
|                   labelText: "${nearestERItem.distanceInKilometers} km".needTranslation, | ||||
|                   icon: AppAssets.location, | ||||
|                   iconHasColor: false, | ||||
|                   labelPadding: EdgeInsetsDirectional.only(start: 4.h, end: 0.h), | ||||
|                   padding: EdgeInsets.all(8.h), | ||||
|                 ).toShimmer2(isShow: isLoading), | ||||
|                 AppCustomChipWidget( | ||||
|                   labelText: "Expected waiting time: ${nearestERItem.getTime()} mins".needTranslation, | ||||
|                   icon: AppAssets.waiting_time_clock, | ||||
|                   iconHasColor: false, | ||||
|                   labelPadding: EdgeInsetsDirectional.only(start: 4.h, end: 0.h), | ||||
|                   padding: EdgeInsets.all(8.h), | ||||
|                 ).toShimmer2(isShow: isLoading), | ||||
|               ], | ||||
|             ), | ||||
|             SizedBox(height: 16.h), | ||||
|             Row( | ||||
|               children: [ | ||||
|                 Expanded( | ||||
|                   child: CustomButton( | ||||
|                     text: "View Location on Google Maps".needTranslation, | ||||
|                     iconSize: 18.h, | ||||
|                     icon: AppAssets.location, | ||||
|                     onPressed: () { | ||||
|                       context.read<EmergencyServicesViewModel>().openDirections(destLat:  double.parse(nearestERItem.latitude??"0.0"), destLng: double.parse(nearestERItem.longitude??"0.0") ); | ||||
|                     }, | ||||
|                     backgroundColor: AppColors.secondaryLightRedColor, | ||||
|                     borderColor: AppColors.secondaryLightRedColor, | ||||
|                     textColor: AppColors.primaryRedColor, | ||||
|                     iconColor: AppColors.primaryRedColor, | ||||
|                     height: 40.h, | ||||
|                     fontSize: 14, | ||||
|                     fontWeight: FontWeight.w500, | ||||
|                   ).toShimmer2(isShow: isLoading), | ||||
|                 ), | ||||
|                 SizedBox(width: 8.h), | ||||
|                 SizedBox( | ||||
|                   height: 40.h, | ||||
|                   width: 40.h, | ||||
|                   child: CustomButton( | ||||
|                     text: '', | ||||
|                     iconSize: 18.h, | ||||
|                     icon: AppAssets.call_fill, | ||||
|                     onPressed: () { | ||||
|                       context.read<EmergencyServicesViewModel>().openDialer( nearestERItem.phonenumber??""); | ||||
| 
 | ||||
|                     }, | ||||
|                     backgroundColor: AppColors.greyColor, | ||||
|                     iconColor: AppColors.textColor, | ||||
|                     borderColor: AppColors.greyColor, | ||||
|                     height: 40.h, | ||||
|                   ).toShimmer2(isShow: isLoading), | ||||
|                 ), | ||||
|               ], | ||||
|             ), | ||||
|           ], | ||||
|         ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
					Loading…
					
					
				
		Reference in New Issue