Merge branch 'master' of http://34.17.182.140/Haroon6138/HMG_Patient_App_New into dev_sultan
# Conflicts: # lib/core/api_consts.dart # lib/features/hmg_services/hmg_services_repo.dart # lib/features/hmg_services/hmg_services_view_model.dart # lib/presentation/emergency_services/call_ambulance/widgets/pickup_location.dartpull/104/head
commit
5f047e1b6f
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 543 KiB |
@ -0,0 +1,5 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.49411 2.85661C9.06887 2.71829 8.56575 2.71849 7.82926 2.71878L5.20973 2.7188C4.36011 2.71878 3.66581 2.71877 3.11767 2.79255C2.5447 2.86967 2.04795 3.03656 1.65143 3.43352C1.25491 3.83049 1.0882 4.32779 1.01117 4.90139C0.93747 5.45014 0.937484 6.14521 0.9375 6.99576V10.0798C0.937484 10.9303 0.93747 11.6254 1.01117 12.1741C1.0882 12.7477 1.25491 13.245 1.65143 13.642C1.76583 13.7565 1.89283 13.8531 2.02893 13.9345C2.22063 14.0492 2.31647 14.1065 2.39389 14.059C2.47131 14.0115 2.46224 13.8786 2.44411 13.6127C2.43973 13.5484 2.4375 13.4836 2.4375 13.4181C2.4375 11.8631 3.6967 10.6025 5.25 10.6025C6.8033 10.6025 8.0625 11.8631 8.0625 13.4181C8.0625 13.5947 8.04626 13.7675 8.01519 13.9351C7.97875 14.1317 7.96053 14.23 8.00499 14.2841C8.04945 14.3381 8.14092 14.3389 8.32387 14.3406C8.77449 14.3448 9.22551 14.3448 9.67614 14.3406C9.85908 14.3389 9.95055 14.3381 9.99501 14.2841C10.0395 14.23 10.0213 14.1317 9.98481 13.9351C9.95374 13.7675 9.9375 13.5947 9.9375 13.4181C9.9375 11.8631 11.1967 10.6025 12.75 10.6025C14.3033 10.6025 15.5625 11.8631 15.5625 13.4181C15.5625 13.4835 15.5603 13.5484 15.5559 13.6127C15.5378 13.8786 15.5287 14.0115 15.6061 14.059C15.6835 14.1065 15.7794 14.0492 15.9711 13.9345C16.1072 13.8531 16.2342 13.7565 16.3486 13.642C16.7451 13.245 16.9118 12.7477 16.9888 12.1741C17.0625 11.6254 17.0625 10.9303 17.0625 10.0798V8.55433C17.0654 8.4286 17.0367 8.30042 16.9729 8.18177L15.9988 6.37069C15.7544 5.91626 15.5451 5.52708 15.3388 5.22173C15.1184 4.89536 14.8689 4.61351 14.5195 4.40455C14.17 4.19558 13.8038 4.10932 13.4123 4.06973C13.046 4.0327 12.6044 4.03272 12.0889 4.03274L11.2524 4.03274C11.1353 4.03274 11.0767 4.03274 11.0295 4.00933C10.9823 3.98592 10.9424 3.93349 10.8626 3.82864C10.5202 3.37853 10.0455 3.03597 9.49411 2.85661ZM11.7406 5.53441C11.5945 5.53441 11.5214 5.53441 11.4773 5.57901C11.4333 5.62362 11.4342 5.69802 11.4359 5.84684C11.4377 5.99664 11.4376 6.15736 11.4375 6.33106C11.4375 6.93389 11.4444 7.20613 11.4834 7.32612C11.5761 7.61185 11.7999 7.83587 12.0853 7.92871C12.2052 7.96769 12.3728 7.97464 12.975 7.97464H14.6556C14.8798 7.97464 14.9919 7.97464 15.0355 7.90148C15.0792 7.82832 15.026 7.72952 14.9197 7.53192L14.6949 7.11386C14.429 6.61959 14.2551 6.29803 14.0963 6.06291C13.9469 5.84183 13.845 5.75037 13.7503 5.69375C13.6556 5.63714 13.5268 5.59062 13.2616 5.5638C12.9795 5.53529 12.6142 5.53441 12.0535 5.53441H11.7406ZM4.5001 5.53125C4.91431 5.53125 5.2501 5.86704 5.2501 6.28125V7.78125C5.2501 8.19546 4.91431 8.53125 4.5001 8.53125C4.08589 8.53125 3.7501 8.19546 3.7501 7.78125V6.28125C3.7501 5.86704 4.08589 5.53125 4.5001 5.53125ZM7.5001 5.53125C7.91431 5.53125 8.2501 5.86704 8.2501 6.28125V7.78125C8.2501 8.19546 7.91431 8.53125 7.5001 8.53125C7.08589 8.53125 6.7501 8.19546 6.7501 7.78125V6.28125C6.7501 5.86704 7.08589 5.53125 7.5001 5.53125Z" fill="#2E3039"/>
|
||||
<path d="M5.25 11.5312C4.21447 11.5312 3.375 12.3707 3.375 13.4062C3.375 14.4418 4.21447 15.2812 5.25 15.2812C6.28553 15.2812 7.125 14.4418 7.125 13.4062C7.125 12.3707 6.28553 11.5312 5.25 11.5312Z" fill="#2E3039"/>
|
||||
<path d="M12.75 11.5312C11.7145 11.5312 10.875 12.3707 10.875 13.4062C10.875 14.4418 11.7145 15.2812 12.75 15.2812C13.7855 15.2812 14.625 14.4418 14.625 13.4062C14.625 12.3707 13.7855 11.5312 12.75 11.5312Z" fill="#2E3039"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 10 KiB |
@ -0,0 +1,11 @@
|
||||
class FeedbackType {
|
||||
final int id;
|
||||
final String nameEN;
|
||||
final String nameAR;
|
||||
|
||||
FeedbackType({
|
||||
required this.id,
|
||||
required this.nameEN,
|
||||
required this.nameAR,
|
||||
});
|
||||
}
|
||||
@ -0,0 +1,137 @@
|
||||
class RequestInsertCOCItem {
|
||||
bool? isUserLoggedIn;
|
||||
String? mobileNo;
|
||||
int? identificationNo;
|
||||
int? patientID;
|
||||
int? patientOutSA;
|
||||
int? patientTypeID;
|
||||
String? tokenID;
|
||||
String? patientName;
|
||||
int? projectID;
|
||||
String? fileName;
|
||||
String? attachment;
|
||||
String? uILanguage;
|
||||
String? browserInfo;
|
||||
String? cOCTypeName;
|
||||
String? formTypeID;
|
||||
String? details;
|
||||
String? deviceInfo;
|
||||
String? deviceType;
|
||||
String? title;
|
||||
String? resolution;
|
||||
double? versionID;
|
||||
int? channel;
|
||||
int? languageID;
|
||||
String? iPAdress;
|
||||
String? generalid;
|
||||
String? sessionID;
|
||||
bool? isDentalAllowedBackend;
|
||||
int? deviceTypeID;
|
||||
int? patientType;
|
||||
double? appVersion;
|
||||
bool? forDemo;
|
||||
|
||||
RequestInsertCOCItem(
|
||||
{this.isUserLoggedIn,
|
||||
this.mobileNo,
|
||||
this.identificationNo,
|
||||
this.patientID,
|
||||
this.patientOutSA,
|
||||
this.patientTypeID,
|
||||
this.tokenID,
|
||||
this.patientName,
|
||||
this.projectID,
|
||||
this.fileName,
|
||||
this.attachment,
|
||||
this.uILanguage,
|
||||
this.browserInfo,
|
||||
this.cOCTypeName,
|
||||
this.formTypeID,
|
||||
this.details,
|
||||
this.deviceInfo,
|
||||
this.deviceType,
|
||||
this.title,
|
||||
this.resolution,
|
||||
this.versionID,
|
||||
this.channel,
|
||||
this.languageID,
|
||||
this.iPAdress,
|
||||
this.generalid,
|
||||
this.sessionID,
|
||||
this.isDentalAllowedBackend,
|
||||
this.deviceTypeID,
|
||||
this.patientType,
|
||||
this.appVersion,
|
||||
this.forDemo});
|
||||
|
||||
RequestInsertCOCItem.fromJson(Map<String, dynamic> json) {
|
||||
isUserLoggedIn = json['IsUserLoggedIn'];
|
||||
mobileNo = json['MobileNo'];
|
||||
identificationNo = json['IdentificationNo'];
|
||||
patientID = json['PatientID'];
|
||||
patientOutSA = json['PatientOutSA'];
|
||||
patientTypeID = json['PatientTypeID'];
|
||||
tokenID = json['TokenID'];
|
||||
patientName = json['PatientName'];
|
||||
projectID = json['ProjectID'];
|
||||
fileName = json['FileName'];
|
||||
attachment = json['Attachment'];
|
||||
uILanguage = json['UILanguage'];
|
||||
browserInfo = json['BrowserInfo'];
|
||||
cOCTypeName = json['COCTypeName'];
|
||||
formTypeID = json['FormTypeID'];
|
||||
details = json['Details'];
|
||||
deviceInfo = json['DeviceInfo'];
|
||||
deviceType = json['DeviceType'];
|
||||
title = json['Title'];
|
||||
resolution = json['Resolution'];
|
||||
versionID = json['VersionID'];
|
||||
channel = json['Channel'];
|
||||
languageID = json['LanguageID'];
|
||||
iPAdress = json['IPAdress'];
|
||||
generalid = json['generalid'];
|
||||
sessionID = json['SessionID'];
|
||||
isDentalAllowedBackend = json['isDentalAllowedBackend'];
|
||||
deviceTypeID = json['DeviceTypeID'];
|
||||
patientType = json['PatientType'];
|
||||
appVersion = json['AppVersion'];
|
||||
forDemo = json['ForDemo'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['IsUserLoggedIn'] = this.isUserLoggedIn;
|
||||
data['MobileNo'] = this.mobileNo;
|
||||
data['IdentificationNo'] = this.identificationNo;
|
||||
data['PatientID'] = this.patientID;
|
||||
data['PatientOutSA'] = this.patientOutSA;
|
||||
data['PatientTypeID'] = this.patientTypeID;
|
||||
data['TokenID'] = this.tokenID;
|
||||
data['PatientName'] = this.patientName;
|
||||
data['ProjectID'] = this.projectID;
|
||||
data['FileName'] = this.fileName;
|
||||
data['Attachment'] = this.attachment;
|
||||
data['UILanguage'] = this.uILanguage;
|
||||
data['BrowserInfo'] = this.browserInfo;
|
||||
data['COCTypeName'] = this.cOCTypeName;
|
||||
data['FormTypeID'] = this.formTypeID;
|
||||
data['Details'] = this.details;
|
||||
data['DeviceInfo'] = this.deviceInfo;
|
||||
data['DeviceType'] = this.deviceType;
|
||||
data['Title'] = this.title;
|
||||
data['Resolution'] = this.resolution;
|
||||
data['VersionID'] = this.versionID;
|
||||
data['Channel'] = this.channel;
|
||||
data['LanguageID'] = this.languageID;
|
||||
data['IPAdress'] = this.iPAdress;
|
||||
data['generalid'] = this.generalid;
|
||||
data['SessionID'] = this.sessionID;
|
||||
data['isDentalAllowedBackend'] = this.isDentalAllowedBackend;
|
||||
data['DeviceTypeID'] = this.deviceTypeID;
|
||||
data['PatientType'] = this.patientType;
|
||||
data['AppVersion'] = this.appVersion;
|
||||
data['ForDemo'] = this.forDemo;
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
enum OrderDislpay{
|
||||
ALL,RRT,AMBULANCE
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
class RRTRequestModel {
|
||||
num? patientId;
|
||||
int? patientOutSa;
|
||||
bool? isOutPatient;
|
||||
int? nearestProjectId;
|
||||
num? longitude;
|
||||
num? latitude;
|
||||
String? additionalDetails;
|
||||
String? nationality;
|
||||
num? paymentAmount;
|
||||
List<Procedures>? procedures;
|
||||
|
||||
RRTRequestModel(
|
||||
{this.patientId,
|
||||
this.patientOutSa,
|
||||
this.isOutPatient,
|
||||
this.nearestProjectId,
|
||||
this.longitude,
|
||||
this.latitude,
|
||||
this.additionalDetails,
|
||||
this.nationality,
|
||||
this.paymentAmount,
|
||||
this.procedures});
|
||||
|
||||
RRTRequestModel.fromJson(Map<String, dynamic> json) {
|
||||
patientId = json['patientId'];
|
||||
patientOutSa = json['patientOutSa'];
|
||||
isOutPatient = json['isOutPatient'];
|
||||
nearestProjectId = json['nearestProjectId'];
|
||||
longitude = json['longitude'];
|
||||
latitude = json['latitude'];
|
||||
additionalDetails = json['additionalDetails'];
|
||||
nationality = json['nationality'];
|
||||
paymentAmount = json['paymentAmount'];
|
||||
if (json['procedures'] != null) {
|
||||
procedures = <Procedures>[];
|
||||
json['procedures'].forEach((v) {
|
||||
procedures!.add(new Procedures.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['patientId'] = this.patientId;
|
||||
data['patientOutSa'] = this.patientOutSa;
|
||||
data['isOutPatient'] = this.isOutPatient;
|
||||
data['nearestProjectId'] = this.nearestProjectId;
|
||||
data['longitude'] = this.longitude;
|
||||
data['latitude'] = this.latitude;
|
||||
data['additionalDetails'] = this.additionalDetails;
|
||||
data['nationality'] = this.nationality;
|
||||
data['paymentAmount'] = this.paymentAmount;
|
||||
if (this.procedures != null) {
|
||||
data['procedures'] = this.procedures!.map((v) => v.toJson()).toList();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class Procedures {
|
||||
String? serviceID;
|
||||
|
||||
Procedures({this.serviceID});
|
||||
|
||||
Procedures.fromJson(Map<String, dynamic> json) {
|
||||
serviceID = json['ServiceID'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['ServiceID'] = this.serviceID;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
class ServicePrice {
|
||||
String? currency;
|
||||
dynamic maxPrice;
|
||||
dynamic maxTotalPrice;
|
||||
dynamic maxVAT;
|
||||
dynamic minPrice;
|
||||
dynamic minTotalPrice;
|
||||
dynamic minVAT;
|
||||
dynamic price;
|
||||
dynamic totalPrice;
|
||||
dynamic vat;
|
||||
|
||||
ServicePrice({
|
||||
this.currency,
|
||||
this.maxPrice,
|
||||
this.maxTotalPrice,
|
||||
this.maxVAT,
|
||||
this.minPrice,
|
||||
this.minTotalPrice,
|
||||
this.minVAT,
|
||||
this.price,
|
||||
this.totalPrice,
|
||||
this.vat});
|
||||
|
||||
ServicePrice.fromJson(dynamic json) {
|
||||
currency = json["Currency"];
|
||||
maxPrice = json["MaxPrice"];
|
||||
maxTotalPrice = json["MaxTotalPrice"];
|
||||
maxVAT = json["MaxVAT"];
|
||||
minPrice = json["MinPrice"];
|
||||
minTotalPrice = json["MinTotalPrice"];
|
||||
minVAT = json["MinVAT"];
|
||||
price = json["Price"];
|
||||
totalPrice = json["TotalPrice"];
|
||||
vat = json["VAT"];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
var map = <String, dynamic>{};
|
||||
map["Currency"] = currency;
|
||||
map["MaxPrice"] = maxPrice;
|
||||
map["MaxTotalPrice"] = maxTotalPrice;
|
||||
map["MaxVAT"] = maxVAT;
|
||||
map["MinPrice"] = minPrice;
|
||||
map["MinTotalPrice"] = minTotalPrice;
|
||||
map["MinVAT"] = minVAT;
|
||||
map["Price"] = price;
|
||||
map["TotalPrice"] = totalPrice;
|
||||
map["VAT"] = vat;
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,406 @@
|
||||
class RRTServiceData {
|
||||
List<GetCMCAllOrdersResponseModel> pendingOrders = [];
|
||||
List<GetCMCAllOrdersResponseModel> completedOrders = [];
|
||||
ServicePrice servicePrice = ServicePrice();
|
||||
}
|
||||
|
||||
class GetCMCAllOrdersResponseModel {
|
||||
int? iD;
|
||||
int? patientId;
|
||||
int? patientOutSa;
|
||||
bool? isOutPatient;
|
||||
int? projectId;
|
||||
int? nearestProjectId;
|
||||
dynamic longitude;
|
||||
dynamic latitude;
|
||||
dynamic appointmentNo;
|
||||
dynamic dischargeId;
|
||||
int? statusId;
|
||||
int? serviceId;
|
||||
int? channel;
|
||||
Orderpayment? orderpayment;
|
||||
dynamic orderselectedservice;
|
||||
dynamic wforder;
|
||||
dynamic orderapprovalobj;
|
||||
String? created;
|
||||
dynamic createdBy;
|
||||
dynamic modified;
|
||||
dynamic modifiedBy;
|
||||
bool? isDeleted;
|
||||
String? statusText;
|
||||
int? paymentStatus;
|
||||
dynamic clientRequestid;
|
||||
dynamic paymentStatusText;
|
||||
String? projectName;
|
||||
String? nearestProjectName;
|
||||
dynamic paymentAmount;
|
||||
WFOrder? wFOrder;
|
||||
String? serviceText;
|
||||
bool? isSentForApproval;
|
||||
int? exaCartOrderId;
|
||||
bool? isTimer;
|
||||
int? timeSeconds;
|
||||
int? totalPendingSeconds;
|
||||
int? timeMinute;
|
||||
int? timeHour;
|
||||
int? timeTotalSeconds;
|
||||
int? timeTotalMinute;
|
||||
int? timeTotalHour;
|
||||
dynamic approvalStatus;
|
||||
bool? isActive;
|
||||
int? clickButton;
|
||||
List<dynamic>? procedures;
|
||||
dynamic pickupLocation;
|
||||
dynamic dropOffLocation;
|
||||
dynamic clinicName;
|
||||
dynamic doctorName;
|
||||
dynamic branch;
|
||||
dynamic time;
|
||||
dynamic notes;
|
||||
|
||||
GetCMCAllOrdersResponseModel(
|
||||
{this.iD,
|
||||
this.patientId,
|
||||
this.patientOutSa,
|
||||
this.isOutPatient,
|
||||
this.projectId,
|
||||
this.nearestProjectId,
|
||||
this.longitude,
|
||||
this.latitude,
|
||||
this.appointmentNo,
|
||||
this.dischargeId,
|
||||
this.statusId,
|
||||
this.serviceId,
|
||||
this.channel,
|
||||
this.orderpayment,
|
||||
this.orderselectedservice,
|
||||
this.wforder,
|
||||
this.orderapprovalobj,
|
||||
this.created,
|
||||
this.createdBy,
|
||||
this.modified,
|
||||
this.modifiedBy,
|
||||
this.isDeleted,
|
||||
this.statusText,
|
||||
this.paymentStatus,
|
||||
this.clientRequestid,
|
||||
this.paymentStatusText,
|
||||
this.projectName,
|
||||
this.nearestProjectName,
|
||||
this.paymentAmount,
|
||||
this.wFOrder,
|
||||
this.serviceText,
|
||||
this.isSentForApproval,
|
||||
this.exaCartOrderId,
|
||||
this.isTimer,
|
||||
this.timeSeconds,
|
||||
this.totalPendingSeconds,
|
||||
this.timeMinute,
|
||||
this.timeHour,
|
||||
this.timeTotalSeconds,
|
||||
this.timeTotalMinute,
|
||||
this.timeTotalHour,
|
||||
this.approvalStatus,
|
||||
this.isActive,
|
||||
this.clickButton,
|
||||
this.procedures,
|
||||
this.pickupLocation,
|
||||
this.dropOffLocation,
|
||||
this.clinicName,
|
||||
this.doctorName,
|
||||
this.branch,
|
||||
this.time,
|
||||
this.notes});
|
||||
|
||||
GetCMCAllOrdersResponseModel.fromJson(Map<String, dynamic> json) {
|
||||
iD = json['ID'];
|
||||
patientId = json['PatientId'];
|
||||
patientOutSa = json['PatientOutSa'];
|
||||
isOutPatient = json['IsOutPatient'];
|
||||
projectId = json['ProjectId'];
|
||||
nearestProjectId = json['NearestProjectId'];
|
||||
longitude = json['Longitude'];
|
||||
latitude = json['Latitude'];
|
||||
appointmentNo = json['AppointmentNo'];
|
||||
dischargeId = json['DischargeId'];
|
||||
statusId = json['StatusId'];
|
||||
serviceId = json['ServiceId'];
|
||||
channel = json['Channel'];
|
||||
orderpayment = json['orderpayment'] != null
|
||||
? new Orderpayment.fromJson(json['orderpayment'])
|
||||
: null;
|
||||
orderselectedservice = json['orderselectedservice'];
|
||||
wforder = json['wforder'];
|
||||
orderapprovalobj = json['orderapprovalobj'];
|
||||
created = json['Created'];
|
||||
createdBy = json['CreatedBy'];
|
||||
modified = json['Modified'];
|
||||
modifiedBy = json['ModifiedBy'];
|
||||
isDeleted = json['IsDeleted'];
|
||||
statusText = json['StatusText'];
|
||||
paymentStatus = json['PaymentStatus'];
|
||||
clientRequestid = json['ClientRequestid'];
|
||||
paymentStatusText = json['PaymentStatusText'];
|
||||
projectName = json['ProjectName'];
|
||||
nearestProjectName = json['NearestProjectName'];
|
||||
paymentAmount = json['PaymentAmount'];
|
||||
wFOrder = json['WF_order'] != null
|
||||
? new WFOrder.fromJson(json['WF_order'])
|
||||
: null;
|
||||
serviceText = json['ServiceText'];
|
||||
isSentForApproval = json['isSentForApproval'];
|
||||
exaCartOrderId = json['ExaCart_OrderId'];
|
||||
isTimer = json['isTimer'];
|
||||
timeSeconds = json['TimeSeconds'];
|
||||
totalPendingSeconds = json['TotalPendingSeconds'];
|
||||
timeMinute = json['TimeMinute'];
|
||||
timeHour = json['TimeHour'];
|
||||
timeTotalSeconds = json['TimeTotalSeconds'];
|
||||
timeTotalMinute = json['TimeTotalMinute'];
|
||||
timeTotalHour = json['TimeTotalHour'];
|
||||
approvalStatus = json['ApprovalStatus'];
|
||||
isActive = json['isActive'];
|
||||
clickButton = json['ClickButton'];
|
||||
pickupLocation = json['PickupLocation'];
|
||||
dropOffLocation = json['DropOffLocation'];
|
||||
clinicName = json['clinicName'];
|
||||
doctorName = json['DoctorName'];
|
||||
branch = json['Branch'];
|
||||
time = json['Time'];
|
||||
notes = json['Notes'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['ID'] = this.iD;
|
||||
data['PatientId'] = this.patientId;
|
||||
data['PatientOutSa'] = this.patientOutSa;
|
||||
data['IsOutPatient'] = this.isOutPatient;
|
||||
data['ProjectId'] = this.projectId;
|
||||
data['NearestProjectId'] = this.nearestProjectId;
|
||||
data['Longitude'] = this.longitude;
|
||||
data['Latitude'] = this.latitude;
|
||||
data['AppointmentNo'] = this.appointmentNo;
|
||||
data['DischargeId'] = this.dischargeId;
|
||||
data['StatusId'] = this.statusId;
|
||||
data['ServiceId'] = this.serviceId;
|
||||
data['Channel'] = this.channel;
|
||||
if (this.orderpayment != null) {
|
||||
data['orderpayment'] = this.orderpayment!.toJson();
|
||||
}
|
||||
data['orderselectedservice'] = this.orderselectedservice;
|
||||
|
||||
data['wforder'] = this.wforder;
|
||||
data['orderapprovalobj'] = this.orderapprovalobj;
|
||||
data['Created'] = this.created;
|
||||
data['CreatedBy'] = this.createdBy;
|
||||
data['Modified'] = this.modified;
|
||||
data['ModifiedBy'] = this.modifiedBy;
|
||||
data['IsDeleted'] = this.isDeleted;
|
||||
data['StatusText'] = this.statusText;
|
||||
data['PaymentStatus'] = this.paymentStatus;
|
||||
data['ClientRequestid'] = this.clientRequestid;
|
||||
data['PaymentStatusText'] = this.paymentStatusText;
|
||||
data['ProjectName'] = this.projectName;
|
||||
data['NearestProjectName'] = this.nearestProjectName;
|
||||
data['PaymentAmount'] = this.paymentAmount;
|
||||
if (this.wFOrder != null) {
|
||||
data['WF_order'] = this.wFOrder!.toJson();
|
||||
}
|
||||
data['ServiceText'] = this.serviceText;
|
||||
data['isSentForApproval'] = this.isSentForApproval;
|
||||
data['ExaCart_OrderId'] = this.exaCartOrderId;
|
||||
data['isTimer'] = this.isTimer;
|
||||
data['TimeSeconds'] = this.timeSeconds;
|
||||
data['TotalPendingSeconds'] = this.totalPendingSeconds;
|
||||
data['TimeMinute'] = this.timeMinute;
|
||||
data['TimeHour'] = this.timeHour;
|
||||
data['TimeTotalSeconds'] = this.timeTotalSeconds;
|
||||
data['TimeTotalMinute'] = this.timeTotalMinute;
|
||||
data['TimeTotalHour'] = this.timeTotalHour;
|
||||
data['ApprovalStatus'] = this.approvalStatus;
|
||||
data['isActive'] = this.isActive;
|
||||
data['ClickButton'] = this.clickButton;
|
||||
data['PickupLocation'] = this.pickupLocation;
|
||||
data['DropOffLocation'] = this.dropOffLocation;
|
||||
data['clinicName'] = this.clinicName;
|
||||
data['DoctorName'] = this.doctorName;
|
||||
data['Branch'] = this.branch;
|
||||
data['Time'] = this.time;
|
||||
data['Notes'] = this.notes;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class Orderpayment {
|
||||
int? iD;
|
||||
int? orderId;
|
||||
dynamic clientRequestId;
|
||||
dynamic totalAmount;
|
||||
int? paymentStatus;
|
||||
dynamic order;
|
||||
String? created;
|
||||
dynamic createdBy;
|
||||
dynamic modified;
|
||||
dynamic modifiedBy;
|
||||
bool? isDeleted;
|
||||
|
||||
Orderpayment(
|
||||
{this.iD,
|
||||
this.orderId,
|
||||
this.clientRequestId,
|
||||
this.totalAmount,
|
||||
this.paymentStatus,
|
||||
this.order,
|
||||
this.created,
|
||||
this.createdBy,
|
||||
this.modified,
|
||||
this.modifiedBy,
|
||||
this.isDeleted});
|
||||
|
||||
Orderpayment.fromJson(Map<String, dynamic> json) {
|
||||
iD = json['ID'];
|
||||
orderId = json['OrderId'];
|
||||
clientRequestId = json['ClientRequestId'];
|
||||
totalAmount = json['TotalAmount'];
|
||||
paymentStatus = json['PaymentStatus'];
|
||||
order = json['Order'];
|
||||
created = json['Created'];
|
||||
createdBy = json['CreatedBy'];
|
||||
modified = json['Modified'];
|
||||
modifiedBy = json['ModifiedBy'];
|
||||
isDeleted = json['IsDeleted'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['ID'] = this.iD;
|
||||
data['OrderId'] = this.orderId;
|
||||
data['ClientRequestId'] = this.clientRequestId;
|
||||
data['TotalAmount'] = this.totalAmount;
|
||||
data['PaymentStatus'] = this.paymentStatus;
|
||||
data['Order'] = this.order;
|
||||
data['Created'] = this.created;
|
||||
data['CreatedBy'] = this.createdBy;
|
||||
data['Modified'] = this.modified;
|
||||
data['ModifiedBy'] = this.modifiedBy;
|
||||
data['IsDeleted'] = this.isDeleted;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class WFOrder {
|
||||
dynamic wfButtonsDTO;
|
||||
int? iD;
|
||||
int? orderId;
|
||||
int? previousStep;
|
||||
int? nextStep;
|
||||
int? serviceId;
|
||||
dynamic order;
|
||||
String? created;
|
||||
dynamic createdBy;
|
||||
dynamic modified;
|
||||
dynamic modifiedBy;
|
||||
bool? isDeleted;
|
||||
|
||||
WFOrder(
|
||||
{this.wfButtonsDTO,
|
||||
this.iD,
|
||||
this.orderId,
|
||||
this.previousStep,
|
||||
this.nextStep,
|
||||
this.serviceId,
|
||||
this.order,
|
||||
this.created,
|
||||
this.createdBy,
|
||||
this.modified,
|
||||
this.modifiedBy,
|
||||
this.isDeleted});
|
||||
|
||||
WFOrder.fromJson(Map<String, dynamic> json) {
|
||||
wfButtonsDTO = json['wf_ButtonsDTO'];
|
||||
iD = json['ID'];
|
||||
orderId = json['OrderId'];
|
||||
previousStep = json['PreviousStep'];
|
||||
nextStep = json['NextStep'];
|
||||
serviceId = json['ServiceId'];
|
||||
order = json['Order'];
|
||||
created = json['Created'];
|
||||
createdBy = json['CreatedBy'];
|
||||
modified = json['Modified'];
|
||||
modifiedBy = json['ModifiedBy'];
|
||||
isDeleted = json['IsDeleted'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['wf_ButtonsDTO'] = this.wfButtonsDTO;
|
||||
data['ID'] = this.iD;
|
||||
data['OrderId'] = this.orderId;
|
||||
data['PreviousStep'] = this.previousStep;
|
||||
data['NextStep'] = this.nextStep;
|
||||
data['ServiceId'] = this.serviceId;
|
||||
data['Order'] = this.order;
|
||||
data['Created'] = this.created;
|
||||
data['CreatedBy'] = this.createdBy;
|
||||
data['Modified'] = this.modified;
|
||||
data['ModifiedBy'] = this.modifiedBy;
|
||||
data['IsDeleted'] = this.isDeleted;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ServicePrice {
|
||||
String? currency;
|
||||
dynamic maxPrice;
|
||||
dynamic maxTotalPrice;
|
||||
dynamic maxVAT;
|
||||
dynamic minPrice;
|
||||
dynamic minTotalPrice;
|
||||
dynamic minVAT;
|
||||
dynamic price;
|
||||
dynamic totalPrice;
|
||||
dynamic vat;
|
||||
|
||||
ServicePrice({
|
||||
this.currency,
|
||||
this.maxPrice,
|
||||
this.maxTotalPrice,
|
||||
this.maxVAT,
|
||||
this.minPrice,
|
||||
this.minTotalPrice,
|
||||
this.minVAT,
|
||||
this.price,
|
||||
this.totalPrice,
|
||||
this.vat});
|
||||
|
||||
ServicePrice.fromJson(dynamic json) {
|
||||
currency = json["Currency"];
|
||||
maxPrice = json["MaxPrice"];
|
||||
maxTotalPrice = json["MaxTotalPrice"];
|
||||
maxVAT = json["MaxVAT"];
|
||||
minPrice = json["MinPrice"];
|
||||
minTotalPrice = json["MinTotalPrice"];
|
||||
minVAT = json["MinVAT"];
|
||||
price = json["Price"];
|
||||
totalPrice = json["TotalPrice"];
|
||||
vat = json["VAT"];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
var map = <String, dynamic>{};
|
||||
map["Currency"] = currency;
|
||||
map["MaxPrice"] = maxPrice;
|
||||
map["MaxTotalPrice"] = maxTotalPrice;
|
||||
map["MaxVAT"] = maxVAT;
|
||||
map["MinPrice"] = minPrice;
|
||||
map["MinTotalPrice"] = minTotalPrice;
|
||||
map["MinVAT"] = minVAT;
|
||||
map["Price"] = price;
|
||||
map["TotalPrice"] = totalPrice;
|
||||
map["VAT"] = vat;
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
class CmcCreateServiceOrderReqModel {
|
||||
int? recordID;
|
||||
String? serviceID;
|
||||
String? selectedServiceName;
|
||||
String? selectedServiceNameAR;
|
||||
dynamic price;
|
||||
dynamic vAT;
|
||||
dynamic totalPrice;
|
||||
|
||||
CmcCreateServiceOrderReqModel({
|
||||
this.recordID,
|
||||
this.serviceID,
|
||||
this.selectedServiceName,
|
||||
this.selectedServiceNameAR,
|
||||
this.price,
|
||||
this.vAT,
|
||||
this.totalPrice,
|
||||
});
|
||||
|
||||
CmcCreateServiceOrderReqModel.fromJson(Map<String, dynamic> json) {
|
||||
recordID = json['RecordID'];
|
||||
serviceID = json['ServiceID'];
|
||||
selectedServiceName = json['selectedServiceName'];
|
||||
selectedServiceNameAR = json['selectedServiceNameAR'];
|
||||
price = json['Price'];
|
||||
vAT = json['VAT'];
|
||||
totalPrice = json['TotalPrice'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['RecordID'] = recordID;
|
||||
data['ServiceID'] = serviceID;
|
||||
data['selectedServiceName'] = selectedServiceName;
|
||||
data['selectedServiceNameAR'] = selectedServiceNameAR;
|
||||
data['Price'] = price;
|
||||
data['VAT'] = vAT;
|
||||
data['TotalPrice'] = totalPrice;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,515 @@
|
||||
import 'dart:developer';
|
||||
|
||||
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/app_state.dart';
|
||||
import 'package:hmg_patient_app_new/core/dependencies.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/route_extensions.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/hmg_services/hmg_services_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/cmc_create_new_order_req_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/payfort/payfort_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/comprehensive_checkup/widgets/cmc_ui_selection_helper.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
|
||||
import 'package:maps_launcher/maps_launcher.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class CmcSelectionReviewPage extends StatefulWidget {
|
||||
final GetCMCServicesResponseModel selectedService;
|
||||
final HospitalsModel? preSelectedHospital;
|
||||
|
||||
const CmcSelectionReviewPage({super.key, required this.selectedService, this.preSelectedHospital});
|
||||
|
||||
@override
|
||||
State<CmcSelectionReviewPage> createState() => _CmcSelectionReviewPageState();
|
||||
}
|
||||
|
||||
class _CmcSelectionReviewPageState extends State<CmcSelectionReviewPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// Initialize ViewModel state with preselected hospital if provided
|
||||
if (widget.preSelectedHospital != null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
|
||||
hmgServicesViewModel.setSelectedHospitalForOrder(widget.preSelectedHospital);
|
||||
hmgServicesViewModel.setSelectedServiceForOrder(widget.selectedService);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final appState = getIt.get<AppState>();
|
||||
final isArabic = appState.isArabic();
|
||||
|
||||
return CollapsingListView(
|
||||
title: "Summary".needTranslation,
|
||||
bottomChild: _buildBottomButton(),
|
||||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildOrderSummaryCard(isArabic),
|
||||
SizedBox(height: 16.h),
|
||||
_buildSelectedServiceCard(isArabic),
|
||||
SizedBox(height: 16.h),
|
||||
_buildPaymentSummary(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildOrderSummaryCard(bool isArabic) {
|
||||
return Consumer<HmgServicesViewModel>(
|
||||
builder: (context, hmgServicesViewModel, child) {
|
||||
final selectedHospital = hmgServicesViewModel.selectedHospitalForOrder;
|
||||
final isLocationSelected = selectedHospital != null;
|
||||
|
||||
return Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 16.r,
|
||||
),
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Select Hospital".needTranslation,
|
||||
style: TextStyle(
|
||||
fontSize: 16.f,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.blackColor,
|
||||
letterSpacing: -0.5,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
_buildHospitalSelector(isArabic, selectedHospital, isLocationSelected),
|
||||
if (isLocationSelected) ...[
|
||||
SizedBox(height: 16.h),
|
||||
_buildHospitalMap(selectedHospital),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHospitalSelector(bool isArabic, HospitalsModel? selectedHospital, bool isLocationSelected) {
|
||||
return InkWell(
|
||||
onTap: _showHospitalSelectionBottomSheet,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 14.h),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.bgScaffoldColor,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
border: Border.all(
|
||||
color: AppColors.greyColor.withAlpha(51),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
isLocationSelected && selectedHospital != null
|
||||
? (isArabic ? (selectedHospital.nameN ?? selectedHospital.name ?? '') : (selectedHospital.name ?? ''))
|
||||
: "Select Hospital".needTranslation,
|
||||
style: TextStyle(
|
||||
fontSize: 14.f,
|
||||
fontWeight: isLocationSelected ? FontWeight.w600 : FontWeight.w400,
|
||||
color: isLocationSelected ? AppColors.blackColor : AppColors.greyTextColor,
|
||||
letterSpacing: -0.4,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.keyboard_arrow_down,
|
||||
color: AppColors.greyTextColor,
|
||||
size: 24.h,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHospitalMap(HospitalsModel selectedHospital) {
|
||||
final String lat = selectedHospital.latitude ?? "0.0";
|
||||
final String lng = selectedHospital.longitude ?? "0.0";
|
||||
|
||||
log("selectedHospital: $lng and $lat");
|
||||
|
||||
if (lat == "0.0" || lng == "0.0") return SizedBox.shrink();
|
||||
|
||||
final String staticMapUrl =
|
||||
"https://maps.googleapis.com/maps/api/staticmap?center=$lat,$lng&zoom=16&size=600x300&maptype=roadmap&markers=color:red%7C$lat,$lng&key=AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8";
|
||||
|
||||
return Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
child: Image.network(
|
||||
staticMapUrl,
|
||||
height: 200.h,
|
||||
width: double.infinity,
|
||||
fit: BoxFit.cover,
|
||||
loadingBuilder: (context, child, loadingProgress) {
|
||||
if (loadingProgress == null) return child;
|
||||
return Container(
|
||||
height: 200.h,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.bgScaffoldColor,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: AppColors.primaryRedColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
return Container(
|
||||
height: 200.h,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.bgScaffoldColor,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.error_outline,
|
||||
size: 48.h,
|
||||
color: AppColors.greyTextColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 12.h,
|
||||
right: 12.w,
|
||||
child: InkWell(
|
||||
onTap: () => _launchDirections(selectedHospital),
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: BorderRadius.circular(1000.r),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color.fromARGB(26, 0, 0, 0),
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Utils.buildSvgWithAssets(
|
||||
icon: AppAssets.directions_icon,
|
||||
width: 16.w,
|
||||
height: 16.h,
|
||||
),
|
||||
SizedBox(width: 6.w),
|
||||
Text(
|
||||
"Get Directions".needTranslation,
|
||||
style: TextStyle(
|
||||
fontSize: 12.f,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.blackColor,
|
||||
letterSpacing: -0.4,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSelectedServiceCard(bool isArabic) {
|
||||
final serviceName = isArabic ? (widget.selectedService.textN ?? widget.selectedService.text ?? '') : (widget.selectedService.text ?? '');
|
||||
final price = widget.selectedService.priceTotal ?? 0.0;
|
||||
|
||||
return Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 16.r,
|
||||
),
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
"Selected Service".needTranslation.toText14(
|
||||
weight: FontWeight.w600,
|
||||
color: AppColors.greyTextColor,
|
||||
letterSpacing: -0.4,
|
||||
),
|
||||
SizedBox(height: 6.h),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: serviceName.toText16(weight: FontWeight.w700, color: AppColors.blackColor, letterSpacing: -0.5)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPaymentSummary() {
|
||||
// Use selected service from widget
|
||||
final service = widget.selectedService;
|
||||
|
||||
log("service: ${service.toJson()}");
|
||||
|
||||
final double amountBeforeTax = service.price ?? 0.0;
|
||||
final double taxAmount = service.priceVAT ?? 0.0;
|
||||
final double totalAmount = service.priceTotal ?? (amountBeforeTax + taxAmount);
|
||||
|
||||
return Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 24.h,
|
||||
hasShadow: false,
|
||||
),
|
||||
child: Consumer<PayfortViewModel>(builder: (context, payfortVM, child) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 24.h),
|
||||
"Total amount to pay".needTranslation.toText18(isBold: true).paddingSymmetrical(24.h, 0.h),
|
||||
SizedBox(height: 17.h),
|
||||
|
||||
// Amount before tax
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
"Amount before tax".needTranslation.toText14(isBold: true),
|
||||
Utils.getPaymentAmountWithSymbol(
|
||||
amountBeforeTax.toString().toText16(isBold: true),
|
||||
AppColors.blackColor,
|
||||
13,
|
||||
isSaudiCurrency: true,
|
||||
),
|
||||
],
|
||||
).paddingSymmetrical(24.h, 0.h),
|
||||
|
||||
// VAT (use label VAT 15% if desired)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
"VAT 15%".needTranslation.toText14(isBold: true, color: AppColors.greyTextColor),
|
||||
Utils.getPaymentAmountWithSymbol(
|
||||
taxAmount.toString().toText14(isBold: true, color: AppColors.greyTextColor),
|
||||
AppColors.greyTextColor,
|
||||
13,
|
||||
isSaudiCurrency: true,
|
||||
),
|
||||
],
|
||||
).paddingSymmetrical(24.h, 0.h),
|
||||
SizedBox(height: 17.h),
|
||||
// Total Amount
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
"".needTranslation.toText14(isBold: true),
|
||||
Utils.getPaymentAmountWithSymbol(
|
||||
totalAmount.toString().toText24(isBold: true),
|
||||
AppColors.blackColor,
|
||||
17,
|
||||
isSaudiCurrency: true,
|
||||
),
|
||||
],
|
||||
).paddingSymmetrical(24.h, 0.h),
|
||||
|
||||
SizedBox(height: 16.h),
|
||||
],
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBottomButton() {
|
||||
return Consumer<HmgServicesViewModel>(
|
||||
builder: (context, hmgServicesViewModel, child) {
|
||||
final isLocationSelected = hmgServicesViewModel.selectedHospitalForOrder != null;
|
||||
|
||||
return SafeArea(
|
||||
top: false,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color.fromARGB(13, 0, 0, 0),
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, -2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: CustomButton(
|
||||
text: "Confirm".needTranslation,
|
||||
onPressed: () {
|
||||
isLocationSelected ? _handleConfirm() : null;
|
||||
},
|
||||
textColor: AppColors.whiteColor,
|
||||
backgroundColor: isLocationSelected ? AppColors.successColor : AppColors.greyColor,
|
||||
borderRadius: 12.r,
|
||||
borderColor: Colors.transparent,
|
||||
borderWidth: 0,
|
||||
padding: EdgeInsets.symmetric(vertical: 14.h),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _showHospitalSelectionBottomSheet() {
|
||||
CmcUiSelectionHelper.showHospitalSelectionBottomSheet(context: context, onHospitalSelected: (hospital) => context.pop());
|
||||
}
|
||||
|
||||
void _launchDirections(HospitalsModel selectedHospital) {
|
||||
final double lat = double.parse(selectedHospital.latitude ?? "0.0");
|
||||
final double lng = double.parse(selectedHospital.longitude ?? "0.0");
|
||||
|
||||
if (lat != 0.0 && lng != 0.0) {
|
||||
MapsLauncher.launchCoordinates(
|
||||
lat,
|
||||
lng,
|
||||
selectedHospital.name ?? "Hospital",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
showSuccessBottomSheet(int requestId, HmgServicesViewModel hmgServicesViewModel) {
|
||||
return showCommonBottomSheetWithoutHeight(
|
||||
context,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Column(
|
||||
children: [
|
||||
Utils.getSuccessWidget(loadingText: "Your request has been successfully submitted.".needTranslation),
|
||||
Row(
|
||||
children: [
|
||||
"Here is your request #: ".needTranslation.toText14(
|
||||
color: AppColors.textColorLight,
|
||||
weight: FontWeight.w500,
|
||||
),
|
||||
SizedBox(width: 4.w),
|
||||
("$requestId").toText16(isBold: true),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 24.h),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 56.h,
|
||||
text: LocaleKeys.ok.tr(),
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
context.pop();
|
||||
hmgServicesViewModel.getAllCmcOrders();
|
||||
},
|
||||
textColor: AppColors.whiteColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
isCloseButtonVisible: false,
|
||||
isDismissible: false,
|
||||
isFullScreen: false,
|
||||
);
|
||||
}
|
||||
|
||||
void _handleConfirm() {
|
||||
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
|
||||
final selectedHospital = hmgServicesViewModel.selectedHospitalForOrder;
|
||||
|
||||
if (selectedHospital == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text("Please select a hospital to continue".needTranslation),
|
||||
backgroundColor: AppColors.errorColor,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final selectedService = widget.selectedService;
|
||||
return showCommonBottomSheetWithoutHeight(
|
||||
title: LocaleKeys.notice.tr(context: context),
|
||||
context,
|
||||
child: Utils.getWarningWidget(
|
||||
loadingText: "Are you sure you want to submit this request?".needTranslation,
|
||||
isShowActionButtons: true,
|
||||
onCancelTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onConfirmTap: () async {
|
||||
Navigator.pop(context);
|
||||
LoaderBottomSheet.showLoader();
|
||||
|
||||
// Create the services list
|
||||
final servicesList = [
|
||||
PatientERCMCInsertServicesList(
|
||||
recordID: selectedService.iD,
|
||||
serviceID: selectedService.serviceID,
|
||||
selectedServiceName: selectedService.text,
|
||||
selectedServiceNameAR: selectedService.textN,
|
||||
price: selectedService.price,
|
||||
vAT: selectedService.priceVAT,
|
||||
totalPrice: selectedService.priceTotal,
|
||||
),
|
||||
];
|
||||
|
||||
await hmgServicesViewModel.addCmcOrder(
|
||||
projectID: selectedHospital.mainProjectID ?? 0,
|
||||
orderServiceID: selectedService.orderServiceID ?? 3,
|
||||
services: servicesList,
|
||||
onSuccess: (requestId) {
|
||||
LoaderBottomSheet.hideLoader();
|
||||
showSuccessBottomSheet(requestId, hmgServicesViewModel);
|
||||
},
|
||||
onError: (err) {
|
||||
LoaderBottomSheet.hideLoader();
|
||||
// showCommonBottomSheetWithoutHeight(context, child: Utils.getErrorWidget(loadingText: err), callBackFunc: () {});
|
||||
},
|
||||
);
|
||||
}),
|
||||
callBackFunc: () {},
|
||||
isFullScreen: false,
|
||||
isCloseButtonVisible: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,195 +0,0 @@
|
||||
// import 'package:hmg_patient_app/core/enum/viewstate.dart';
|
||||
// import 'package:hmg_patient_app/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart';
|
||||
// import 'package:hmg_patient_app/core/viewModels/AlHabibMedicalService/cmc_view_model.dart';
|
||||
// import 'package:hmg_patient_app/core/viewModels/project_view_model.dart';
|
||||
// import 'package:hmg_patient_app/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_three_page.dart';
|
||||
// import 'package:hmg_patient_app/uitl/translations_delegate_base.dart';
|
||||
// import 'package:hmg_patient_app/uitl/utils.dart';
|
||||
// import 'package:hmg_patient_app/uitl/utils_new.dart';
|
||||
// import 'package:hmg_patient_app/widgets/buttons/defaultButton.dart';
|
||||
// import 'package:hmg_patient_app/widgets/dragable_sheet.dart';
|
||||
// import 'package:hmg_patient_app/widgets/others/app_scaffold_widget.dart';
|
||||
// import 'package:hmg_patient_app/widgets/photo_view_page.dart';
|
||||
// import 'package:flutter/cupertino.dart';
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_svg/svg.dart';
|
||||
// import 'package:provider/provider.dart';
|
||||
//
|
||||
// import 'new_cmc_step_tow_page.dart';
|
||||
//
|
||||
// class NewCMCStepOnePage extends StatefulWidget {
|
||||
// final CMCInsertPresOrderRequestModel cMCInsertPresOrderRequestModel;
|
||||
// final Function changePageViewIndex;
|
||||
// final CMCViewModel model;
|
||||
//
|
||||
// final double latitude;
|
||||
// final double longitude;
|
||||
//
|
||||
// const NewCMCStepOnePage({Key? key, required this.cMCInsertPresOrderRequestModel, required this.model, required this.changePageViewIndex, required this.latitude, required this.longitude})
|
||||
// : super(key: key);
|
||||
//
|
||||
// @override
|
||||
// _NewCMCStepOnePageState createState() => _NewCMCStepOnePageState();
|
||||
// }
|
||||
//
|
||||
// class _NewCMCStepOnePageState extends State<NewCMCStepOnePage> {
|
||||
// int selectedItem = 0;
|
||||
//
|
||||
// @override
|
||||
// void initState() {
|
||||
// super.initState();
|
||||
// }
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// ProjectViewModel projectViewModel = Provider.of(context);
|
||||
//
|
||||
// return AppScaffold(
|
||||
// isShowAppBar: false,
|
||||
// baseViewModel: widget.model,
|
||||
// body: Column(
|
||||
// children: [
|
||||
// Expanded(
|
||||
// child: SingleChildScrollView(
|
||||
// physics: BouncingScrollPhysics(),
|
||||
// padding: EdgeInsets.all(21),
|
||||
// child: Column(
|
||||
// children: [
|
||||
// ListView.separated(
|
||||
// physics: NeverScrollableScrollPhysics(),
|
||||
// shrinkWrap: true,
|
||||
// itemBuilder: (context, index) {
|
||||
// return Row(
|
||||
// children: [
|
||||
// Radio(
|
||||
// value: num.tryParse(widget.model.cmcAllServicesList[index].serviceID!),
|
||||
// activeColor: Colors.red[800],
|
||||
// onChanged: (newValue) async {
|
||||
// selectedItem = index;
|
||||
// PatientERCMCInsertServicesList patientERCMCInsertServicesList = PatientERCMCInsertServicesList(
|
||||
// price: widget.model.cmcAllServicesList[index].price,
|
||||
// serviceID: widget.model.cmcAllServicesList[index].serviceID,
|
||||
// selectedServiceName: widget.model.cmcAllServicesList[index].text,
|
||||
// selectedServiceNameAR: widget.model.cmcAllServicesList[index].textN,
|
||||
// recordID: 1,
|
||||
// totalPrice: widget.model.cmcAllServicesList[index].priceTotal,
|
||||
// vAT: widget.model.cmcAllServicesList[index].priceVAT);
|
||||
// setState(() {
|
||||
// widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList = [patientERCMCInsertServicesList];
|
||||
// });
|
||||
// // CMCGetItemsRequestModel cMCGetItemsRequestModel = new CMCGetItemsRequestModel(checkupType: newValue);
|
||||
// // await widget.model.getCheckupItems(cMCGetItemsRequestModel: cMCGetItemsRequestModel);
|
||||
// },
|
||||
// groupValue: widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList!.length > 0
|
||||
// ? int.parse(widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList![0].serviceID!)
|
||||
// : 1),
|
||||
// Expanded(
|
||||
// child: Padding(
|
||||
// padding: const EdgeInsets.only(
|
||||
// left: 10,
|
||||
// right: 10,
|
||||
// top: 20,
|
||||
// bottom: 20,
|
||||
// ),
|
||||
// child: Text(
|
||||
// projectViewModel.isArabic ? widget.model.cmcAllServicesList[index].textN! : widget.model.cmcAllServicesList[index].text!,
|
||||
// style: TextStyle(
|
||||
// fontSize: 14,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// letterSpacing: -0.45,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// },
|
||||
// separatorBuilder: (context, index) {
|
||||
// return mDivider(Colors.grey);
|
||||
// },
|
||||
// itemCount: widget.model.cmcAllServicesList.length),
|
||||
// Stack(
|
||||
// children: [
|
||||
// Image.asset(
|
||||
// projectViewModel.isArabic ? "assets/images/cc_ar.png" : "assets/images/cc_en.png",
|
||||
// width: double.infinity,
|
||||
// ),
|
||||
// Align(
|
||||
// alignment: Alignment.topRight,
|
||||
// child: Container(
|
||||
// decoration: containerColorRadiusBorder(
|
||||
// Colors.black.withOpacity(0.2),
|
||||
// 1000,
|
||||
// Colors.white,
|
||||
// ),
|
||||
// margin: EdgeInsets.all(12),
|
||||
// child: IconButton(
|
||||
// icon: SvgPicture.asset(
|
||||
// "assets/images/new/ic_zoom.svg",
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// padding: EdgeInsets.all(12),
|
||||
// onPressed: () {
|
||||
// showDraggableDialog(context, PhotoViewPage(projectViewModel.isArabic ? "assets/images/cc_ar.png" : "assets/images/cc_en.png"));
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// Container(
|
||||
// color: Colors.white,
|
||||
// padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21),
|
||||
// child: DefaultButton(
|
||||
// TranslationBase.of(context).next,
|
||||
// () async {
|
||||
// if (widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList!.length != 0 || widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList == null) {
|
||||
// // int index = widget.model.cmcAllServicesList.length;
|
||||
// PatientERCMCInsertServicesList patientERCMCInsertServicesList = new PatientERCMCInsertServicesList(
|
||||
// price: widget.model.cmcAllServicesList[selectedItem].price,
|
||||
// serviceID: widget.model.cmcAllServicesList[selectedItem].serviceID.toString(),
|
||||
// selectedServiceName: widget.model.cmcAllServicesList[selectedItem].text,
|
||||
// selectedServiceNameAR: widget.model.cmcAllServicesList[selectedItem].textN,
|
||||
// recordID: 1,
|
||||
// totalPrice: widget.model.cmcAllServicesList[selectedItem].priceTotal,
|
||||
// vAT: widget.model.cmcAllServicesList[selectedItem].priceVAT,
|
||||
// );
|
||||
//
|
||||
// widget.cMCInsertPresOrderRequestModel.patientID = projectViewModel.user!.patientID;
|
||||
// widget.cMCInsertPresOrderRequestModel.patientOutSA = projectViewModel.user!.outSA;
|
||||
//
|
||||
// widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList = [patientERCMCInsertServicesList];
|
||||
// navigateTo(
|
||||
// context,
|
||||
// NewCMCStepThreePage(
|
||||
// cmcInsertPresOrderRequestModel: widget.cMCInsertPresOrderRequestModel,
|
||||
// model: widget.model,
|
||||
// ),
|
||||
// );
|
||||
// // await widget.model.getCustomerInfo();
|
||||
// if (widget.model.state == ViewState.ErrorLocal) {
|
||||
// Utils.showErrorToast();
|
||||
// } else {
|
||||
// // navigateTo(
|
||||
// // context,
|
||||
// // NewCMCStepTowPage(
|
||||
// // longitude: widget.longitude,
|
||||
// // latitude: widget.latitude,
|
||||
// // cmcInsertPresOrderRequestModel: widget.cMCInsertPresOrderRequestModel,
|
||||
// // model: widget.model,
|
||||
// // ),
|
||||
// // );
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
@ -1,183 +0,0 @@
|
||||
// import 'package:hmg_patient_app/core/enum/viewstate.dart';
|
||||
// import 'package:hmg_patient_app/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/GetCMCAllOrdersResponseModel.dart';
|
||||
// import 'package:hmg_patient_app/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart';
|
||||
// import 'package:hmg_patient_app/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart';
|
||||
// import 'package:hmg_patient_app/core/viewModels/AlHabibMedicalService/cmc_view_model.dart';
|
||||
// import 'package:hmg_patient_app/core/viewModels/project_view_model.dart';
|
||||
// import 'package:hmg_patient_app/uitl/app_toast.dart';
|
||||
// import 'package:hmg_patient_app/uitl/date_uitl.dart';
|
||||
// import 'package:hmg_patient_app/uitl/gif_loader_dialog_utils.dart';
|
||||
// import 'package:hmg_patient_app/uitl/translations_delegate_base.dart';
|
||||
// import 'package:hmg_patient_app/uitl/utils.dart';
|
||||
// import 'package:hmg_patient_app/uitl/utils_new.dart';
|
||||
// import 'package:hmg_patient_app/widgets/buttons/defaultButton.dart';
|
||||
// import 'package:hmg_patient_app/widgets/buttons/secondary_button.dart';
|
||||
// import 'package:hmg_patient_app/widgets/data_display/text.dart';
|
||||
// import 'package:hmg_patient_app/widgets/dialogs/ConfirmWithMessageDialog.dart';
|
||||
// import 'package:hmg_patient_app/widgets/others/app_scaffold_widget.dart';
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:provider/provider.dart';
|
||||
//
|
||||
// import 'Dialog/confirm_cancel_order_dialog.dart';
|
||||
//
|
||||
// class OrdersLogDetailsPage extends StatelessWidget {
|
||||
// final CMCViewModel model;
|
||||
//
|
||||
// const OrdersLogDetailsPage({Key ?key, required this.model}) : super(key: key);
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// ProjectViewModel projectViewModel = Provider.of(context);
|
||||
//
|
||||
// void showConfirmMessage(CMCViewModel model, GetCMCAllOrdersResponseModel order) {
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (cxt) => ConfirmWithMessageDialog(
|
||||
// message: TranslationBase.of(context).cancelOrderMsg,
|
||||
// onTap: () {
|
||||
// UpdatePresOrderRequestModel updatePresOrderRequestModel = UpdatePresOrderRequestModel(presOrderID: order.iD, rejectionReason: "", presOrderStatus: 4, editedBy: 3);
|
||||
// Future.delayed(new Duration(milliseconds: 300)).then((value) async {
|
||||
// GifLoaderDialogUtils.showMyDialog(context);
|
||||
// await model.updateCmcPresOrder(updatePresOrderRequestModel);
|
||||
// if (model.state == ViewState.ErrorLocal) {
|
||||
// Utils.showErrorToast(model.error);
|
||||
// GifLoaderDialogUtils.hideDialog(context);
|
||||
// } else {
|
||||
// AppToast.showSuccessToast(message: TranslationBase.of(context).processDoneSuccessfully);
|
||||
// await model.getCmcAllPresOrders();
|
||||
// GifLoaderDialogUtils.hideDialog(context);
|
||||
// }
|
||||
// });
|
||||
// },
|
||||
// ));
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// return AppScaffold(
|
||||
// isShowAppBar: false,
|
||||
// baseViewModel: model,
|
||||
// body: model.cmcAllPresOrders.length > 0 ? ListView.separated(
|
||||
// padding: EdgeInsets.all(21),
|
||||
// physics: BouncingScrollPhysics(),
|
||||
// itemBuilder: (context, index) {
|
||||
// GetCMCAllOrdersResponseModel order = model.cmcAllPresOrders.reversed.toList()[index];
|
||||
//
|
||||
// int status = order.statusId!;
|
||||
// String _statusDisp = order.statusText!;
|
||||
// late Color _color;
|
||||
// if (status == 1) {
|
||||
// //pending
|
||||
// _color = Color(0xffCC9B14);
|
||||
// } else if (status == 2) {
|
||||
// //processing
|
||||
// _color = Color(0xff2E303A);
|
||||
// } else if (status == 3) {
|
||||
// //completed
|
||||
// _color = Color(0xff359846);
|
||||
// } else if (status == 4 || status == 6 || status == 7) {
|
||||
// //cancel // Rejected
|
||||
// _color = Color(0xffD02127);
|
||||
// }
|
||||
// return Container(
|
||||
// decoration: BoxDecoration(
|
||||
// color: _color,
|
||||
// borderRadius: BorderRadius.all(
|
||||
// Radius.circular(10.0),
|
||||
// ),
|
||||
// boxShadow: [
|
||||
// BoxShadow(
|
||||
// color: Color(0xff000000).withOpacity(.05),
|
||||
// blurRadius: 27,
|
||||
// offset: Offset(0, -3),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// child: Container(
|
||||
// margin: EdgeInsets.only(left: projectViewModel.isArabic ? 0 : 6, right: projectViewModel.isArabic ? 6 : 0),
|
||||
// padding: EdgeInsets.symmetric(vertical: 14, horizontal: 12),
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// border: Border.all(color: Colors.white, width: 1),
|
||||
// borderRadius: BorderRadius.only(
|
||||
// bottomRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0),
|
||||
// topRight: projectViewModel.isArabic ? Radius.circular(0) : Radius.circular(10.0),
|
||||
// bottomLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0),
|
||||
// topLeft: projectViewModel.isArabic ? Radius.circular(10.0) : Radius.circular(0),
|
||||
// ),
|
||||
// ),
|
||||
// // clipBehavior: Clip.antiAlias,
|
||||
// child: Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Expanded(
|
||||
// child: Column(
|
||||
// mainAxisAlignment: MainAxisAlignment.start,
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Text(
|
||||
// _statusDisp,
|
||||
// style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _color, letterSpacing: -0.4, height: 16 / 10),
|
||||
// ),
|
||||
// SizedBox(height: 6),
|
||||
// Text(
|
||||
// '${TranslationBase.of(context).requestID}: ${order.iD}',
|
||||
// style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16),
|
||||
// ),
|
||||
// Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Text(
|
||||
// TranslationBase.of(context).hospital + ": ",
|
||||
// style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.4, height: 16 / 10),
|
||||
// ),
|
||||
// Expanded(
|
||||
// child: Text(
|
||||
// // !projectViewModel.isArabic ? order.nearestProjectDescription.trim().toString() : order.nearestProjectDescriptionN.toString(),
|
||||
// order.projectName != null ? order.projectName!.trim().toString() : "",
|
||||
// style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.56),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// Column(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// crossAxisAlignment: CrossAxisAlignment.end,
|
||||
// children: [
|
||||
// Text(
|
||||
// DateUtil.getDayMonthYearDateFormatted(DateTime.tryParse(order.created!)!),
|
||||
// style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.4, height: 16 / 10),
|
||||
// ),
|
||||
// SizedBox(height: 12),
|
||||
// if (order.statusId == 1 || order.statusId == 2)
|
||||
// InkWell(
|
||||
// onTap: () {
|
||||
// showConfirmMessage(model, order);
|
||||
// },
|
||||
// child: Container(
|
||||
// padding: EdgeInsets.symmetric(vertical: 8, horizontal: 14),
|
||||
// decoration: BoxDecoration(
|
||||
// color: Color(0xffD02127),
|
||||
// border: Border.all(color: Colors.white, width: 1),
|
||||
// borderRadius: BorderRadius.circular(10),
|
||||
// ),
|
||||
// child: Text(
|
||||
// TranslationBase.of(context).cancel_nocaps,
|
||||
// style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.4),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// separatorBuilder: (context, index) => SizedBox(height: 12),
|
||||
// itemCount: model.cmcAllPresOrders.length) : getNoDataWidget(context),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
@ -0,0 +1,111 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.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/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/hmg_services/hmg_services_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
|
||||
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/comprehensive_checkup/widgets/cmc_hospital_list_item.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
class CmcHospitalBottomSheetBody extends StatelessWidget {
|
||||
final Function(HospitalsModel) onHospitalSelected;
|
||||
|
||||
const CmcHospitalBottomSheetBody({super.key, required this.onHospitalSelected});
|
||||
|
||||
Widget _buildLoadingShimmer() {
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: 4,
|
||||
separatorBuilder: (_, __) => SizedBox(height: 12.h),
|
||||
itemBuilder: (context, index) {
|
||||
return Shimmer.fromColors(
|
||||
baseColor: Colors.grey[300]!,
|
||||
highlightColor: Colors.grey[100]!,
|
||||
child: Container(
|
||||
height: 80.h,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final appState = getIt.get<AppState>();
|
||||
final bool isArabic = appState.isArabic();
|
||||
final bool isLocationEnabled = (appState.userLat != 0) && (appState.userLong != 0);
|
||||
|
||||
return Consumer(
|
||||
builder: (BuildContext context, HmgServicesViewModel hmgServicesViewModel, Widget? child) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
"Choose your preferred hospital for the service".needTranslation.toText14(
|
||||
weight: FontWeight.w400,
|
||||
color: AppColors.greyTextColor,
|
||||
letterSpacing: -0.4,
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
TextInputWidget(
|
||||
labelText: LocaleKeys.search.tr(),
|
||||
hintText: LocaleKeys.searchHospital.tr(),
|
||||
onChange: (value) {
|
||||
hmgServicesViewModel.filterHospitalsByString(value ?? '', isArabic);
|
||||
},
|
||||
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: 8.h),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.4,
|
||||
child: hmgServicesViewModel.isHospitalListLoading
|
||||
? _buildLoadingShimmer()
|
||||
: hmgServicesViewModel.filteredHospitalsList.isEmpty
|
||||
? Center(
|
||||
child: "No hospitals Found".needTranslation.toText16(weight: FontWeight.w500, color: AppColors.greyTextColor),
|
||||
)
|
||||
: ListView.separated(
|
||||
itemCount: hmgServicesViewModel.filteredHospitalsList.length,
|
||||
separatorBuilder: (context, index) => SizedBox(height: 12.h),
|
||||
itemBuilder: (context, index) {
|
||||
final hospital = hmgServicesViewModel.filteredHospitalsList[index];
|
||||
return CmcHospitalListItem(
|
||||
hospital: hospital,
|
||||
isLocationEnabled: isLocationEnabled,
|
||||
onPress: () {
|
||||
hmgServicesViewModel.setSelectedHospital(hospital);
|
||||
onHospitalSelected(hospital);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,126 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/core/app_assets.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/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/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 CmcHospitalListItem extends StatelessWidget {
|
||||
final HospitalsModel hospital;
|
||||
final VoidCallback onPress;
|
||||
final bool isLocationEnabled;
|
||||
|
||||
const CmcHospitalListItem({
|
||||
super.key,
|
||||
required this.hospital,
|
||||
required this.onPress,
|
||||
this.isLocationEnabled = false,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final appState = getIt.get<AppState>();
|
||||
final bool isArabic = appState.isArabic();
|
||||
final String hospitalName = isArabic ? (hospital.nameN ?? hospital.name ?? '') : (hospital.name ?? '');
|
||||
|
||||
return InkWell(
|
||||
onTap: onPress,
|
||||
child: 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: [
|
||||
_buildHospitalName(hospitalName),
|
||||
_buildDistanceInfo(),
|
||||
],
|
||||
),
|
||||
),
|
||||
Transform.flip(
|
||||
flipX: isArabic,
|
||||
child: Utils.buildSvgWithAssets(
|
||||
icon: AppAssets.forward_arrow_icon_small,
|
||||
iconColor: AppColors.blackColor,
|
||||
width: 18.h,
|
||||
height: 13.h,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
],
|
||||
).paddingSymmetrical(16.h, 16.h),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHospitalName(String hospitalName) {
|
||||
return Row(
|
||||
children: [
|
||||
Utils.buildSvgWithAssets(
|
||||
icon: (hospital.isHMC == true) ? AppAssets.hmc : AppAssets.hmg,
|
||||
).paddingOnly(right: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
hospitalName,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16,
|
||||
color: AppColors.blackColor,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDistanceInfo() {
|
||||
log("hospital: ${hospital.distanceInKilometers}");
|
||||
final distanceText = hospital.distanceInKilometers != null ? hospital.distanceInKilometers!.toStringAsFixed(1) : "0";
|
||||
|
||||
return Row(
|
||||
spacing: 4.w,
|
||||
children: [
|
||||
Visibility(
|
||||
visible: (hospital.distanceInKilometers != null && hospital.distanceInKilometers! > 0),
|
||||
child: AppCustomChipWidget(
|
||||
labelText: "$distanceText km".needTranslation,
|
||||
icon: AppAssets.location_red,
|
||||
iconColor: AppColors.errorColor,
|
||||
backgroundColor: AppColors.secondaryLightRedColor,
|
||||
textColor: AppColors.errorColor,
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: (hospital.distanceInKilometers == null || hospital.distanceInKilometers == 0),
|
||||
child: AppCustomChipWidget(
|
||||
labelText: " Distance not available".needTranslation,
|
||||
textColor: AppColors.blackColor,
|
||||
),
|
||||
),
|
||||
// Visibility(
|
||||
// visible: !isLocationEnabled,
|
||||
// child: AppCustomChipWidget(
|
||||
// labelText: "Location turned off".needTranslation,
|
||||
// deleteIcon: AppAssets.location_unavailable,
|
||||
// deleteIconSize: Size(9.w, 12.h),
|
||||
// textColor: AppColors.blackColor,
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,110 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/comprehensive_checkup/widgets/cmc_hospital_bottom_sheet_body.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:easy_localization/easy_localization.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/route_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/order_update_req_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
|
||||
import 'package:hmg_patient_app_new/generated/locale_keys.g.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/loader/bottomsheet_loader.dart';
|
||||
|
||||
class CmcUiSelectionHelper {
|
||||
static void showHospitalSelectionBottomSheet({
|
||||
required BuildContext context,
|
||||
required Function(dynamic) onHospitalSelected,
|
||||
}) {
|
||||
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
|
||||
|
||||
showCommonBottomSheetWithoutHeight(
|
||||
context,
|
||||
title: "Select Hospital".needTranslation,
|
||||
child: CmcHospitalBottomSheetBody(
|
||||
onHospitalSelected: (hospital) {
|
||||
hmgServicesViewModel.setSelectedHospitalForOrder(hospital);
|
||||
onHospitalSelected(hospital);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static void showCancelConfirmationDialog({
|
||||
required BuildContext context,
|
||||
required GetCMCAllOrdersResponseModel order,
|
||||
}) {
|
||||
final HmgServicesViewModel hmgServicesViewModel = context.read<HmgServicesViewModel>();
|
||||
|
||||
return showCommonBottomSheetWithoutHeight(
|
||||
title: LocaleKeys.notice.tr(context: context),
|
||||
context,
|
||||
child: Utils.getWarningWidget(
|
||||
loadingText: "Are you sure you want to cancel this order?".needTranslation,
|
||||
isShowActionButtons: true,
|
||||
onCancelTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onConfirmTap: () async {
|
||||
Navigator.pop(context);
|
||||
LoaderBottomSheet.showLoader();
|
||||
|
||||
final requestModel = OrderUpdateRequestModel(
|
||||
presOrderID: order.iD,
|
||||
rejectionReason: "Cancelled by user",
|
||||
presOrderStatus: 4, // Cancelled status
|
||||
editedBy: 3,
|
||||
);
|
||||
|
||||
await hmgServicesViewModel.updateCmcPresOrder(
|
||||
requestModel: requestModel,
|
||||
onSuccess: (_) async {
|
||||
LoaderBottomSheet.hideLoader();
|
||||
showCommonBottomSheetWithoutHeight(
|
||||
context,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Column(
|
||||
children: [
|
||||
Utils.getSuccessWidget(loadingText: "Order has been cancelled successfully".needTranslation),
|
||||
SizedBox(height: 24.h),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 56.h,
|
||||
text: LocaleKeys.ok.tr(),
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
context.pop();
|
||||
hmgServicesViewModel.getAllCmcOrders();
|
||||
},
|
||||
textColor: AppColors.whiteColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
isCloseButtonVisible: false,
|
||||
isDismissible: false,
|
||||
isFullScreen: false,
|
||||
);
|
||||
},
|
||||
onError: (error) {
|
||||
LoaderBottomSheet.hideLoader();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
callBackFunc: () {},
|
||||
isFullScreen: false,
|
||||
isCloseButtonVisible: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,400 @@
|
||||
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/app_state.dart';
|
||||
import 'package:hmg_patient_app_new/core/dependencies.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/date_util.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/features/book_appointments/book_appointments_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/contact_us/contact_us_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/contact_us/models/feedback_type.dart';
|
||||
import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.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/appointment_card.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/contact_us/widgets/feedback_appointment_selection.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.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:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/custom_tab_bar.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/image_picker.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class FeedbackPage extends StatelessWidget {
|
||||
FeedbackPage({super.key});
|
||||
|
||||
late ContactUsViewModel contactUsViewModel;
|
||||
late MedicalFileViewModel medicalFileViewModel;
|
||||
|
||||
final TextEditingController subjectTextController = TextEditingController();
|
||||
final TextEditingController messageTextController = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
contactUsViewModel = Provider.of<ContactUsViewModel>(context, listen: false);
|
||||
medicalFileViewModel = Provider.of<MedicalFileViewModel>(context, listen: false);
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.bgScaffoldColor,
|
||||
body: Consumer<ContactUsViewModel>(builder: (context, contactUsVM, child) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CollapsingListView(
|
||||
isLeading: Navigator.canPop(context),
|
||||
title: LocaleKeys.feedback.tr(),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 16.h),
|
||||
CustomTabBar(
|
||||
activeTextColor: AppColors.primaryRedColor,
|
||||
activeBackgroundColor: AppColors.primaryRedColor.withValues(alpha: .1),
|
||||
tabs: [
|
||||
CustomTabBarModel(null, "Send".needTranslation),
|
||||
CustomTabBarModel(null, "Status".needTranslation),
|
||||
],
|
||||
onTabChange: (index) {
|
||||
contactUsViewModel.setIsSendFeedbackTabSelected(index == 0);
|
||||
},
|
||||
).paddingSymmetrical(24.h, 0.h),
|
||||
getSelectedTabWidget(context).paddingSymmetrical(24.h, 16.w),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
customBorder: BorderRadius.only(
|
||||
topLeft: Radius.circular(24.h),
|
||||
topRight: Radius.circular(24.h),
|
||||
),
|
||||
hasShadow: true,
|
||||
),
|
||||
child: CustomButton(
|
||||
text: LocaleKeys.submit.tr(context: context),
|
||||
onPressed: () async {
|
||||
if (subjectTextController.text.isEmpty) {
|
||||
showCommonBottomSheetWithoutHeight(
|
||||
context,
|
||||
child: Utils.getErrorWidget(loadingText: LocaleKeys.emptySubject.tr(context: context)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (messageTextController.text.isEmpty) {
|
||||
showCommonBottomSheetWithoutHeight(
|
||||
context,
|
||||
child: Utils.getErrorWidget(loadingText: LocaleKeys.emptyMessage.tr(context: context)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
LoaderBottomSheet.showLoader(loadingText: "Sending Feedback...".needTranslation);
|
||||
contactUsViewModel.insertCOCItem(
|
||||
subject: subjectTextController.text,
|
||||
message: messageTextController.text,
|
||||
onSuccess: (val) {
|
||||
LoaderBottomSheet.hideLoader();
|
||||
subjectTextController.clear();
|
||||
messageTextController.clear();
|
||||
contactUsViewModel.setPatientFeedbackSelectedAppointment(null);
|
||||
showCommonBottomSheetWithoutHeight(context, child: Utils.getSuccessWidget(loadingText: LocaleKeys.success.tr(context: context)), callBackFunc: () {
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
onError: (err) {
|
||||
LoaderBottomSheet.hideLoader();
|
||||
showCommonBottomSheetWithoutHeight(
|
||||
context,
|
||||
child: Utils.getSuccessWidget(loadingText: err),
|
||||
);
|
||||
});
|
||||
},
|
||||
backgroundColor: AppColors.primaryRedColor,
|
||||
borderColor: AppColors.primaryRedColor,
|
||||
textColor: AppColors.whiteColor,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
borderRadius: 12,
|
||||
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
|
||||
height: 50.h,
|
||||
icon: AppAssets.feedback,
|
||||
iconColor: AppColors.whiteColor,
|
||||
iconSize: 20.h,
|
||||
).paddingSymmetrical(24.h, 24.h),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getSelectedTabWidget(BuildContext context) {
|
||||
if (contactUsViewModel.isSendFeedbackTabSelected) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.likeToHear.tr().toText14(weight: FontWeight.w500),
|
||||
SizedBox(height: 16.h),
|
||||
Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 16.r,
|
||||
hasShadow: false,
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16.h),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Utils.buildSvgWithAssets(icon: AppAssets.ask_doctor_icon, width: 24.w, height: 24.h, iconColor: AppColors.greyTextColor),
|
||||
SizedBox(width: 12.w),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.feedbackType.tr().toText16(color: AppColors.textColor, weight: FontWeight.w500),
|
||||
(getIt.get<AppState>().isArabic() ? contactUsViewModel.selectedFeedbackType.nameAR : contactUsViewModel.selectedFeedbackType.nameEN)
|
||||
.toText14(color: AppColors.greyTextColor, weight: FontWeight.w500),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Utils.buildSvgWithAssets(icon: AppAssets.arrow_down, width: 25.h, height: 25.h),
|
||||
],
|
||||
).onPress(() {
|
||||
showCommonBottomSheetWithoutHeight(context,
|
||||
title: "Select Feedback Type".needTranslation,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24),
|
||||
child: ListView.builder(
|
||||
itemCount: contactUsViewModel.feedbackTypeList.length,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
padding: EdgeInsets.only(top: 8, bottom: 8),
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (innerContext, index) {
|
||||
return Theme(
|
||||
data: Theme.of(context).copyWith(
|
||||
listTileTheme: ListTileThemeData(horizontalTitleGap: 4),
|
||||
),
|
||||
child: RadioListTile<FeedbackType>(
|
||||
title: Text(
|
||||
getIt.get<AppState>().isArabic() ? contactUsViewModel.feedbackTypeList[index].nameAR : contactUsViewModel.feedbackTypeList[index].nameEN,
|
||||
style: TextStyle(
|
||||
fontSize: 16.h,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
value: contactUsViewModel.feedbackTypeList[index],
|
||||
fillColor: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return AppColors.primaryRedColor;
|
||||
}
|
||||
return Color(0xffEEEEEE);
|
||||
}),
|
||||
contentPadding: EdgeInsets.only(left: 12.h, right: 12.h),
|
||||
groupValue: contactUsViewModel.selectedFeedbackType,
|
||||
onChanged: (FeedbackType? newValue) async {
|
||||
Navigator.pop(context);
|
||||
contactUsViewModel.setSelectedFeedbackType(newValue!);
|
||||
if (contactUsViewModel.selectedFeedbackType.id == 1) {
|
||||
LoaderBottomSheet.showLoader(loadingText: "Loading appointments list...".needTranslation);
|
||||
await medicalFileViewModel.getPatientMedicalReportAppointmentsList(onSuccess: (val) async {
|
||||
LoaderBottomSheet.hideLoader();
|
||||
bool? value = await Navigator.of(context).push(
|
||||
CustomPageRoute(
|
||||
page: FeedbackAppointmentSelection(),
|
||||
fullScreenDialog: true,
|
||||
direction: AxisDirection.down,
|
||||
),
|
||||
);
|
||||
if (value != null) {
|
||||
// showConfirmRequestMedicalReportBottomSheet();
|
||||
}
|
||||
}, onError: (err) {
|
||||
LoaderBottomSheet.hideLoader();
|
||||
showCommonBottomSheetWithoutHeight(
|
||||
context,
|
||||
child: Utils.getErrorWidget(loadingText: "You do not have any appointments to submit a feedback.".needTranslation),
|
||||
callBackFunc: () {},
|
||||
isFullScreen: false,
|
||||
isCloseButtonVisible: true,
|
||||
);
|
||||
});
|
||||
} else {
|
||||
contactUsViewModel.setPatientFeedbackSelectedAppointment(null);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
callBackFunc: () {},
|
||||
isFullScreen: false,
|
||||
isCloseButtonVisible: true);
|
||||
}),
|
||||
]),
|
||||
),
|
||||
),
|
||||
if (contactUsViewModel.patientFeedbackSelectedAppointment != null) ...[
|
||||
SizedBox(height: 16.h),
|
||||
"Selected Appointment:".needTranslation.toText16(isBold: true),
|
||||
SizedBox(height: 8.h),
|
||||
Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 20.r,
|
||||
hasShadow: false,
|
||||
),
|
||||
padding: EdgeInsets.all(16.h),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Image.network(
|
||||
contactUsViewModel.patientFeedbackSelectedAppointment!.doctorImageURL!,
|
||||
width: 63.h,
|
||||
height: 63.h,
|
||||
fit: BoxFit.cover,
|
||||
).circle(100).toShimmer2(isShow: false),
|
||||
SizedBox(width: 16.h),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
(contactUsViewModel.patientFeedbackSelectedAppointment!.doctorNameObj!).toText16(isBold: true, maxlines: 1).toShimmer2(isShow: false),
|
||||
SizedBox(height: 8.h),
|
||||
Wrap(
|
||||
direction: Axis.horizontal,
|
||||
spacing: 3.h,
|
||||
runSpacing: 4.h,
|
||||
children: [
|
||||
AppCustomChipWidget(labelText: contactUsViewModel.patientFeedbackSelectedAppointment!.clinicName!).toShimmer2(isShow: false),
|
||||
AppCustomChipWidget(labelText: contactUsViewModel.patientFeedbackSelectedAppointment!.projectName!).toShimmer2(isShow: false),
|
||||
AppCustomChipWidget(
|
||||
icon: AppAssets.appointment_calendar_icon,
|
||||
labelText: DateUtil.formatDateToDate(DateUtil.convertStringToDate(contactUsViewModel.patientFeedbackSelectedAppointment!.appointmentDate), false),
|
||||
).toShimmer2(isShow: false),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
SizedBox(height: 16.h),
|
||||
TextInputWidget(
|
||||
labelText: "Subject".needTranslation,
|
||||
hintText: "Enter subject here".needTranslation,
|
||||
controller: subjectTextController,
|
||||
isEnable: true,
|
||||
prefix: null,
|
||||
autoFocus: false,
|
||||
isBorderAllowed: false,
|
||||
keyboardType: TextInputType.text,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: ResponsiveExtension(10).h,
|
||||
horizontal: ResponsiveExtension(15).h,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
TextInputWidget(
|
||||
labelText: "Message".needTranslation,
|
||||
hintText: "Enter message here".needTranslation,
|
||||
controller: messageTextController,
|
||||
isEnable: true,
|
||||
prefix: null,
|
||||
autoFocus: false,
|
||||
isBorderAllowed: false,
|
||||
isMultiline: true,
|
||||
keyboardType: TextInputType.text,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: ResponsiveExtension(10).h,
|
||||
horizontal: ResponsiveExtension(15).h,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
CustomButton(
|
||||
text: LocaleKeys.selectAttachment.tr(context: context),
|
||||
onPressed: () async {
|
||||
ImageOptions.showImageOptionsNew(
|
||||
context,
|
||||
true,
|
||||
(String image, file) {
|
||||
print(image);
|
||||
print(file);
|
||||
Navigator.pop(context);
|
||||
contactUsViewModel.addFeedbackAttachment(image);
|
||||
},
|
||||
);
|
||||
},
|
||||
backgroundColor: AppColors.secondaryLightRedColor,
|
||||
borderColor: AppColors.secondaryLightRedColor,
|
||||
textColor: AppColors.primaryRedColor,
|
||||
fontSize: 14.f,
|
||||
fontWeight: FontWeight.w500,
|
||||
borderRadius: 10.r,
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.w),
|
||||
height: isTablet || isFoldable ? 46.h : 40.h,
|
||||
icon: AppAssets.file_icon,
|
||||
iconColor: AppColors.primaryRedColor,
|
||||
iconSize: 16.h,
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
contactUsViewModel.feedbackAttachmentList.isNotEmpty
|
||||
? Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 12.r,
|
||||
hasShadow: false,
|
||||
),
|
||||
child: ListView.builder(
|
||||
padding: EdgeInsets.all(16.h),
|
||||
shrinkWrap: true,
|
||||
itemCount: contactUsViewModel.feedbackAttachmentList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.attach_file,
|
||||
color: Color(0xff2B353E),
|
||||
),
|
||||
SizedBox(width: 8.w),
|
||||
"Image ${index + 1}".toText14().paddingOnly(bottom: 8.h),
|
||||
],
|
||||
),
|
||||
Utils.buildSvgWithAssets(icon: AppAssets.cancel_circle_icon).onPress(() {
|
||||
contactUsViewModel.removeFeedbackAttachment(contactUsViewModel.feedbackAttachmentList[index]);
|
||||
}),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,27 +1,176 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
|
||||
import 'package:hmg_patient_app_new/core/app_assets.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/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/features/contact_us/contact_us_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.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';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class LiveChatPage extends StatelessWidget {
|
||||
const LiveChatPage({super.key});
|
||||
LiveChatPage({super.key});
|
||||
|
||||
String chatURL = "";
|
||||
|
||||
late AppState appState;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
appState = getIt.get<AppState>();
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.bgScaffoldColor,
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CollapsingListView(
|
||||
title: LocaleKeys.liveChat.tr(),
|
||||
child: SingleChildScrollView(),
|
||||
body: Consumer<ContactUsViewModel>(builder: (context, contactUsVM, child) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CollapsingListView(
|
||||
title: LocaleKeys.liveChat.tr(),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 16.h),
|
||||
ListView.separated(
|
||||
padding: EdgeInsets.only(top: 16.h),
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemCount: contactUsVM.isLiveChatProjectsListLoading ? 5 : contactUsVM.liveChatProjectsList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return contactUsVM.isLiveChatProjectsListLoading
|
||||
? Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
|
||||
child: Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 20.h,
|
||||
hasShadow: true,
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(14.h),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Image.network(
|
||||
"https://hmgwebservices.com/Images/MobileImages/DUBAI/unkown_female.png",
|
||||
width: 63.h,
|
||||
height: 63.h,
|
||||
fit: BoxFit.cover,
|
||||
).circle(100).toShimmer2(isShow: true),
|
||||
SizedBox(width: 16.h),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
"Dr John Smith".toText16(isBold: true).toShimmer2(isShow: true),
|
||||
SizedBox(height: 8.h),
|
||||
Wrap(
|
||||
direction: Axis.horizontal,
|
||||
spacing: 3.h,
|
||||
runSpacing: 4.h,
|
||||
children: [
|
||||
AppCustomChipWidget(labelText: "").toShimmer2(isShow: true, width: 16.h),
|
||||
AppCustomChipWidget(labelText: "").toShimmer2(isShow: true, width: 16.h),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
).paddingSymmetrical(24.h, 0.h)
|
||||
: AnimationConfiguration.staggeredList(
|
||||
position: index,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: SlideAnimation(
|
||||
verticalOffset: 100.0,
|
||||
child: FadeInAnimation(
|
||||
child: AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
|
||||
child: DecoratedBox(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: contactUsVM.selectedLiveChatProjectIndex == index ? AppColors.primaryRedColor : AppColors.whiteColor,
|
||||
borderRadius: 16.r,
|
||||
hasShadow: false,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
("${appState.isArabic() ? contactUsVM.liveChatProjectsList[index].projectNameN! : contactUsVM.liveChatProjectsList[index].projectName!}\n${contactUsVM.liveChatProjectsList[index].distanceInKilometers!} KM")
|
||||
.needTranslation
|
||||
.toText14(isBold: true, color: contactUsVM.selectedLiveChatProjectIndex == index ? AppColors.whiteColor : AppColors.textColor),
|
||||
Transform.flip(
|
||||
flipX: getIt.get<AppState>().isArabic(),
|
||||
child: Utils.buildSvgWithAssets(
|
||||
icon: AppAssets.forward_arrow_icon_small,
|
||||
iconColor: contactUsVM.selectedLiveChatProjectIndex == index ? AppColors.whiteColor : AppColors.textColor,
|
||||
width: 18.h,
|
||||
height: 13.h,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
],
|
||||
).paddingSymmetrical(16.h, 16.h),
|
||||
).onPress(() {
|
||||
contactUsVM.setSelectedLiveChatProjectIndex(index);
|
||||
chatURL =
|
||||
"https://chat.hmg.com/Index.aspx?Name=${appState.getAuthenticatedUser()!.firstName}&PatientID=${appState.getAuthenticatedUser()!.patientId}&MobileNo=${appState.getAuthenticatedUser()!.mobileNumber}&Language=${appState.isArabic() ? 'ar' : 'en'}&WorkGroup=${contactUsVM.liveChatProjectsList[index].value}";
|
||||
debugPrint("Chat URL: $chatURL");
|
||||
}),
|
||||
).paddingSymmetrical(24.h, 0.h),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
|
||||
),
|
||||
SizedBox(height: 24.h),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 24.h,
|
||||
hasShadow: true,
|
||||
),
|
||||
child: CustomButton(
|
||||
text: LocaleKeys.liveChat.tr(context: context),
|
||||
onPressed: () async {
|
||||
Uri uri = Uri.parse(chatURL);
|
||||
launchUrl(uri, mode: LaunchMode.platformDefault, webOnlyWindowName: "");
|
||||
},
|
||||
backgroundColor: contactUsVM.selectedLiveChatProjectIndex == -1 ? AppColors.greyColor : AppColors.primaryRedColor,
|
||||
borderColor: contactUsVM.selectedLiveChatProjectIndex == -1 ? AppColors.greyColor : AppColors.primaryRedColor,
|
||||
textColor: AppColors.whiteColor,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
borderRadius: 12,
|
||||
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
|
||||
height: 50.h,
|
||||
).paddingSymmetrical(24.h, 24.h),
|
||||
),
|
||||
),
|
||||
Container()
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/contact_us/contact_us_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/medical_file/medical_file_view_model.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/appointment_card.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class FeedbackAppointmentSelection extends StatelessWidget {
|
||||
FeedbackAppointmentSelection({super.key});
|
||||
|
||||
late MedicalFileViewModel medicalFileViewModel;
|
||||
late ContactUsViewModel contactUsViewModel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
medicalFileViewModel = Provider.of<MedicalFileViewModel>(context, listen: false);
|
||||
contactUsViewModel = Provider.of<ContactUsViewModel>(context, listen: false);
|
||||
return CollapsingListView(
|
||||
title: LocaleKeys.feedback.tr(),
|
||||
isClose: true,
|
||||
child: Column(
|
||||
children: [
|
||||
ListView.separated(
|
||||
padding: EdgeInsets.only(top: 24.h),
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemCount: medicalFileViewModel.patientMedicalReportAppointmentHistoryList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return AnimationConfiguration.staggeredList(
|
||||
position: index,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: SlideAnimation(
|
||||
verticalOffset: 100.0,
|
||||
child: FadeInAnimation(
|
||||
child: AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(color: AppColors.whiteColor, borderRadius: 24.h, hasShadow: true),
|
||||
child: AppointmentCard(
|
||||
patientAppointmentHistoryResponseModel: medicalFileViewModel.patientMedicalReportAppointmentHistoryList[index],
|
||||
myAppointmentsViewModel: Provider.of<MyAppointmentsViewModel>(context, listen: false),
|
||||
bookAppointmentsViewModel: Provider.of<BookAppointmentsViewModel>(context, listen: false),
|
||||
medicalFileViewModel: medicalFileViewModel,
|
||||
contactUsViewModel: contactUsViewModel,
|
||||
isLoading: false,
|
||||
isFromHomePage: false,
|
||||
isFromMedicalReport: true,
|
||||
isForFeedback: true,
|
||||
),
|
||||
).paddingSymmetrical(24.h, 0.h),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (BuildContext cxt, int index) => SizedBox(height: 16.h),
|
||||
),
|
||||
SizedBox(height: 24.h),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,633 @@
|
||||
import 'dart:io';
|
||||
|
||||
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/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/models/AmbulanceCallingPlace.dart';
|
||||
import 'package:hmg_patient_app_new/features/location/GeocodeResponse.dart';
|
||||
import 'package:hmg_patient_app_new/features/location/PlaceDetails.dart';
|
||||
import 'package:hmg_patient_app_new/features/location/PlacePrediction.dart';
|
||||
import 'package:hmg_patient_app_new/features/location/location_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/appointments/widgets/appointment_doctor_card.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/AddressItem.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/HospitalBottomSheetBody.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/emergency_services/call_ambulance/widgets/appointment_bottom_sheet.dart' show AppointmentBottomSheet;
|
||||
import 'package:hmg_patient_app_new/presentation/emergency_services/widgets/location_input_bottom_sheet.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/CustomSwitch.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/expandable_bottom_sheet/ExpandableBottomSheet.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/expandable_bottom_sheet/model/BottomSheetType.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/map/HMSMap.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/map/map.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../../widgets/common_bottom_sheet.dart';
|
||||
|
||||
class RrtMapScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
floatingActionButton: Visibility(
|
||||
visible: context.watch<EmergencyServicesViewModel>().bottomSheetType ==
|
||||
BottomSheetType.FIXED,
|
||||
child: Padding(
|
||||
padding: EdgeInsetsDirectional.only(end: 8.h, bottom: 68.h),
|
||||
child: DecoratedBox(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor, borderRadius: 12.h),
|
||||
child: Utils.buildSvgWithAssets(
|
||||
icon: AppAssets.locate_me, width: 24.h, height: 24.h)
|
||||
.paddingAll(12.h)
|
||||
.onPress(() {
|
||||
context
|
||||
.read<EmergencyServicesViewModel>()
|
||||
.moveToCurrentLocation();
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomSheet: ExpandableBottomSheet(
|
||||
bottomSheetType:
|
||||
context.watch<EmergencyServicesViewModel>().bottomSheetType,
|
||||
children: {
|
||||
BottomSheetType.EXPANDED: ExpanedBottomSheet(context),
|
||||
BottomSheetType.FIXED: FixedBottomSheet(context),
|
||||
},
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
if (context.read<EmergencyServicesViewModel>().isGMSAvailable)
|
||||
GMSMap(
|
||||
currentLocation:
|
||||
context.read<EmergencyServicesViewModel>().getGMSLocation(),
|
||||
onCameraMoved: (value) => context
|
||||
.read<LocationViewModel>()
|
||||
.handleGMSMapCameraMoved(value),
|
||||
onCameraIdle:
|
||||
context.read<LocationViewModel>().handleOnCameraIdle,
|
||||
myLocationEnabled: true,
|
||||
inputController:
|
||||
context.read<EmergencyServicesViewModel>().gmsController,
|
||||
showCenterMarker: true,
|
||||
)
|
||||
else
|
||||
HMSMap(
|
||||
currentLocation:
|
||||
context.read<EmergencyServicesViewModel>().getHMSLocation(),
|
||||
onCameraMoved: (value) => context
|
||||
.read<LocationViewModel>()
|
||||
.handleHMSMapCameraMoved(value),
|
||||
onCameraIdle:
|
||||
context.read<LocationViewModel>().handleOnCameraIdle,
|
||||
myLocationEnabled: false,
|
||||
inputController:
|
||||
context.read<EmergencyServicesViewModel>().hmsController,
|
||||
showCenterMarker: true,
|
||||
),
|
||||
Align(
|
||||
alignment: AlignmentDirectional.topStart,
|
||||
child: Utils.buildSvgWithAssets(
|
||||
icon: AppAssets.closeBottomNav, width: 32.h, height: 32.h)
|
||||
.onPress(() {
|
||||
context
|
||||
.read<EmergencyServicesViewModel>()
|
||||
.flushPickupInformation();
|
||||
Navigator.pop(context);
|
||||
}),
|
||||
).paddingOnly(top: 51.h, left: 24.h),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget FixedBottomSheet(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onVerticalDragUpdate: (details){
|
||||
},
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
spacing: 24.h,
|
||||
children: [
|
||||
inputFields(context).paddingSymmetrical(16.h, 0.h),
|
||||
SizedBox(
|
||||
child: DecoratedBox(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.scaffoldBgColor,
|
||||
customBorder: BorderRadius.only(
|
||||
topLeft: Radius.circular(24.h),
|
||||
topRight: Radius.circular(24.h),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 24.h,
|
||||
children: [
|
||||
Column(
|
||||
spacing: 4.h,
|
||||
children: [
|
||||
"Select Location".needTranslation.toText21(
|
||||
weight: FontWeight.w600,
|
||||
color: AppColors.textColor,
|
||||
),
|
||||
"Please select the location".needTranslation.toText12(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.greyTextColor,
|
||||
)
|
||||
],
|
||||
),
|
||||
CustomButton(
|
||||
text: "Submit Request".needTranslation,
|
||||
onPressed: () {
|
||||
LocationViewModel locationViewModel = context.read<LocationViewModel>();
|
||||
GeocodeResponse? response = locationViewModel.geocodeResponse;
|
||||
PlaceDetails? placeDetails = locationViewModel.placeDetails;
|
||||
PlacePrediction? placePrediction = locationViewModel.selectedPrediction;
|
||||
context.read<EmergencyServicesViewModel>().submitRRTRequest(response?.results.first, placeDetails, placePrediction);
|
||||
},
|
||||
)
|
||||
],
|
||||
).paddingOnly(top: 24.h, bottom: 32.h, left: 24.h, right: 24.h),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget ExpanedBottomSheet(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onVerticalDragUpdate: (details){
|
||||
if(details.delta.dy>0){
|
||||
context.read<EmergencyServicesViewModel>().updateBottomSheetState(BottomSheetType.FIXED);
|
||||
}
|
||||
},
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
DecoratedBox(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.scaffoldBgColor,
|
||||
customBorder: BorderRadius.only(
|
||||
topLeft: Radius.circular(24.h),
|
||||
topRight: Radius.circular(24.h),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 16.h,
|
||||
children: [
|
||||
|
||||
hospitalAndPickUpSection(context),
|
||||
|
||||
|
||||
],
|
||||
).paddingOnly(top: 24.h, bottom: 32.h,left: 24.h, right: 24.h),
|
||||
|
||||
bottomPriceContent(context)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
locationsSections(BuildContext context) {
|
||||
return DecoratedBox(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 24.h,
|
||||
),
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
ListView.separated(
|
||||
separatorBuilder: (_, __) => Column(
|
||||
children: [
|
||||
SizedBox(height: 16.h),
|
||||
Divider(
|
||||
color: AppColors.bottomNAVBorder,
|
||||
height: 1,
|
||||
thickness: 1,
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
],
|
||||
),
|
||||
shrinkWrap: true,
|
||||
itemCount: 3,
|
||||
itemBuilder: (__, index) {
|
||||
if (index ==
|
||||
2) // todo means the end of the list so handle as per the viewmodel
|
||||
{
|
||||
return CustomButton(
|
||||
height: 40.h,
|
||||
backgroundColor: AppColors.lightRedButtonColor,
|
||||
borderColor: Colors.transparent,
|
||||
text: "Add new address".needTranslation,
|
||||
textColor: AppColors.primaryRedColor,
|
||||
iconColor: AppColors.primaryRedColor,
|
||||
onPressed: () {},
|
||||
icon: AppAssets.add_icon);
|
||||
} else {
|
||||
return AddressItem(
|
||||
isSelected: index == 0,
|
||||
address:
|
||||
"Flat No 301, Building No 12, Palm Spring Apartment, Sector 45, Gurugram, Haryana 122003",
|
||||
title: index == 0
|
||||
? "Home".needTranslation
|
||||
: "Work".needTranslation,
|
||||
onTap: () {},
|
||||
);
|
||||
}
|
||||
})
|
||||
]).paddingAll(16.h),
|
||||
);
|
||||
}
|
||||
|
||||
hospitalAndPickUpSection(BuildContext context) {
|
||||
return DecoratedBox(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 24.r,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 16.h,
|
||||
children: [
|
||||
// Row(
|
||||
// children: [
|
||||
// hospitalAndPickUpItemContent(
|
||||
// title: "Select Hospital".needTranslation,
|
||||
// subTitle: "hospital".needTranslation,
|
||||
// leadingIcon: AppAssets.hospital,
|
||||
// ),
|
||||
// Utils.buildSvgWithAssets(icon: AppAssets.down_cheveron,
|
||||
// width: 24.h, height: 24.h)
|
||||
// .paddingAll(16.h)
|
||||
// ],
|
||||
// ).onPress((){
|
||||
// showHospitalBottomSheet(context);
|
||||
// }),
|
||||
// SizedBox(height: 16.h),
|
||||
// Divider(
|
||||
// color: AppColors.bottomNAVBorder,
|
||||
// height: 1,
|
||||
// thickness: 1,
|
||||
// ),
|
||||
// SizedBox(height: 16.h),
|
||||
|
||||
Row(
|
||||
children: [
|
||||
hospitalAndPickUpItemContent(
|
||||
title: "Pick".needTranslation,
|
||||
subTitle: "Inside the home".needTranslation,
|
||||
leadingIcon: AppAssets.pickup_bed,
|
||||
),
|
||||
CustomSwitch(
|
||||
value: context
|
||||
.watch<EmergencyServicesViewModel>()
|
||||
.pickupFromInsideTheLocation,
|
||||
onChanged: (value){
|
||||
context
|
||||
.read<EmergencyServicesViewModel>()
|
||||
.updateThePickupPlaceFromLocation(value);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
|
||||
Row(
|
||||
children: [
|
||||
hospitalAndPickUpItemContent(
|
||||
title: '',
|
||||
subTitle: "Have any appointment".needTranslation,
|
||||
leadingIcon: AppAssets.appointment_checkin_icon,
|
||||
),
|
||||
CustomSwitch(
|
||||
value: context
|
||||
.watch<EmergencyServicesViewModel>()
|
||||
.haveAnAppointment,
|
||||
onChanged: (value) async {
|
||||
// if (value) {
|
||||
// openAppointmentList(context);
|
||||
// }
|
||||
await context.read<EmergencyServicesViewModel>()
|
||||
.updateAppointment(value);
|
||||
if (context.read<EmergencyServicesViewModel>().appointments?.isNotEmpty == true) {
|
||||
openAppointmentList(context);
|
||||
}
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
).paddingAll(16.h),
|
||||
);
|
||||
}
|
||||
|
||||
leadingIcon(String leadingIcon) {
|
||||
return Container(
|
||||
height: 40.h,
|
||||
width: 40.h,
|
||||
margin: EdgeInsets.only(right: 10.h),
|
||||
padding: EdgeInsets.all(8.h),
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
borderRadius: 12.h,
|
||||
color: AppColors.greyColor,
|
||||
),
|
||||
child: Utils.buildSvgWithAssets(icon: leadingIcon),
|
||||
);
|
||||
}
|
||||
|
||||
hospitalAndPickUpItemContent({
|
||||
required String title,
|
||||
required String subTitle,
|
||||
required String leadingIcon,
|
||||
}) {
|
||||
return Expanded(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
this.leadingIcon(leadingIcon),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Visibility(
|
||||
visible: title.isNotEmpty,
|
||||
child: Column(
|
||||
children: [
|
||||
title.toText12(
|
||||
color: AppColors.greyTextColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
SizedBox(height: 2.h),
|
||||
],
|
||||
),
|
||||
),
|
||||
subTitle.toText14(
|
||||
color: AppColors.textColor,
|
||||
weight: FontWeight.w500,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bottomPriceContent(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
DecoratedBox(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.scaffoldBgColor,
|
||||
customBorder: BorderRadius.only(
|
||||
topLeft: Radius.circular(24.h),
|
||||
topRight: Radius.circular(24.h),
|
||||
),
|
||||
hasShadow: true
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 12.h,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 4.h,
|
||||
children: [
|
||||
"Total amount to pay".needTranslation.toText18(
|
||||
weight: FontWeight.w600,
|
||||
color: AppColors.textColor,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Utils.buildSvgWithAssets(icon: AppAssets.warning,
|
||||
height: 18.h, width: 18.h),
|
||||
SizedBox(width: 4.h,),
|
||||
"Amount will be paid at the hospital"
|
||||
.needTranslation
|
||||
.toText12(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.greyTextColor,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Utils.getPaymentAmountWithSymbol(
|
||||
(Utils.formatNumberToInternationalFormat(context
|
||||
.read<EmergencyServicesViewModel>()
|
||||
.getTotalPrice() ??
|
||||
0))
|
||||
.toText24(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textColor,
|
||||
letterSpacing: -2),
|
||||
AppColors.blackColor,
|
||||
17.h)
|
||||
|
||||
// Utils.getPaymentAmountWithSymbol2(context.read<EmergencyServicesViewModel>().selectedTransportOption?.priceTotal??"0", letterSpacing: -2)
|
||||
],
|
||||
),
|
||||
CustomButton(
|
||||
text: "Submit Request".needTranslation,
|
||||
onPressed: () {
|
||||
LocationViewModel locationViewModel = context.read<LocationViewModel>();
|
||||
GeocodeResponse? response = locationViewModel.geocodeResponse;
|
||||
PlaceDetails? placeDetails = locationViewModel.placeDetails;
|
||||
PlacePrediction? placePrediction = locationViewModel.selectedPrediction;
|
||||
context.read<EmergencyServicesViewModel>().submitAmbulanceRequest(response?.results.first, placeDetails, placePrediction);
|
||||
})
|
||||
],
|
||||
).paddingOnly(top: 24.h, bottom: 12.h, left: 24.h, right: 24.h),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
showHospitalBottomSheet(BuildContext context){
|
||||
showCommonBottomSheetWithoutHeight(
|
||||
title:
|
||||
LocaleKeys.selectHospital.tr(),
|
||||
context,
|
||||
child: Consumer<EmergencyServicesViewModel>(
|
||||
builder:(_,vm,__)=> HospitalBottomSheetBody(
|
||||
searchText: vm.searchController,
|
||||
displayList: vm.displayList,
|
||||
onFacilityClicked: (value) {
|
||||
vm.setSelectedFacility(value);
|
||||
vm.getDisplayList();
|
||||
},
|
||||
onHospitalClicked: (hospital) {
|
||||
Navigator.pop(context);
|
||||
vm.setSelectedHospital(hospital);
|
||||
},
|
||||
onHospitalSearch: (value) {
|
||||
vm.searchHospitals(value ?? "");
|
||||
},
|
||||
selectedFacility:
|
||||
vm.selectedFacility,
|
||||
hmcCount: vm.hmcCount,
|
||||
hmgCount: vm.hmgCount,
|
||||
),
|
||||
),
|
||||
isFullScreen: false,
|
||||
isCloseButtonVisible: true,
|
||||
hasBottomPadding: false,
|
||||
backgroundColor: AppColors.bottomSheetBgColor,
|
||||
callBackFunc: () {
|
||||
context.read<EmergencyServicesViewModel>().clearSearchText();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
///it will show the places field first and then hospital field
|
||||
PlaceFirstThanHospitalField(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 16.h,
|
||||
children: [
|
||||
textPlaceInput(context),
|
||||
hospitalField(context),
|
||||
],
|
||||
).paddingOnly(right: 24.h, left: 24.h);
|
||||
}
|
||||
|
||||
HospitalFieldFirstThanPlaces(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 16.h,
|
||||
children: [hospitalField(context), textPlaceInput(context)],
|
||||
).paddingOnly(right: 24.h, left: 24.h);
|
||||
}
|
||||
|
||||
textPlaceInput(context) {
|
||||
return Consumer<LocationViewModel>(builder: (_, vm, __) {
|
||||
print(
|
||||
"the data is ${vm.geocodeResponse?.results.first.formattedAddress ?? vm.selectedPrediction?.description}");
|
||||
return SizedBox(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
child: TextInputWidget(
|
||||
labelText: "Enter Pickup Location Manually".needTranslation,
|
||||
hintText: "Enter Pickup Location".needTranslation,
|
||||
controller: TextEditingController(
|
||||
text: vm.geocodeResponse?.results.first.formattedAddress ??
|
||||
vm.selectedPrediction?.description,
|
||||
),
|
||||
leadingIcon: AppAssets.location_pickup,
|
||||
isAllowLeadingIcon: true,
|
||||
isEnable: false,
|
||||
prefix: null,
|
||||
autoFocus: false,
|
||||
isBorderAllowed: false,
|
||||
keyboardType: TextInputType.text,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: ResponsiveExtension(10).h,
|
||||
horizontal: ResponsiveExtension(15).h,
|
||||
),
|
||||
).onPress(() {
|
||||
openLocationInputBottomSheet(context);
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
///decide which field to show first based on the selected calling place
|
||||
Widget inputFields(BuildContext context) {
|
||||
return textPlaceInput(context);
|
||||
}
|
||||
|
||||
openLocationInputBottomSheet(BuildContext context) {
|
||||
context.read<LocationViewModel>().flushSearchPredictions();
|
||||
showCommonBottomSheetWithoutHeight(
|
||||
title: "".needTranslation,
|
||||
context,
|
||||
child: SizedBox(
|
||||
height: MediaQuery.sizeOf(context).height * .8,
|
||||
child: LocationInputBottomSheet(),
|
||||
),
|
||||
isFullScreen: false,
|
||||
isCloseButtonVisible: true,
|
||||
hasBottomPadding: false,
|
||||
backgroundColor: AppColors.bottomSheetBgColor,
|
||||
callBackFunc: () {},
|
||||
);
|
||||
}
|
||||
|
||||
hospitalField(BuildContext context) {
|
||||
return DecoratedBox(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor, borderRadius: 12.h),
|
||||
child: Row(
|
||||
children: [
|
||||
hospitalAndPickUpItemContent(
|
||||
title: "Select Hospital".needTranslation,
|
||||
subTitle: context
|
||||
.read<EmergencyServicesViewModel>()
|
||||
.getSelectedHospitalName() ??
|
||||
"Select Hospital".needTranslation,
|
||||
leadingIcon: AppAssets.hospital,
|
||||
),
|
||||
Utils.buildSvgWithAssets(
|
||||
icon: AppAssets.down_cheveron, width: 24.h, height: 24.h)
|
||||
.paddingAll(16.h)
|
||||
],
|
||||
).onPress(() {
|
||||
print("the item is clicked");
|
||||
showHospitalBottomSheet(context);
|
||||
}).paddingSymmetrical(
|
||||
10.w,
|
||||
12.h,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void openAppointmentList(BuildContext context) {
|
||||
showCommonBottomSheetWithoutHeight(
|
||||
title: "Select Appointment".needTranslation,
|
||||
context,
|
||||
child: SizedBox(
|
||||
height: MediaQuery.sizeOf(context).height * .5,
|
||||
child: AppointmentBottomSheet(
|
||||
list: context.read<EmergencyServicesViewModel>().appointments!,
|
||||
onAppointmentSelection: (appointment) {
|
||||
Navigator.pop(context);
|
||||
context.read<EmergencyServicesViewModel>().setSelectedAppointment(appointment);
|
||||
}),
|
||||
),
|
||||
isFullScreen: false,
|
||||
isCloseButtonVisible: true,
|
||||
hasBottomPadding: false,
|
||||
backgroundColor: AppColors.bottomSheetBgColor,
|
||||
callBackFunc: () {
|
||||
context.read<EmergencyServicesViewModel>().checkHasAppointment();
|
||||
},
|
||||
);
|
||||
// );
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_widget_from_html/flutter_widget_from_html.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/features/emergency_services/emergency_services_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class TermsAndCondition extends StatelessWidget {
|
||||
final String termsAndCondition;
|
||||
const TermsAndCondition({super.key, required this.termsAndCondition});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
|
||||
Expanded(
|
||||
child: CollapsingListView(
|
||||
title: "Terms And Condition".needTranslation,
|
||||
child:DecoratedBox(decoration:RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 20.h,
|
||||
hasShadow: true,
|
||||
),child: HtmlWidget(termsAndCondition).paddingAll(16.h)).paddingAll(12.h)))]));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
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/date_util.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/models/resp_model/AmbulanceRequestOrdersModel.dart';
|
||||
import 'package:hmg_patient_app_new/features/emergency_services/models/resp_model/RRTServiceData.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/emergency_services/history/widget/RequestStatus.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';
|
||||
|
||||
import '../../../../core/utils/utils.dart';
|
||||
|
||||
|
||||
class RRTItem extends StatelessWidget {
|
||||
final GetCMCAllOrdersResponseModel order;
|
||||
|
||||
const RRTItem({super.key, required this.order});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DecoratedBox(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: Colors.white,
|
||||
hasShadow: true,
|
||||
customBorder: BorderRadius.all(
|
||||
Radius.circular(20.h),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 8.h,
|
||||
children: [
|
||||
RequestStatus(status: order.statusId ?? 0),
|
||||
"Req ID: ${order.iD}".toText16(color: AppColors.textColor, weight: FontWeight.w600),
|
||||
Row(
|
||||
spacing: 4.w,
|
||||
children: [
|
||||
chip( Utils.getDayMonthYearDateFormatted(DateUtil.convertStringToDate(order.time)), AppAssets.calendar, AppColors.blackBgColor),
|
||||
chip("Rapid Response Team(RRT)".needTranslation, AppAssets.ic_rrt_vehicle, AppColors.blackBgColor),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4.h),
|
||||
if (order.statusId == 1 || order.statusId == 2)
|
||||
CustomButton(
|
||||
text: "Cancel Request".needTranslation,
|
||||
onPressed: () async {
|
||||
openCancelOrderBottomSheet(context);
|
||||
},
|
||||
backgroundColor: AppColors.primaryRedColor,
|
||||
borderColor: AppColors.primaryRedColor,
|
||||
textColor: Colors.white,
|
||||
icon: AppAssets.cancel,
|
||||
iconSize: 20.h,
|
||||
height: 40.h,
|
||||
),
|
||||
],
|
||||
).paddingAll(16.h),
|
||||
).paddingOnly(bottom: 16.h);
|
||||
}
|
||||
|
||||
chip(String title, String iconString, Color iconColor) {
|
||||
return AppCustomChipWidget(
|
||||
labelText: title,
|
||||
icon: iconString,
|
||||
iconColor: iconColor,
|
||||
iconSize: 12.h,
|
||||
);
|
||||
}
|
||||
|
||||
openCancelOrderBottomSheet(BuildContext context) {
|
||||
context.read<EmergencyServicesViewModel>().cancelRRTOrder(order.iD);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,248 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_staggered_animations/flutter_staggered_animations.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/features/hmg_services/hmg_services_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/home_health_care/widgets/hhc_ui_selection_helper.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.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 HhcOrderDetailPage extends StatefulWidget {
|
||||
const HhcOrderDetailPage({super.key});
|
||||
|
||||
@override
|
||||
State<HhcOrderDetailPage> createState() => _HhcOrderDetailPageState();
|
||||
}
|
||||
|
||||
class _HhcOrderDetailPageState extends State<HhcOrderDetailPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
|
||||
scheduleMicrotask(() async {
|
||||
await hmgServicesViewModel.getAllHhcOrders();
|
||||
});
|
||||
}
|
||||
|
||||
Color _getStatusColor(int? statusId) {
|
||||
switch (statusId) {
|
||||
case 1: // Pending
|
||||
return const Color(0xffCC9B14);
|
||||
case 2: // Processing
|
||||
return const Color(0xff2E303A);
|
||||
case 3: // Completed
|
||||
return const Color(0xff359846);
|
||||
case 4: // Cancelled
|
||||
case 6: // Rejected
|
||||
case 7: // Rejected
|
||||
return const Color(0xffD02127);
|
||||
default:
|
||||
return AppColors.greyColor;
|
||||
}
|
||||
}
|
||||
|
||||
String _formatDate(String? dateString) {
|
||||
if (dateString == null) return '';
|
||||
try {
|
||||
final date = DateTime.parse(dateString);
|
||||
return DateFormat('MMM dd, yyyy').format(date);
|
||||
} catch (e) {
|
||||
return dateString;
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildLoadingShimmer() {
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: 3,
|
||||
separatorBuilder: (_, __) => SizedBox(height: 12.h),
|
||||
itemBuilder: (context, index) {
|
||||
return _buildOrderCard(GetCMCAllOrdersResponseModel(), isLoading: true);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildOrderCard(GetCMCAllOrdersResponseModel order, {bool isLoading = false}) {
|
||||
final statusColor = _getStatusColor(order.statusId);
|
||||
final canCancel = order.statusId == 1 || order.statusId == 2;
|
||||
|
||||
return AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 24.h,
|
||||
hasShadow: true,
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Status and Date Row
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.h),
|
||||
decoration: BoxDecoration(
|
||||
color: statusColor.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
child: (isLoading ? "Processing" : order.statusText ?? '')
|
||||
.toText12(
|
||||
color: statusColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
)
|
||||
.toShimmer2(isShow: isLoading),
|
||||
),
|
||||
SizedBox(width: 8.w),
|
||||
(isLoading ? "Jan 15, 2024" : _formatDate(order.created))
|
||||
.toText12(
|
||||
color: AppColors.textColorLight,
|
||||
fontWeight: FontWeight.w500,
|
||||
)
|
||||
.toShimmer2(isShow: isLoading),
|
||||
],
|
||||
),
|
||||
|
||||
SizedBox(height: 16.h),
|
||||
|
||||
// Request ID
|
||||
Row(
|
||||
children: [
|
||||
if (!isLoading) ...[
|
||||
"Request ID:".needTranslation.toText14(
|
||||
color: AppColors.textColorLight,
|
||||
weight: FontWeight.w500,
|
||||
),
|
||||
SizedBox(width: 4.w),
|
||||
],
|
||||
(isLoading ? "12345" : "${order.iD ?? '-'}").toText16(isBold: true).toShimmer2(isShow: isLoading),
|
||||
],
|
||||
),
|
||||
|
||||
SizedBox(height: 12.h),
|
||||
|
||||
// Chips for Hospital, Service, and Amount
|
||||
Wrap(
|
||||
spacing: 6.w,
|
||||
runSpacing: 6.h,
|
||||
children: [
|
||||
// Service
|
||||
if (order.serviceText != null || isLoading)
|
||||
AppCustomChipWidget(
|
||||
icon: AppAssets.servicesBottom,
|
||||
labelText: isLoading ? "Service Name" : order.serviceText ?? '-',
|
||||
).toShimmer2(isShow: isLoading),
|
||||
],
|
||||
),
|
||||
|
||||
// Cancel Button
|
||||
if (canCancel || isLoading) ...[
|
||||
SizedBox(height: 16.h),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
text: "Cancel Order".needTranslation,
|
||||
onPressed: isLoading ? () {} : () => HhcUiSelectionHelper.showCancelConfirmationDialog(context: context, order: order),
|
||||
backgroundColor: AppColors.primaryRedColor,
|
||||
borderColor: AppColors.primaryRedColor,
|
||||
textColor: AppColors.whiteColor,
|
||||
fontSize: 14.f,
|
||||
fontWeight: FontWeight.w600,
|
||||
borderRadius: 10.r,
|
||||
height: 44.h,
|
||||
).toShimmer2(isShow: isLoading),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildEmptyState() {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 40.h),
|
||||
child: Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 12.r,
|
||||
hasShadow: false,
|
||||
),
|
||||
child: Utils.getNoDataWidget(
|
||||
context,
|
||||
noDataText: "You don't have any Home Health Care orders yet.".needTranslation,
|
||||
isSmallWidget: true,
|
||||
width: 62.w,
|
||||
height: 62.h,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CollapsingListView(
|
||||
title: "HHC Orders".needTranslation,
|
||||
isLeading: true,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Consumer<HmgServicesViewModel>(
|
||||
builder: (context, viewModel, child) {
|
||||
if (viewModel.isHhcOrdersLoading) {
|
||||
return _buildLoadingShimmer();
|
||||
}
|
||||
|
||||
if (viewModel.hhcOrdersList.isEmpty) {
|
||||
return _buildEmptyState();
|
||||
}
|
||||
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: viewModel.hhcOrdersList.length,
|
||||
separatorBuilder: (_, __) => SizedBox(height: 12.h),
|
||||
itemBuilder: (context, index) {
|
||||
final order = viewModel.hhcOrdersList.reversed.toList()[index];
|
||||
|
||||
return AnimationConfiguration.staggeredList(
|
||||
position: index,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: SlideAnimation(
|
||||
verticalOffset: 100.0,
|
||||
child: FadeInAnimation(
|
||||
child: _buildOrderCard(order),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
).paddingSymmetrical(24.w, 0),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,414 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.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/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/features/hmg_services/hmg_services_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/home_health_care/hhc_order_detail_page.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/home_health_care/hhc_selection_review_page.dart';
|
||||
import 'package:hmg_patient_app_new/presentation/home_health_care/widgets/hhc_ui_selection_helper.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
class HhcProceduresPage extends StatefulWidget {
|
||||
const HhcProceduresPage({super.key});
|
||||
|
||||
@override
|
||||
State<HhcProceduresPage> createState() => _HhcProceduresPageState();
|
||||
}
|
||||
|
||||
class _HhcProceduresPageState extends State<HhcProceduresPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
final HmgServicesViewModel hmgServicesViewModel = context.read<HmgServicesViewModel>();
|
||||
final AppState appState = getIt.get<AppState>();
|
||||
|
||||
scheduleMicrotask(() async {
|
||||
final user = appState.getAuthenticatedUser();
|
||||
if (user != null) {
|
||||
// Clear previous selections when entering the page
|
||||
hmgServicesViewModel.clearHhcServicesSelection();
|
||||
await hmgServicesViewModel.getAllHhcOrders();
|
||||
await hmgServicesViewModel.getAllHhcServices(patientID: user.patientId ?? 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
GetCMCAllOrdersResponseModel? _getPendingOrder(List<GetCMCAllOrdersResponseModel> orders) {
|
||||
if (orders.isEmpty) return null;
|
||||
|
||||
// Find pending or processing orders (status 1 or 2)
|
||||
for (var order in orders) {
|
||||
if (order.statusId == 1 || order.statusId == 2) {
|
||||
return order;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Widget _buildPendingOrderCard(GetCMCAllOrdersResponseModel order) {
|
||||
int status = order.statusId ?? 0;
|
||||
String statusDisp = order.statusText ?? "";
|
||||
Color statusColor;
|
||||
|
||||
if (status == 1) {
|
||||
// pending
|
||||
statusColor = AppColors.statusPendingColor;
|
||||
} else if (status == 2) {
|
||||
// processing
|
||||
statusColor = AppColors.statusProcessingColor;
|
||||
} else if (status == 3) {
|
||||
// completed
|
||||
statusColor = AppColors.statusCompletedColor;
|
||||
} else {
|
||||
// cancel / rejected
|
||||
statusColor = AppColors.statusRejectedColor;
|
||||
}
|
||||
|
||||
final canCancel = order.statusId == 1 || order.statusId == 2;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
margin: EdgeInsets.all(16.w),
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 24.h,
|
||||
hasShadow: true,
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Status and Date Row
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.h),
|
||||
decoration: BoxDecoration(
|
||||
color: statusColor.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
child: statusDisp.toText12(
|
||||
color: statusColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8.w),
|
||||
if (order.created != null)
|
||||
DateFormat('MMM dd, yyyy').format(DateTime.parse(order.created!)).toText12(
|
||||
color: AppColors.textColorLight,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
SizedBox(height: 16.h),
|
||||
|
||||
// Request ID
|
||||
Row(
|
||||
children: [
|
||||
"Request ID:".needTranslation.toText14(color: AppColors.textColorLight, weight: FontWeight.w500),
|
||||
SizedBox(width: 4.w),
|
||||
"${order.iD ?? '-'}".toText16(isBold: true),
|
||||
],
|
||||
),
|
||||
|
||||
SizedBox(height: 12.h),
|
||||
|
||||
// Info message
|
||||
Container(
|
||||
padding: EdgeInsets.all(12.w),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.infoBannerBgColor,
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
border: Border.all(
|
||||
color: AppColors.infoBannerBorderColor,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info_outline,
|
||||
size: 20.w,
|
||||
color: AppColors.infoBannerIconColor,
|
||||
),
|
||||
SizedBox(width: 8.w),
|
||||
Expanded(
|
||||
child: "You have a pending order. Please wait for it to be processed.".needTranslation.toText12(
|
||||
color: AppColors.infoBannerTextColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (canCancel) ...[
|
||||
SizedBox(height: 16.h),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
text: "Cancel Order".needTranslation,
|
||||
onPressed: () => HhcUiSelectionHelper.showCancelConfirmationDialog(context: context, order: order),
|
||||
backgroundColor: AppColors.primaryRedColor,
|
||||
borderColor: AppColors.primaryRedColor,
|
||||
textColor: AppColors.whiteColor,
|
||||
fontSize: 14.f,
|
||||
fontWeight: FontWeight.w600,
|
||||
borderRadius: 10.r,
|
||||
height: 44.h,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildServiceSelectionList(List<GetCMCServicesResponseModel> services) {
|
||||
if (services.isEmpty) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(24.h),
|
||||
child: Text(
|
||||
'No services available'.needTranslation,
|
||||
style: TextStyle(
|
||||
fontSize: 16.h,
|
||||
color: AppColors.greyTextColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Consumer<HmgServicesViewModel>(
|
||||
builder: (context, viewModel, child) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 8.h),
|
||||
if (viewModel.selectedHhcServices.isNotEmpty) ...[
|
||||
SizedBox(height: 16.h),
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 16.w),
|
||||
padding: EdgeInsets.all(16.w),
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.primaryRedColor.withValues(alpha: 0.1),
|
||||
borderRadius: 16.r,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
"Selected Services".needTranslation.toText12(
|
||||
color: AppColors.textColorLight,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
"${viewModel.selectedHhcServices.length} service(s) selected".toText14(
|
||||
isBold: true,
|
||||
weight: FontWeight.bold,
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
"Total Amount".needTranslation.toText12(
|
||||
color: AppColors.textColorLight,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
Utils.getPaymentAmountWithSymbol(
|
||||
viewModel.getHhcSelectedServicesTotal().toStringAsFixed(2).toText16(
|
||||
isBold: true,
|
||||
weight: FontWeight.bold,
|
||||
color: AppColors.primaryRedColor,
|
||||
),
|
||||
AppColors.primaryRedColor,
|
||||
14,
|
||||
isSaudiCurrency: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
SizedBox(height: 16.h),
|
||||
Text(
|
||||
'Select Services'.needTranslation,
|
||||
style: TextStyle(
|
||||
fontSize: 20.h,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.blackColor,
|
||||
letterSpacing: -0.8,
|
||||
),
|
||||
).paddingOnly(left: 16.w, right: 16.w),
|
||||
SizedBox(height: 12.h),
|
||||
ListView.builder(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.w),
|
||||
itemCount: services.length,
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
final service = services[index];
|
||||
final isSelected = viewModel.isHhcServiceSelected(service);
|
||||
final isArabic = getIt.get<AppState>().isArabic();
|
||||
final serviceName = isArabic ? (service.textN ?? service.text ?? '') : (service.text ?? '');
|
||||
|
||||
return AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
margin: EdgeInsets.only(bottom: 12.h),
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 16.r,
|
||||
hasShadow: true,
|
||||
),
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () => viewModel.toggleHhcServiceSelection(service),
|
||||
borderRadius: BorderRadius.circular(16.r),
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: isSelected,
|
||||
onChanged: (v) => viewModel.toggleHhcServiceSelection(service),
|
||||
activeColor: AppColors.primaryRedColor,
|
||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
visualDensity: VisualDensity.compact,
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
serviceName.toText16(
|
||||
weight: FontWeight.w400,
|
||||
color: AppColors.blackColor,
|
||||
maxlines: 2,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
// Summary Section
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _proceedWithSelectedService() {
|
||||
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
|
||||
if (hmgServicesViewModel.selectedHhcServices.isNotEmpty) {
|
||||
hmgServicesViewModel.setSelectedServiceForHhcOrder(hmgServicesViewModel.selectedHhcServices.first);
|
||||
Navigator.of(context).pushReplacement(
|
||||
CustomPageRoute(
|
||||
page: HhcSelectionReviewPage(selectedServices: hmgServicesViewModel.selectedHhcServices),
|
||||
direction: AxisDirection.left,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildLoadingShimmer() {
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
padding: EdgeInsets.all(16.w),
|
||||
itemCount: 10,
|
||||
separatorBuilder: (_, __) => SizedBox(height: 12.h),
|
||||
itemBuilder: (context, index) {
|
||||
return Shimmer.fromColors(
|
||||
baseColor: Colors.grey[300]!,
|
||||
highlightColor: Colors.grey[100]!,
|
||||
child: Container(
|
||||
height: 80.h,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CollapsingListView(
|
||||
title: "Home Health Care".needTranslation,
|
||||
history: () => Navigator.of(context).push(CustomPageRoute(page: HhcOrderDetailPage(), direction: AxisDirection.up)),
|
||||
bottomChild: Consumer<HmgServicesViewModel>(
|
||||
builder: (context, hmgServicesViewModel, child) {
|
||||
if (hmgServicesViewModel.isHhcOrdersLoading || hmgServicesViewModel.isHhcServicesLoading) return SizedBox.shrink();
|
||||
final pendingOrder = _getPendingOrder(hmgServicesViewModel.hhcOrdersList);
|
||||
if (pendingOrder == null && hmgServicesViewModel.selectedHhcServices.isNotEmpty) {
|
||||
return SafeArea(
|
||||
top: false,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: 16.w, right: 16.w, top: 12.h),
|
||||
child: CustomButton(
|
||||
borderWidth: 0,
|
||||
text: "Next".needTranslation,
|
||||
onPressed: _proceedWithSelectedService,
|
||||
textColor: AppColors.whiteColor,
|
||||
borderRadius: 12.r,
|
||||
borderColor: Colors.transparent,
|
||||
padding: EdgeInsets.symmetric(vertical: 14.h),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
child: Consumer<HmgServicesViewModel>(
|
||||
builder: (context, hmgServicesViewModel, child) {
|
||||
if (hmgServicesViewModel.isHhcOrdersLoading || hmgServicesViewModel.isHhcServicesLoading) {
|
||||
return _buildLoadingShimmer();
|
||||
}
|
||||
final pendingOrder = _getPendingOrder(hmgServicesViewModel.hhcOrdersList);
|
||||
if (pendingOrder != null) {
|
||||
return _buildPendingOrderCard(pendingOrder);
|
||||
} else {
|
||||
return _buildServiceSelectionList(hmgServicesViewModel.hhcServicesList);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,244 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.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/size_utils.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/utils.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/route_extensions.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/hmg_services/hmg_services_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/cmc_create_new_order_req_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_services_resp_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
|
||||
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/appbar/collapsing_list_view.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
|
||||
import 'package:maps_launcher/maps_launcher.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class HhcSelectionReviewPage extends StatefulWidget {
|
||||
final List<GetCMCServicesResponseModel> selectedServices;
|
||||
|
||||
const HhcSelectionReviewPage({super.key, required this.selectedServices});
|
||||
|
||||
@override
|
||||
State<HhcSelectionReviewPage> createState() => _HhcSelectionReviewPageState();
|
||||
}
|
||||
|
||||
class _HhcSelectionReviewPageState extends State<HhcSelectionReviewPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// Initialize ViewModel state with selected services
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
|
||||
if (widget.selectedServices.isNotEmpty) {
|
||||
hmgServicesViewModel.setSelectedServiceForHhcOrder(widget.selectedServices.first);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final appState = getIt.get<AppState>();
|
||||
final isArabic = appState.isArabic();
|
||||
|
||||
return CollapsingListView(
|
||||
title: "Summary".needTranslation,
|
||||
bottomChild: _buildBottomButton(),
|
||||
child: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildSelectedServicesCard(isArabic),
|
||||
SizedBox(height: 16.h),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSelectedServicesCard(bool isArabic) {
|
||||
return Container(
|
||||
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: 16.r,
|
||||
),
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
"Selected Services".needTranslation.toText14(
|
||||
weight: FontWeight.w600,
|
||||
color: AppColors.greyTextColor,
|
||||
letterSpacing: -0.4,
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
...widget.selectedServices.map((service) {
|
||||
final serviceName = isArabic ? (service.textN ?? service.text ?? '') : (service.text ?? '');
|
||||
final price = service.priceTotal ?? 0.0;
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: 4.h),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: serviceName.toText14(
|
||||
weight: FontWeight.w600,
|
||||
color: AppColors.blackColor,
|
||||
letterSpacing: -0.5,
|
||||
maxlines: 2,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBottomButton() {
|
||||
return SafeArea(
|
||||
top: false,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color.fromARGB(13, 0, 0, 0),
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, -2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: CustomButton(
|
||||
text: "Confirm".needTranslation,
|
||||
onPressed: _handleConfirm,
|
||||
textColor: AppColors.whiteColor,
|
||||
backgroundColor: AppColors.successColor,
|
||||
borderRadius: 12.r,
|
||||
borderColor: Colors.transparent,
|
||||
borderWidth: 0,
|
||||
padding: EdgeInsets.symmetric(vertical: 14.h),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _launchDirections(HospitalsModel selectedHospital) {
|
||||
final double lat = double.parse(selectedHospital.latitude ?? "0.0");
|
||||
final double lng = double.parse(selectedHospital.longitude ?? "0.0");
|
||||
|
||||
if (lat != 0.0 && lng != 0.0) {
|
||||
MapsLauncher.launchCoordinates(
|
||||
lat,
|
||||
lng,
|
||||
selectedHospital.name ?? "Hospital",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
showSuccessBottomSheet(int requestId, HmgServicesViewModel hmgServicesViewModel) {
|
||||
return showCommonBottomSheetWithoutHeight(
|
||||
context,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Column(
|
||||
children: [
|
||||
Utils.getSuccessWidget(loadingText: "Your request has been successfully submitted.".needTranslation),
|
||||
Row(
|
||||
children: [
|
||||
"Here is your request #: ".needTranslation.toText14(
|
||||
color: AppColors.textColorLight,
|
||||
weight: FontWeight.w500,
|
||||
),
|
||||
SizedBox(width: 4.w),
|
||||
("$requestId").toText16(isBold: true),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 24.h),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 56.h,
|
||||
text: LocaleKeys.ok.tr(),
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
context.pop();
|
||||
hmgServicesViewModel.getAllHhcOrders();
|
||||
},
|
||||
textColor: AppColors.whiteColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
isCloseButtonVisible: false,
|
||||
isDismissible: false,
|
||||
isFullScreen: false,
|
||||
);
|
||||
}
|
||||
|
||||
void _handleConfirm() {
|
||||
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
|
||||
final appState = getIt.get<AppState>();
|
||||
|
||||
return showCommonBottomSheetWithoutHeight(
|
||||
title: LocaleKeys.notice.tr(context: context),
|
||||
context,
|
||||
child: Utils.getWarningWidget(
|
||||
loadingText: "Are you sure you want to submit this request?".needTranslation,
|
||||
isShowActionButtons: true,
|
||||
onCancelTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onConfirmTap: () async {
|
||||
Navigator.pop(context);
|
||||
LoaderBottomSheet.showLoader();
|
||||
|
||||
// Create the services list from all selected services
|
||||
final servicesList = widget.selectedServices.map((selectedService) {
|
||||
return PatientERCMCInsertServicesList(
|
||||
recordID: selectedService.iD,
|
||||
serviceID: selectedService.serviceID,
|
||||
selectedServiceName: selectedService.text,
|
||||
selectedServiceNameAR: selectedService.textN,
|
||||
price: selectedService.price,
|
||||
vAT: selectedService.priceVAT,
|
||||
totalPrice: selectedService.priceTotal,
|
||||
);
|
||||
}).toList();
|
||||
|
||||
// For HHC, we don't need hospital selection, use a default projectID or 0
|
||||
await hmgServicesViewModel.addHhcOrder(
|
||||
projectID: 0,
|
||||
// HHC doesn't require hospital/project selection
|
||||
orderServiceID: widget.selectedServices.first.orderServiceID ?? 4,
|
||||
// HHC service ID
|
||||
services: servicesList,
|
||||
onSuccess: (requestId) {
|
||||
LoaderBottomSheet.hideLoader();
|
||||
showSuccessBottomSheet(requestId, hmgServicesViewModel);
|
||||
},
|
||||
onError: (err) {
|
||||
LoaderBottomSheet.hideLoader();
|
||||
},
|
||||
);
|
||||
}),
|
||||
callBackFunc: () {},
|
||||
isFullScreen: false,
|
||||
isCloseButtonVisible: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
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';
|
||||
import 'package:hmg_patient_app_new/extensions/route_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/order_update_req_model.dart';
|
||||
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_cmc_all_orders_resp_model.dart';
|
||||
import 'package:hmg_patient_app_new/generated/locale_keys.g.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/common_bottom_sheet.dart';
|
||||
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class HhcUiSelectionHelper {
|
||||
static void showCancelConfirmationDialog({
|
||||
required BuildContext context,
|
||||
required GetCMCAllOrdersResponseModel order,
|
||||
}) {
|
||||
final HmgServicesViewModel hmgServicesViewModel = context.read<HmgServicesViewModel>();
|
||||
|
||||
return showCommonBottomSheetWithoutHeight(
|
||||
title: LocaleKeys.notice.tr(context: context),
|
||||
context,
|
||||
child: Utils.getWarningWidget(
|
||||
loadingText: "Are you sure you want to cancel this order?".needTranslation,
|
||||
isShowActionButtons: true,
|
||||
onCancelTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onConfirmTap: () async {
|
||||
Navigator.pop(context);
|
||||
LoaderBottomSheet.showLoader();
|
||||
|
||||
final requestModel = OrderUpdateRequestModel(
|
||||
presOrderID: order.iD,
|
||||
rejectionReason: "Cancelled by user",
|
||||
presOrderStatus: 4, // Cancelled status
|
||||
editedBy: 3,
|
||||
);
|
||||
|
||||
await hmgServicesViewModel.updateHhcPresOrder(
|
||||
requestModel: requestModel,
|
||||
onSuccess: (_) async {
|
||||
LoaderBottomSheet.hideLoader();
|
||||
showCommonBottomSheetWithoutHeight(
|
||||
context,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Column(
|
||||
children: [
|
||||
Utils.getSuccessWidget(loadingText: "Order has been cancelled successfully".needTranslation),
|
||||
SizedBox(height: 24.h),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomButton(
|
||||
height: 56.h,
|
||||
text: LocaleKeys.ok.tr(),
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
hmgServicesViewModel.getAllHhcOrders();
|
||||
},
|
||||
textColor: AppColors.whiteColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
isCloseButtonVisible: false,
|
||||
isDismissible: false,
|
||||
isFullScreen: false,
|
||||
);
|
||||
},
|
||||
onError: (error) {
|
||||
LoaderBottomSheet.hideLoader();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
callBackFunc: () {},
|
||||
isFullScreen: false,
|
||||
isCloseButtonVisible: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -1,23 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
|
||||
class ServicesPage extends StatelessWidget {
|
||||
const ServicesPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.bgScaffoldColor,
|
||||
appBar: AppBar(
|
||||
title: const Text('Appointments'),
|
||||
backgroundColor: AppColors.bgScaffoldColor,
|
||||
),
|
||||
body: const Center(
|
||||
child: Text(
|
||||
'Appointments Page',
|
||||
style: TextStyle(fontSize: 24),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue