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