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