commit
a3d89c7afa
@ -0,0 +1,57 @@
|
|||||||
|
class CheckActivationCodeForEReferralRequestModel {
|
||||||
|
String? logInTokenID;
|
||||||
|
String? activationCode;
|
||||||
|
double? versionID;
|
||||||
|
int? channel;
|
||||||
|
int? languageID;
|
||||||
|
String? iPAdress;
|
||||||
|
String? generalid;
|
||||||
|
int? patientOutSA;
|
||||||
|
dynamic sessionID;
|
||||||
|
bool? isDentalAllowedBackend;
|
||||||
|
int? deviceTypeID;
|
||||||
|
|
||||||
|
CheckActivationCodeForEReferralRequestModel(
|
||||||
|
{this.logInTokenID,
|
||||||
|
this.activationCode,
|
||||||
|
this.versionID,
|
||||||
|
this.channel,
|
||||||
|
this.languageID,
|
||||||
|
this.iPAdress,
|
||||||
|
this.generalid,
|
||||||
|
this.patientOutSA,
|
||||||
|
this.sessionID,
|
||||||
|
this.isDentalAllowedBackend,
|
||||||
|
this.deviceTypeID});
|
||||||
|
|
||||||
|
CheckActivationCodeForEReferralRequestModel.fromJson(
|
||||||
|
Map<String, dynamic> json) {
|
||||||
|
logInTokenID = json['LogInTokenID'];
|
||||||
|
activationCode = json['activationCode'];
|
||||||
|
versionID = json['VersionID'];
|
||||||
|
channel = json['Channel'];
|
||||||
|
languageID = json['LanguageID'];
|
||||||
|
iPAdress = json['IPAdress'];
|
||||||
|
generalid = json['generalid'];
|
||||||
|
patientOutSA = json['PatientOutSA'];
|
||||||
|
sessionID = json['SessionID'];
|
||||||
|
isDentalAllowedBackend = json['isDentalAllowedBackend'];
|
||||||
|
deviceTypeID = json['DeviceTypeID'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['LogInTokenID'] = this.logInTokenID;
|
||||||
|
data['activationCode'] = this.activationCode;
|
||||||
|
data['VersionID'] = this.versionID;
|
||||||
|
data['Channel'] = this.channel;
|
||||||
|
data['LanguageID'] = this.languageID;
|
||||||
|
data['IPAdress'] = this.iPAdress;
|
||||||
|
data['generalid'] = this.generalid;
|
||||||
|
data['PatientOutSA'] = this.patientOutSA;
|
||||||
|
data['SessionID'] = this.sessionID;
|
||||||
|
data['isDentalAllowedBackend'] = this.isDentalAllowedBackend;
|
||||||
|
data['DeviceTypeID'] = this.deviceTypeID;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,155 @@
|
|||||||
|
class CreateEReferralRequestModel {
|
||||||
|
bool? isInsuredPatient;
|
||||||
|
String? cityCode;
|
||||||
|
String? cityName;
|
||||||
|
String? requesterName;
|
||||||
|
String? requesterContactNo;
|
||||||
|
int? requesterRelationship;
|
||||||
|
String? otherRelationship;
|
||||||
|
String? fullName;
|
||||||
|
int? identificationNo;
|
||||||
|
String? patientMobileNumber;
|
||||||
|
int? preferredBranchCode;
|
||||||
|
String? preferredBranchName;
|
||||||
|
List<EReferralAttachment>? medicalReportAttachment;
|
||||||
|
dynamic insuranceCardAttachment;
|
||||||
|
double? versionID;
|
||||||
|
int? channel;
|
||||||
|
int? languageID;
|
||||||
|
String? iPAdress;
|
||||||
|
String? generalid;
|
||||||
|
int? patientOutSA;
|
||||||
|
String? sessionID;
|
||||||
|
bool? isDentalAllowedBackend;
|
||||||
|
int? deviceTypeID;
|
||||||
|
int? patientID;
|
||||||
|
String? tokenID;
|
||||||
|
int? patientTypeID;
|
||||||
|
int? patientType;
|
||||||
|
|
||||||
|
CreateEReferralRequestModel(
|
||||||
|
{this.isInsuredPatient,
|
||||||
|
this.cityCode,
|
||||||
|
this.cityName,
|
||||||
|
this.requesterName,
|
||||||
|
this.requesterContactNo,
|
||||||
|
this.requesterRelationship,
|
||||||
|
this.otherRelationship,
|
||||||
|
this.fullName,
|
||||||
|
this.identificationNo,
|
||||||
|
this.patientMobileNumber,
|
||||||
|
this.preferredBranchCode,
|
||||||
|
this.preferredBranchName,
|
||||||
|
this.medicalReportAttachment,
|
||||||
|
this.insuranceCardAttachment,
|
||||||
|
this.versionID,
|
||||||
|
this.channel,
|
||||||
|
this.languageID,
|
||||||
|
this.iPAdress,
|
||||||
|
this.generalid,
|
||||||
|
this.patientOutSA,
|
||||||
|
this.sessionID,
|
||||||
|
this.isDentalAllowedBackend,
|
||||||
|
this.deviceTypeID,
|
||||||
|
this.patientID,
|
||||||
|
this.tokenID,
|
||||||
|
this.patientTypeID,
|
||||||
|
this.patientType});
|
||||||
|
|
||||||
|
CreateEReferralRequestModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
isInsuredPatient = json['IsInsuredPatient'];
|
||||||
|
cityCode = json['CityCode'];
|
||||||
|
cityName = json['CityName'];
|
||||||
|
requesterName = json['RequesterName'];
|
||||||
|
requesterContactNo = json['RequesterContactNo'];
|
||||||
|
requesterRelationship = json['RequesterRelationship'];
|
||||||
|
otherRelationship = json['OtherRelationship'];
|
||||||
|
fullName = json['FullName'];
|
||||||
|
identificationNo = json['IdentificationNo'];
|
||||||
|
patientMobileNumber = json['PatientMobileNumber'];
|
||||||
|
preferredBranchCode = json['PreferredBranchCode'];
|
||||||
|
preferredBranchName = json['PreferredBranchName'];
|
||||||
|
if (json['MedicalReportAttachment'] != null) {
|
||||||
|
medicalReportAttachment = <EReferralAttachment>[];
|
||||||
|
json['MedicalReportAttachment'].forEach((v) {
|
||||||
|
medicalReportAttachment!.add(EReferralAttachment.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
insuranceCardAttachment = json['InsuranceCardAttachment'] != null ? EReferralAttachment.fromJson(json['InsuranceCardAttachment']) : null;
|
||||||
|
versionID = json['VersionID'];
|
||||||
|
channel = json['Channel'];
|
||||||
|
languageID = json['LanguageID'];
|
||||||
|
iPAdress = json['IPAdress'];
|
||||||
|
generalid = json['generalid'];
|
||||||
|
patientOutSA = json['PatientOutSA'];
|
||||||
|
sessionID = json['SessionID'];
|
||||||
|
isDentalAllowedBackend = json['isDentalAllowedBackend'];
|
||||||
|
deviceTypeID = json['DeviceTypeID'];
|
||||||
|
patientID = json['PatientID'];
|
||||||
|
tokenID = json['TokenID'];
|
||||||
|
patientTypeID = json['PatientTypeID'];
|
||||||
|
patientType = json['PatientType'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['IsInsuredPatient'] = this.isInsuredPatient;
|
||||||
|
data['CityCode'] = this.cityCode;
|
||||||
|
data['CityName'] = this.cityName;
|
||||||
|
data['RequesterName'] = this.requesterName;
|
||||||
|
data['RequesterContactNo'] = this.requesterContactNo;
|
||||||
|
data['RequesterRelationship'] = this.requesterRelationship;
|
||||||
|
data['OtherRelationship'] = this.otherRelationship;
|
||||||
|
data['FullName'] = this.fullName;
|
||||||
|
data['IdentificationNo'] = this.identificationNo;
|
||||||
|
data['PatientMobileNumber'] = this.patientMobileNumber;
|
||||||
|
data['PreferredBranchCode'] = this.preferredBranchCode;
|
||||||
|
data['PreferredBranchName'] = this.preferredBranchName;
|
||||||
|
if (this.medicalReportAttachment != null) {
|
||||||
|
// FIXED: Use map() to convert each item to JSON, then convert to list
|
||||||
|
data['MedicalReportAttachment'] = this.medicalReportAttachment!.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
if (this.insuranceCardAttachment == null) {
|
||||||
|
data['InsuranceCardAttachment'] = {};
|
||||||
|
} else if (this.insuranceCardAttachment is EReferralAttachment) {
|
||||||
|
// FIXED: Check if it's an EReferralAttachment before calling toJson()
|
||||||
|
data['InsuranceCardAttachment'] = (this.insuranceCardAttachment as EReferralAttachment).toJson();
|
||||||
|
} else {
|
||||||
|
// If it's something else, assign directly
|
||||||
|
data['InsuranceCardAttachment'] = this.insuranceCardAttachment;
|
||||||
|
}
|
||||||
|
data['VersionID'] = this.versionID;
|
||||||
|
data['Channel'] = this.channel;
|
||||||
|
data['LanguageID'] = this.languageID;
|
||||||
|
data['IPAdress'] = this.iPAdress;
|
||||||
|
data['generalid'] = this.generalid;
|
||||||
|
data['PatientOutSA'] = this.patientOutSA;
|
||||||
|
data['SessionID'] = this.sessionID;
|
||||||
|
data['isDentalAllowedBackend'] = this.isDentalAllowedBackend;
|
||||||
|
data['DeviceTypeID'] = this.deviceTypeID;
|
||||||
|
data['PatientID'] = this.patientID;
|
||||||
|
data['TokenID'] = this.tokenID;
|
||||||
|
data['PatientTypeID'] = this.patientTypeID;
|
||||||
|
data['PatientType'] = this.patientType;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EReferralAttachment {
|
||||||
|
String? fileName;
|
||||||
|
String? base64String;
|
||||||
|
|
||||||
|
EReferralAttachment({this.fileName, this.base64String});
|
||||||
|
|
||||||
|
EReferralAttachment.fromJson(Map<String, dynamic> json) {
|
||||||
|
fileName = json['FileName'];
|
||||||
|
base64String = json['Base64String'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['FileName'] = this.fileName;
|
||||||
|
data['Base64String'] = this.base64String;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,150 @@
|
|||||||
|
class CreateEReferralRequestModel {
|
||||||
|
bool? isInsuredPatient;
|
||||||
|
String? cityCode;
|
||||||
|
String? cityName;
|
||||||
|
String? requesterName;
|
||||||
|
String? requesterContactNo;
|
||||||
|
int? requesterRelationship;
|
||||||
|
String? otherRelationship;
|
||||||
|
String? fullName;
|
||||||
|
int? identificationNo;
|
||||||
|
String? patientMobileNumber;
|
||||||
|
int? preferredBranchCode;
|
||||||
|
String? preferredBranchName;
|
||||||
|
List<EReferralAttachment>? medicalReportAttachment;
|
||||||
|
dynamic insuranceCardAttachment;
|
||||||
|
double? versionID;
|
||||||
|
int? channel;
|
||||||
|
int? languageID;
|
||||||
|
String? iPAdress;
|
||||||
|
String? generalid;
|
||||||
|
int? patientOutSA;
|
||||||
|
String? sessionID;
|
||||||
|
bool? isDentalAllowedBackend;
|
||||||
|
int? deviceTypeID;
|
||||||
|
int? patientID;
|
||||||
|
String? tokenID;
|
||||||
|
int? patientTypeID;
|
||||||
|
int? patientType;
|
||||||
|
|
||||||
|
CreateEReferralRequestModel(
|
||||||
|
{this.isInsuredPatient,
|
||||||
|
this.cityCode,
|
||||||
|
this.cityName,
|
||||||
|
this.requesterName,
|
||||||
|
this.requesterContactNo,
|
||||||
|
this.requesterRelationship,
|
||||||
|
this.otherRelationship,
|
||||||
|
this.fullName,
|
||||||
|
this.identificationNo,
|
||||||
|
this.patientMobileNumber,
|
||||||
|
this.preferredBranchCode,
|
||||||
|
this.preferredBranchName,
|
||||||
|
this.medicalReportAttachment,
|
||||||
|
this.insuranceCardAttachment,
|
||||||
|
this.versionID,
|
||||||
|
this.channel,
|
||||||
|
this.languageID,
|
||||||
|
this.iPAdress,
|
||||||
|
this.generalid,
|
||||||
|
this.patientOutSA,
|
||||||
|
this.sessionID,
|
||||||
|
this.isDentalAllowedBackend,
|
||||||
|
this.deviceTypeID,
|
||||||
|
this.patientID,
|
||||||
|
this.tokenID,
|
||||||
|
this.patientTypeID,
|
||||||
|
this.patientType});
|
||||||
|
|
||||||
|
CreateEReferralRequestModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
isInsuredPatient = json['IsInsuredPatient'];
|
||||||
|
cityCode = json['CityCode'];
|
||||||
|
cityName = json['CityName'];
|
||||||
|
requesterName = json['RequesterName'];
|
||||||
|
requesterContactNo = json['RequesterContactNo'];
|
||||||
|
requesterRelationship = json['RequesterRelationship'];
|
||||||
|
otherRelationship = json['OtherRelationship'];
|
||||||
|
fullName = json['FullName'];
|
||||||
|
identificationNo = json['IdentificationNo'];
|
||||||
|
patientMobileNumber = json['PatientMobileNumber'];
|
||||||
|
preferredBranchCode = json['PreferredBranchCode'];
|
||||||
|
preferredBranchName = json['PreferredBranchName'];
|
||||||
|
if (json['MedicalReportAttachment'] != null) {
|
||||||
|
medicalReportAttachment = <EReferralAttachment>[];
|
||||||
|
json['MedicalReportAttachment'].forEach((v) {
|
||||||
|
medicalReportAttachment!.add(EReferralAttachment.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
insuranceCardAttachment = json['InsuranceCardAttachment'] != null ? EReferralAttachment.fromJson(json['InsuranceCardAttachment']) : null;
|
||||||
|
versionID = json['VersionID'];
|
||||||
|
channel = json['Channel'];
|
||||||
|
languageID = json['LanguageID'];
|
||||||
|
iPAdress = json['IPAdress'];
|
||||||
|
generalid = json['generalid'];
|
||||||
|
patientOutSA = json['PatientOutSA'];
|
||||||
|
sessionID = json['SessionID'];
|
||||||
|
isDentalAllowedBackend = json['isDentalAllowedBackend'];
|
||||||
|
deviceTypeID = json['DeviceTypeID'];
|
||||||
|
patientID = json['PatientID'];
|
||||||
|
tokenID = json['TokenID'];
|
||||||
|
patientTypeID = json['PatientTypeID'];
|
||||||
|
patientType = json['PatientType'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['IsInsuredPatient'] = this.isInsuredPatient;
|
||||||
|
data['CityCode'] = this.cityCode;
|
||||||
|
data['CityName'] = this.cityName;
|
||||||
|
data['RequesterName'] = this.requesterName;
|
||||||
|
data['RequesterContactNo'] = this.requesterContactNo;
|
||||||
|
data['RequesterRelationship'] = this.requesterRelationship;
|
||||||
|
data['OtherRelationship'] = this.otherRelationship;
|
||||||
|
data['FullName'] = this.fullName;
|
||||||
|
data['IdentificationNo'] = this.identificationNo;
|
||||||
|
data['PatientMobileNumber'] = this.patientMobileNumber;
|
||||||
|
data['PreferredBranchCode'] = this.preferredBranchCode;
|
||||||
|
data['PreferredBranchName'] = this.preferredBranchName;
|
||||||
|
if (this.medicalReportAttachment != null) {
|
||||||
|
data['MedicalReportAttachment'] = this.medicalReportAttachment!.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
if (this.insuranceCardAttachment == null) {
|
||||||
|
data['InsuranceCardAttachment'] = {};
|
||||||
|
} else
|
||||||
|
data['InsuranceCardAttachment'] = this.insuranceCardAttachment.toJson();
|
||||||
|
|
||||||
|
data['VersionID'] = this.versionID;
|
||||||
|
data['Channel'] = this.channel;
|
||||||
|
data['LanguageID'] = this.languageID;
|
||||||
|
data['IPAdress'] = this.iPAdress;
|
||||||
|
data['generalid'] = this.generalid;
|
||||||
|
data['PatientOutSA'] = this.patientOutSA;
|
||||||
|
data['SessionID'] = this.sessionID;
|
||||||
|
data['isDentalAllowedBackend'] = this.isDentalAllowedBackend;
|
||||||
|
data['DeviceTypeID'] = this.deviceTypeID;
|
||||||
|
data['PatientID'] = this.patientID;
|
||||||
|
data['TokenID'] = this.tokenID;
|
||||||
|
data['PatientTypeID'] = this.patientTypeID;
|
||||||
|
data['PatientType'] = this.patientType;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EReferralAttachment {
|
||||||
|
String? fileName;
|
||||||
|
String? base64String;
|
||||||
|
|
||||||
|
EReferralAttachment({this.fileName, this.base64String});
|
||||||
|
|
||||||
|
EReferralAttachment.fromJson(Map<String, dynamic> json) {
|
||||||
|
fileName = json['FileName'];
|
||||||
|
base64String = json['Base64String'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['FileName'] = this.fileName;
|
||||||
|
data['Base64String'] = this.base64String;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
class SearchEReferralRequestModel {
|
||||||
|
String? patientMobileNumber;
|
||||||
|
double? versionID;
|
||||||
|
int? channel;
|
||||||
|
int? languageID;
|
||||||
|
String? iPAdress;
|
||||||
|
String? generalid;
|
||||||
|
int? patientOutSA;
|
||||||
|
dynamic sessionID;
|
||||||
|
bool? isDentalAllowedBackend;
|
||||||
|
int? deviceTypeID;
|
||||||
|
int? referralNumber;
|
||||||
|
String? identificationNo;
|
||||||
|
|
||||||
|
SearchEReferralRequestModel(
|
||||||
|
{this.patientMobileNumber,
|
||||||
|
this.versionID,
|
||||||
|
this.channel,
|
||||||
|
this.languageID,
|
||||||
|
this.iPAdress,
|
||||||
|
this.generalid,
|
||||||
|
this.patientOutSA,
|
||||||
|
this.sessionID,
|
||||||
|
this.isDentalAllowedBackend,
|
||||||
|
this.deviceTypeID,
|
||||||
|
this.referralNumber,
|
||||||
|
this.identificationNo});
|
||||||
|
|
||||||
|
SearchEReferralRequestModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
patientMobileNumber = json['PatientMobileNumber'];
|
||||||
|
versionID = json['VersionID'];
|
||||||
|
channel = json['Channel'];
|
||||||
|
languageID = json['LanguageID'];
|
||||||
|
iPAdress = json['IPAdress'];
|
||||||
|
generalid = json['generalid'];
|
||||||
|
patientOutSA = json['PatientOutSA'];
|
||||||
|
sessionID = json['SessionID'];
|
||||||
|
isDentalAllowedBackend = json['isDentalAllowedBackend'];
|
||||||
|
deviceTypeID = json['DeviceTypeID'];
|
||||||
|
referralNumber = json['ReferralNumber'];
|
||||||
|
identificationNo = json['IdentificationNo'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['PatientMobileNumber'] = this.patientMobileNumber;
|
||||||
|
data['VersionID'] = this.versionID;
|
||||||
|
data['Channel'] = this.channel;
|
||||||
|
data['LanguageID'] = this.languageID;
|
||||||
|
data['IPAdress'] = this.iPAdress;
|
||||||
|
data['generalid'] = this.generalid;
|
||||||
|
data['PatientOutSA'] = this.patientOutSA;
|
||||||
|
data['SessionID'] = this.sessionID;
|
||||||
|
data['isDentalAllowedBackend'] = this.isDentalAllowedBackend;
|
||||||
|
data['DeviceTypeID'] = this.deviceTypeID;
|
||||||
|
data['ReferralNumber'] = this.referralNumber;
|
||||||
|
data['IdentificationNo'] = this.identificationNo;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
class SendActivationCodeForEReferralRequestModel {
|
||||||
|
int? patientMobileNumber;
|
||||||
|
String? zipCode;
|
||||||
|
double? versionID;
|
||||||
|
int? channel;
|
||||||
|
int? languageID;
|
||||||
|
String? iPAdress;
|
||||||
|
String? generalid;
|
||||||
|
int? patientOutSA;
|
||||||
|
dynamic sessionID;
|
||||||
|
bool? isDentalAllowedBackend;
|
||||||
|
int? deviceTypeID;
|
||||||
|
|
||||||
|
SendActivationCodeForEReferralRequestModel(
|
||||||
|
{this.patientMobileNumber,
|
||||||
|
this.zipCode,
|
||||||
|
this.versionID,
|
||||||
|
this.channel,
|
||||||
|
this.languageID,
|
||||||
|
this.iPAdress,
|
||||||
|
this.generalid,
|
||||||
|
this.patientOutSA,
|
||||||
|
this.sessionID,
|
||||||
|
this.isDentalAllowedBackend,
|
||||||
|
this.deviceTypeID});
|
||||||
|
|
||||||
|
SendActivationCodeForEReferralRequestModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
patientMobileNumber = json['PatientMobileNumber'];
|
||||||
|
zipCode = json['ZipCode'];
|
||||||
|
versionID = json['VersionID'];
|
||||||
|
channel = json['Channel'];
|
||||||
|
languageID = json['LanguageID'];
|
||||||
|
iPAdress = json['IPAdress'];
|
||||||
|
generalid = json['generalid'];
|
||||||
|
patientOutSA = json['PatientOutSA'];
|
||||||
|
sessionID = json['SessionID'];
|
||||||
|
isDentalAllowedBackend = json['isDentalAllowedBackend'];
|
||||||
|
deviceTypeID = json['DeviceTypeID'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['PatientMobileNumber'] = this.patientMobileNumber;
|
||||||
|
data['ZipCode'] = this.zipCode;
|
||||||
|
data['VersionID'] = this.versionID;
|
||||||
|
data['Channel'] = this.channel;
|
||||||
|
data['LanguageID'] = this.languageID;
|
||||||
|
data['IPAdress'] = this.iPAdress;
|
||||||
|
data['generalid'] = this.generalid;
|
||||||
|
data['PatientOutSA'] = this.patientOutSA;
|
||||||
|
data['SessionID'] = this.sessionID;
|
||||||
|
data['isDentalAllowedBackend'] = this.isDentalAllowedBackend;
|
||||||
|
data['DeviceTypeID'] = this.deviceTypeID;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
class GetAllCitiesResponseModel {
|
||||||
|
int? iD;
|
||||||
|
String? description;
|
||||||
|
String? descriptionN;
|
||||||
|
|
||||||
|
GetAllCitiesResponseModel({this.iD, this.description, this.descriptionN});
|
||||||
|
|
||||||
|
GetAllCitiesResponseModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
iD = json['ID'];
|
||||||
|
description = json['Description'];
|
||||||
|
descriptionN = json['DescriptionN'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['ID'] = this.iD;
|
||||||
|
data['Description'] = this.description;
|
||||||
|
data['DescriptionN'] = this.descriptionN;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
class GetAllRelationshipTypeResponseModel {
|
||||||
|
int? iD;
|
||||||
|
String? text;
|
||||||
|
String? textAr;
|
||||||
|
String? textEn;
|
||||||
|
|
||||||
|
GetAllRelationshipTypeResponseModel(
|
||||||
|
{this.iD, this.text, this.textAr, this.textEn});
|
||||||
|
|
||||||
|
GetAllRelationshipTypeResponseModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
iD = json['ID'];
|
||||||
|
text = json['Text'];
|
||||||
|
textAr = json['Text_Ar'];
|
||||||
|
textEn = json['Text_En'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['ID'] = this.iD;
|
||||||
|
data['Text'] = this.text;
|
||||||
|
data['Text_Ar'] = this.textAr;
|
||||||
|
data['Text_En'] = this.textEn;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,161 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
class SearchEReferralResponseModel {
|
||||||
|
dynamic acceptedBrachCode;
|
||||||
|
dynamic acceptedBranchName;
|
||||||
|
dynamic acceptedBranchNameAr;
|
||||||
|
dynamic channel;
|
||||||
|
dynamic identityCardAttachment;
|
||||||
|
String? identityNumber;
|
||||||
|
dynamic insuranceCardAttachment;
|
||||||
|
bool? isInsuredPatient;
|
||||||
|
List<MedicalReportAttachment>? medicalReportAttachment;
|
||||||
|
String? otherRelationship;
|
||||||
|
String? patientContactNo;
|
||||||
|
int? patientId;
|
||||||
|
String? patientName;
|
||||||
|
dynamic preferredBranchCode;
|
||||||
|
dynamic preferredBranchName;
|
||||||
|
String? referralDate;
|
||||||
|
int? referralNumber;
|
||||||
|
RelationshipType? relationshipType;
|
||||||
|
String? requesterContactNo;
|
||||||
|
String? requesterName;
|
||||||
|
String? status;
|
||||||
|
String? statusAr;
|
||||||
|
|
||||||
|
SearchEReferralResponseModel({
|
||||||
|
this.acceptedBrachCode,
|
||||||
|
this.acceptedBranchName,
|
||||||
|
this.acceptedBranchNameAr,
|
||||||
|
this.channel,
|
||||||
|
this.identityCardAttachment,
|
||||||
|
this.identityNumber,
|
||||||
|
this.insuranceCardAttachment,
|
||||||
|
this.isInsuredPatient,
|
||||||
|
this.medicalReportAttachment,
|
||||||
|
this.otherRelationship,
|
||||||
|
this.patientContactNo,
|
||||||
|
this.patientId,
|
||||||
|
this.patientName,
|
||||||
|
this.preferredBranchCode,
|
||||||
|
this.preferredBranchName,
|
||||||
|
this.referralDate,
|
||||||
|
this.referralNumber,
|
||||||
|
this.relationshipType,
|
||||||
|
this.requesterContactNo,
|
||||||
|
this.requesterName,
|
||||||
|
this.status,
|
||||||
|
this.statusAr,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory SearchEReferralResponseModel.fromRawJson(String str) => SearchEReferralResponseModel.fromJson(json.decode(str));
|
||||||
|
|
||||||
|
String toRawJson() => json.encode(toJson());
|
||||||
|
|
||||||
|
factory SearchEReferralResponseModel.fromJson(Map<String, dynamic> json) => SearchEReferralResponseModel(
|
||||||
|
acceptedBrachCode: json["AcceptedBrachCode"],
|
||||||
|
acceptedBranchName: json["AcceptedBranchName"],
|
||||||
|
acceptedBranchNameAr: json["AcceptedBranchNameAr"],
|
||||||
|
channel: json["Channel"],
|
||||||
|
identityCardAttachment: json["IdentityCardAttachment"],
|
||||||
|
identityNumber: json["IdentityNumber"],
|
||||||
|
insuranceCardAttachment: json["InsuranceCardAttachment"],
|
||||||
|
isInsuredPatient: json["IsInsuredPatient"],
|
||||||
|
medicalReportAttachment: json["MedicalReportAttachment"] == null ? [] : List<MedicalReportAttachment>.from(json["MedicalReportAttachment"]!.map((x) => MedicalReportAttachment.fromJson(x))),
|
||||||
|
otherRelationship: json["OtherRelationship"],
|
||||||
|
patientContactNo: json["PatientContactNo"],
|
||||||
|
patientId: json["PatientId"],
|
||||||
|
patientName: json["PatientName"],
|
||||||
|
preferredBranchCode: json["PreferredBranchCode"],
|
||||||
|
preferredBranchName: json["PreferredBranchName"],
|
||||||
|
referralDate: json["ReferralDate"],
|
||||||
|
referralNumber: json["ReferralNumber"],
|
||||||
|
relationshipType: json["RelationshipType"] == null ? null : RelationshipType.fromJson(json["RelationshipType"]),
|
||||||
|
requesterContactNo: json["RequesterContactNo"],
|
||||||
|
requesterName: json["RequesterName"],
|
||||||
|
status: json["Status"],
|
||||||
|
statusAr: json["StatusAr"],
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"AcceptedBrachCode": acceptedBrachCode,
|
||||||
|
"AcceptedBranchName": acceptedBranchName,
|
||||||
|
"AcceptedBranchNameAr": acceptedBranchNameAr,
|
||||||
|
"Channel": channel,
|
||||||
|
"IdentityCardAttachment": identityCardAttachment,
|
||||||
|
"IdentityNumber": identityNumber,
|
||||||
|
"InsuranceCardAttachment": insuranceCardAttachment,
|
||||||
|
"IsInsuredPatient": isInsuredPatient,
|
||||||
|
"MedicalReportAttachment": medicalReportAttachment == null ? [] : List<dynamic>.from(medicalReportAttachment!.map((x) => x.toJson())),
|
||||||
|
"OtherRelationship": otherRelationship,
|
||||||
|
"PatientContactNo": patientContactNo,
|
||||||
|
"PatientId": patientId,
|
||||||
|
"PatientName": patientName,
|
||||||
|
"PreferredBranchCode": preferredBranchCode,
|
||||||
|
"PreferredBranchName": preferredBranchName,
|
||||||
|
"ReferralDate": referralDate,
|
||||||
|
"ReferralNumber": referralNumber,
|
||||||
|
"RelationshipType": relationshipType?.toJson(),
|
||||||
|
"RequesterContactNo": requesterContactNo,
|
||||||
|
"RequesterName": requesterName,
|
||||||
|
"Status": status,
|
||||||
|
"StatusAr": statusAr,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class MedicalReportAttachment {
|
||||||
|
String? base64String;
|
||||||
|
String? fileName;
|
||||||
|
|
||||||
|
MedicalReportAttachment({
|
||||||
|
this.base64String,
|
||||||
|
this.fileName,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory MedicalReportAttachment.fromRawJson(String str) => MedicalReportAttachment.fromJson(json.decode(str));
|
||||||
|
|
||||||
|
String toRawJson() => json.encode(toJson());
|
||||||
|
|
||||||
|
factory MedicalReportAttachment.fromJson(Map<String, dynamic> json) => MedicalReportAttachment(
|
||||||
|
base64String: json["Base64String"],
|
||||||
|
fileName: json["FileName"],
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"Base64String": base64String,
|
||||||
|
"FileName": fileName,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class RelationshipType {
|
||||||
|
int? id;
|
||||||
|
String? text;
|
||||||
|
String? textAr;
|
||||||
|
String? textEn;
|
||||||
|
|
||||||
|
RelationshipType({
|
||||||
|
this.id,
|
||||||
|
this.text,
|
||||||
|
this.textAr,
|
||||||
|
this.textEn,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory RelationshipType.fromRawJson(String str) => RelationshipType.fromJson(json.decode(str));
|
||||||
|
|
||||||
|
String toRawJson() => json.encode(toJson());
|
||||||
|
|
||||||
|
factory RelationshipType.fromJson(Map<String, dynamic> json) => RelationshipType(
|
||||||
|
id: json["ID"],
|
||||||
|
text: json["Text"],
|
||||||
|
textAr: json["Text_Ar"],
|
||||||
|
textEn: json["Text_En"],
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"ID": id,
|
||||||
|
"Text": text,
|
||||||
|
"Text_Ar": textAr,
|
||||||
|
"Text_En": textEn,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
// models/referral_models.dart
|
||||||
|
import 'package:hmg_patient_app_new/core/common_models/nationality_country_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/enums.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/create_e_referral_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_all_cities_resp_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/relationship_type_resp_mode.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
|
||||||
|
|
||||||
|
class ReferralFormData {
|
||||||
|
String requesterName = '';
|
||||||
|
String requesterPhone = '';
|
||||||
|
String searchPhone ='';
|
||||||
|
CountryEnum countryEnum = CountryEnum.saudiArabia;
|
||||||
|
CountryEnum patientCountryEnum = CountryEnum.saudiArabia;
|
||||||
|
|
||||||
|
GetAllRelationshipTypeResponseModel? relationship;
|
||||||
|
String otherRelationshipName = '';
|
||||||
|
|
||||||
|
String patientIdentification = '';
|
||||||
|
String patientName = '';
|
||||||
|
String patientPhone = '';
|
||||||
|
GetAllCitiesResponseModel? patientCity;
|
||||||
|
|
||||||
|
List<EReferralAttachment> medicalReportImages = [];
|
||||||
|
HospitalsModel? branch;
|
||||||
|
bool isPatientInsured = false;
|
||||||
|
List<EReferralAttachment> insuredPatientImages = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
class FormValidationErrors {
|
||||||
|
String? requesterName;
|
||||||
|
String? requesterPhone;
|
||||||
|
String? relationship;
|
||||||
|
String? otherRelationshipName;
|
||||||
|
|
||||||
|
String? patientIdentification;
|
||||||
|
String? patientName;
|
||||||
|
String? patientCity;
|
||||||
|
String? patientPhone;
|
||||||
|
|
||||||
|
|
||||||
|
String? medicalReport;
|
||||||
|
String? branch;
|
||||||
|
String? insuredDocument;
|
||||||
|
|
||||||
|
String? searchValue;
|
||||||
|
String? searchPhone;
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/hmg_services/models/ui_models/e_referral_form_model.dart';
|
||||||
|
|
||||||
|
class ReferralValidator {
|
||||||
|
static FormValidationErrors validateStep1(ReferralFormData formData) {
|
||||||
|
final errors = FormValidationErrors();
|
||||||
|
|
||||||
|
if (formData.requesterName.trim().isEmpty) {
|
||||||
|
errors.requesterName = 'Referral requester name is required'.needTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (formData.relationship == null) {
|
||||||
|
errors.relationship = 'Please select a relationship'.needTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData.relationship != null &&
|
||||||
|
formData.relationship?.iD == 5 &&
|
||||||
|
formData.otherRelationshipName.trim().isEmpty) {
|
||||||
|
errors.otherRelationshipName = 'Other relationship name is required'.needTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FormValidationErrors validateStep2(ReferralFormData formData) {
|
||||||
|
final errors = FormValidationErrors();
|
||||||
|
|
||||||
|
if (formData.patientIdentification.trim().isEmpty) {
|
||||||
|
errors.patientIdentification = 'Identification number is required'.needTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData.patientName.trim().isEmpty) {
|
||||||
|
errors.patientName = 'Patient name is required'.needTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData.patientPhone == null) {
|
||||||
|
errors.patientPhone = 'Please Enter patient phone number'.needTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData.patientCity == null) {
|
||||||
|
errors.patientCity = 'Please select patient city'.needTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FormValidationErrors validateStep3(ReferralFormData formData) {
|
||||||
|
final errors = FormValidationErrors();
|
||||||
|
|
||||||
|
if (formData.medicalReportImages.isEmpty) {
|
||||||
|
errors.medicalReport = 'At least one medical report is required'.needTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData.branch == null) {
|
||||||
|
errors.branch = 'Please select a branch'.needTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData.isPatientInsured && formData.insuredPatientImages.isEmpty) {
|
||||||
|
errors.insuredDocument = 'Insurance document is required for insured patients'.needTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _isValidSaudiPhone(String phone) {
|
||||||
|
final regex = RegExp(r'^5\d{8}$');
|
||||||
|
return regex.hasMatch(phone);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool hasErrors(FormValidationErrors errors) {
|
||||||
|
return errors.requesterName != null ||
|
||||||
|
errors.requesterPhone != null ||
|
||||||
|
errors.relationship != null ||
|
||||||
|
errors.otherRelationshipName != null ||
|
||||||
|
errors.patientIdentification != null ||
|
||||||
|
errors.patientName != null ||
|
||||||
|
errors.patientPhone != null ||
|
||||||
|
errors.patientCity != null ||
|
||||||
|
errors.medicalReport != null ||
|
||||||
|
errors.branch != null ||
|
||||||
|
errors.insuredDocument != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,290 @@
|
|||||||
|
// managers/referral_form_manager.dart
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/common_models/nationality_country_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/enums.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/hmg_services/models/req_models/create_e_referral_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/get_all_cities_resp_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/hmg_services/models/resq_models/relationship_type_resp_mode.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/hmg_services/models/ui_models/e_referral_form_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class ReferralFormManager extends ChangeNotifier {
|
||||||
|
final ReferralFormData _formData = ReferralFormData();
|
||||||
|
final FormValidationErrors _errors = FormValidationErrors();
|
||||||
|
|
||||||
|
ReferralFormData get formData => _formData;
|
||||||
|
FormValidationErrors get errors => _errors;
|
||||||
|
|
||||||
|
|
||||||
|
int _searchCriteria = 0; // 0 = Identification Number, 1 = Referral Number
|
||||||
|
String? _searchValue;
|
||||||
|
String? _searchPhone;
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
int get searchCriteria => _searchCriteria;
|
||||||
|
String? get searchValue => _searchValue;
|
||||||
|
String? get searchPhone => _searchPhone;
|
||||||
|
|
||||||
|
void updateRequesterName(String value) {
|
||||||
|
_formData.requesterName = value;
|
||||||
|
_clearError('requesterName');
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateRequesterPhone(String value) {
|
||||||
|
_formData.requesterPhone = value;
|
||||||
|
_clearError('requesterPhone');
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateCountryEnum(CountryEnum value) {
|
||||||
|
_formData.countryEnum = value;
|
||||||
|
}
|
||||||
|
void updatePatientCountryEnum(CountryEnum value) {
|
||||||
|
_formData.patientCountryEnum = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateRelationship(GetAllRelationshipTypeResponseModel? value) {
|
||||||
|
_formData.relationship = value;
|
||||||
|
notifyListeners();
|
||||||
|
_clearError('relationship');
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateOtherRelationshipName(String value) {
|
||||||
|
_formData.otherRelationshipName = value;
|
||||||
|
_clearError('otherRelationshipName');
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePatientIdentification(String value) {
|
||||||
|
_formData.patientIdentification = value;
|
||||||
|
_clearError('patientIdentification');
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePatientName(String value) {
|
||||||
|
_formData.patientName = value;
|
||||||
|
_clearError('patientName');
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePatientPhone(String? value) {
|
||||||
|
_formData.patientPhone = value!;
|
||||||
|
_clearError('patientPhone');
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePatientCity(GetAllCitiesResponseModel? value) {
|
||||||
|
_formData.patientCity = value;
|
||||||
|
_clearError('patientCity');
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateBranch(HospitalsModel? value) {
|
||||||
|
_formData.branch = value;
|
||||||
|
_clearError('branch');
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateIsPatientInsured(bool value) {
|
||||||
|
_formData.isPatientInsured = value;
|
||||||
|
if (!value) {
|
||||||
|
_formData.insuredPatientImages.clear();
|
||||||
|
}
|
||||||
|
_clearError('insuredDocument');
|
||||||
|
}
|
||||||
|
|
||||||
|
void addMedicalReport(EReferralAttachment attachment) {
|
||||||
|
_formData.medicalReportImages.add(attachment);
|
||||||
|
_clearError('medicalReport');
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeMedicalReport(int index) {
|
||||||
|
if (index >= 0 && index < _formData.medicalReportImages.length) {
|
||||||
|
_formData.medicalReportImages.removeAt(index);
|
||||||
|
}
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addInsuranceDocument(EReferralAttachment attachment) {
|
||||||
|
_formData.insuredPatientImages.add(attachment);
|
||||||
|
_clearError('insuredDocument');
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeInsuranceDocument(int index) {
|
||||||
|
if (index >= 0 && index < _formData.insuredPatientImages.length) {
|
||||||
|
_formData.insuredPatientImages.removeAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Error management
|
||||||
|
void setErrors(FormValidationErrors newErrors) {
|
||||||
|
_errors.requesterName = newErrors.requesterName;
|
||||||
|
_errors.requesterPhone = newErrors.requesterPhone;
|
||||||
|
_errors.relationship = newErrors.relationship;
|
||||||
|
_errors.otherRelationshipName = newErrors.otherRelationshipName;
|
||||||
|
_errors.patientIdentification = newErrors.patientIdentification;
|
||||||
|
_errors.patientName = newErrors.patientName;
|
||||||
|
_errors.patientPhone = newErrors.patientPhone;
|
||||||
|
_errors.patientCity = newErrors.patientCity;
|
||||||
|
_errors.medicalReport = newErrors.medicalReport;
|
||||||
|
_errors.branch = newErrors.branch;
|
||||||
|
_errors.insuredDocument = newErrors.insuredDocument;
|
||||||
|
notifyListeners(); // Only notify when errors change
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearAllErrors() {
|
||||||
|
_errors.requesterName = null;
|
||||||
|
_errors.requesterPhone = null;
|
||||||
|
_errors.relationship = null;
|
||||||
|
_errors.otherRelationshipName = null;
|
||||||
|
_errors.patientIdentification = null;
|
||||||
|
_errors.patientName = null;
|
||||||
|
_errors.patientPhone = null;
|
||||||
|
_errors.patientCity = null;
|
||||||
|
_errors.medicalReport = null;
|
||||||
|
_errors.branch = null;
|
||||||
|
_errors.insuredDocument = null;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _clearError(String field) {
|
||||||
|
bool shouldNotify = false;
|
||||||
|
|
||||||
|
switch (field) {
|
||||||
|
case 'requesterName':
|
||||||
|
if (_errors.requesterName != null) {
|
||||||
|
_errors.requesterName = null;
|
||||||
|
shouldNotify = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'requesterPhone':
|
||||||
|
if (_errors.requesterPhone != null) {
|
||||||
|
_errors.requesterPhone = null;
|
||||||
|
shouldNotify = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'relationship':
|
||||||
|
if (_errors.relationship != null) {
|
||||||
|
_errors.relationship = null;
|
||||||
|
shouldNotify = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'otherRelationshipName':
|
||||||
|
if (_errors.otherRelationshipName != null) {
|
||||||
|
_errors.otherRelationshipName = null;
|
||||||
|
shouldNotify = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'patientIdentification':
|
||||||
|
if (_errors.patientIdentification != null) {
|
||||||
|
_errors.patientIdentification = null;
|
||||||
|
shouldNotify = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'patientName':
|
||||||
|
if (_errors.patientName != null) {
|
||||||
|
_errors.patientName = null;
|
||||||
|
shouldNotify = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'patientPhone':
|
||||||
|
if (_errors.patientPhone != null) {
|
||||||
|
_errors.patientPhone = null;
|
||||||
|
shouldNotify = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'patientCity':
|
||||||
|
if (_errors.patientCity != null) {
|
||||||
|
_errors.patientCity = null;
|
||||||
|
shouldNotify = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'medicalReport':
|
||||||
|
if (_errors.medicalReport != null) {
|
||||||
|
_errors.medicalReport = null;
|
||||||
|
shouldNotify = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'branch':
|
||||||
|
if (_errors.branch != null) {
|
||||||
|
_errors.branch = null;
|
||||||
|
shouldNotify = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'insuredDocument':
|
||||||
|
if (_errors.insuredDocument != null) {
|
||||||
|
_errors.insuredDocument = null;
|
||||||
|
shouldNotify = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldNotify) {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void updateSearchCriteria(int criteria) {
|
||||||
|
_searchCriteria = criteria;
|
||||||
|
_errors.searchValue = _validateSearchValue();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSearchValue(String value) {
|
||||||
|
_searchValue = value;
|
||||||
|
_errors.searchValue = _validateSearchValue();
|
||||||
|
}
|
||||||
|
void updateSearchPhone(String value) {
|
||||||
|
_searchPhone = value;
|
||||||
|
_errors.searchPhone = _validateSearchPhone();
|
||||||
|
}
|
||||||
|
|
||||||
|
String? _validateSearchValue() {
|
||||||
|
if (_searchValue == null || _searchValue!.isEmpty) {
|
||||||
|
return _searchCriteria == 0
|
||||||
|
? 'Identification Number is required'
|
||||||
|
: 'Referral Number is required';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_searchCriteria == 0) {
|
||||||
|
// Validate identification number format
|
||||||
|
if (!_isValidIdentificationNumber(_searchValue!)) {
|
||||||
|
return 'Please enter a valid identification number';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Validate referral number format
|
||||||
|
if (!_isValidReferralNumber(_searchValue!)) {
|
||||||
|
return 'Please enter a valid referral number';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isValidIdentificationNumber(String value) {
|
||||||
|
// Add your identification number validation logic
|
||||||
|
return value.isNotEmpty; // Basic validation
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isValidReferralNumber(String value) {
|
||||||
|
// Add your referral number validation logic
|
||||||
|
return value.isNotEmpty; // Basic validation
|
||||||
|
}
|
||||||
|
|
||||||
|
void validateSearchForm() {
|
||||||
|
_errors.searchValue = _validateSearchValue();
|
||||||
|
_errors.searchPhone = _validateSearchPhone();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
String? _validateSearchPhone() {
|
||||||
|
if (_searchPhone == null || _searchPhone!.isEmpty) {
|
||||||
|
return 'Phone number is required';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
bool get isSearchFormInValid {
|
||||||
|
return (
|
||||||
|
_errors.searchValue != null &&
|
||||||
|
_errors.searchValue!.isNotEmpty ||
|
||||||
|
_errors.searchPhone != null &&
|
||||||
|
_errors.searchPhone!.isNotEmpty);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,97 +0,0 @@
|
|||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:hmg_patient_app_new/core/app_export.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/prescriptions/prescriptions_view_model.dart';
|
|
||||||
import 'package:hmg_patient_app_new/presentation/e_referral/new_referral.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:provider/provider.dart';
|
|
||||||
|
|
||||||
class EReferralPage extends StatefulWidget {
|
|
||||||
const EReferralPage({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
_EReferralPageState createState() => _EReferralPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _EReferralPageState extends State<EReferralPage>
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
bool isNewReferral = true;
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
backgroundColor: AppColors.bgScaffoldColor,
|
|
||||||
body: CollapsingListView(
|
|
||||||
title:"E Referral".needTranslation,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Consumer<PrescriptionsViewModel>(builder: (context, model, child) {
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
SizedBox(height: 16.h),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
CustomButton(
|
|
||||||
text: "New Referral".needTranslation,
|
|
||||||
onPressed: () {
|
|
||||||
isNewReferral =true;
|
|
||||||
setState(() {
|
|
||||||
|
|
||||||
});
|
|
||||||
},
|
|
||||||
backgroundColor: model.isSortByClinic ? AppColors.bgRedLightColor : AppColors.whiteColor,
|
|
||||||
borderColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.textColor.withOpacity(0.2),
|
|
||||||
textColor: model.isSortByClinic ? AppColors.primaryRedColor : AppColors.blackColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
borderRadius: 10,
|
|
||||||
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
|
|
||||||
height: 40.h,
|
|
||||||
),
|
|
||||||
SizedBox(width: 8.h),
|
|
||||||
CustomButton(
|
|
||||||
text: "Search Referral".needTranslation,
|
|
||||||
onPressed: () {
|
|
||||||
isNewReferral =false;
|
|
||||||
},
|
|
||||||
backgroundColor: model.isSortByClinic ? AppColors.whiteColor : AppColors.bgRedLightColor,
|
|
||||||
borderColor: model.isSortByClinic ? AppColors.textColor.withOpacity(0.2) : AppColors.primaryRedColor,
|
|
||||||
textColor: model.isSortByClinic ? AppColors.blackColor : AppColors.primaryRedColor,
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
borderRadius: 10,
|
|
||||||
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
|
|
||||||
height: 40.h,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
).paddingSymmetrical(24.h, 0.h),
|
|
||||||
SizedBox(height: 20.h),
|
|
||||||
isNewReferral ? NewEReferral() : SizedBox(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,280 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.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/core/utils/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/hmg_services/models/resq_models/search_e_referral_resp_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';
|
||||||
|
import 'package:smooth_corner/smooth_corner.dart';
|
||||||
|
|
||||||
|
class SearchResultPage extends StatefulWidget {
|
||||||
|
const SearchResultPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_SearchResultPageState createState() => _SearchResultPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SearchResultPageState extends State<SearchResultPage> {
|
||||||
|
HmgServicesViewModel? hmgServicesVM;
|
||||||
|
|
||||||
|
String _selectedFilter = 'All';
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
hmgServicesVM = context.read<HmgServicesViewModel>();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return CollapsingListView(
|
||||||
|
title: "Search Result".needTranslation,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
// List of referrals
|
||||||
|
ListView.builder(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: hmgServicesVM?.searchReferralList.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return _buildReferralCard(hmgServicesVM!.searchReferralList[index]);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildReferralCard(SearchEReferralResponseModel referral) {
|
||||||
|
return SmoothCard(
|
||||||
|
borderRadius: BorderRadius.circular(16.h),
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
color: AppColors.whiteColor,
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(16.h),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
|
||||||
|
'Referral No ${referral.referralNumber}'.needTranslation.toText18(isBold: true, color: AppColors.textColor),
|
||||||
|
|
||||||
|
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _getStatusColor(referral.status!),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
child:
|
||||||
|
referral.status!.toText12(color: AppColors.whiteColor,
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: Colors.white,
|
||||||
|
// fontSize: 12,
|
||||||
|
// fontWeight: FontWeight.w500,
|
||||||
|
// ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Patient information
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.lightGrayBGColor,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
Icons.person,
|
||||||
|
color: AppColors.lightGrayBGColor,
|
||||||
|
size: 30,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
//Text(
|
||||||
|
referral.patientName!.toText16(isBold: true, color: AppColors.textColor),
|
||||||
|
// style: TextStyle(
|
||||||
|
// fontSize: 16,
|
||||||
|
// fontWeight: FontWeight.bold,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
SizedBox(height: 4),
|
||||||
|
// Text(
|
||||||
|
'ID: ${referral.identityNumber}'.toText14(color: AppColors.greyTextColor),
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: Colors.grey[600],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Details row
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
_buildDetailItem(
|
||||||
|
Icons.phone,
|
||||||
|
referral.patientContactNo!,
|
||||||
|
),
|
||||||
|
SizedBox(width: 16),
|
||||||
|
_buildDetailItem(Icons.calendar_today, Utils.getDayMonthYearDateFormatted(DateUtil.convertStringToDateNoTimeZone(referral.referralDate!))),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Requester information
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.all(5.h),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.lightGrayBGColor,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.person_outline,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
//Text(
|
||||||
|
'Requester: ${referral.requesterName}'.toText14(),
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: Colors.grey[700],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
SizedBox(width: 16),
|
||||||
|
Icon(
|
||||||
|
Icons.phone,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
SizedBox(width: 4),
|
||||||
|
// Text(
|
||||||
|
referral.requesterContactNo!.toText14(),
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: Colors.grey[700],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 12),
|
||||||
|
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.group,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
SizedBox(width: 4),
|
||||||
|
//Text(
|
||||||
|
'Relationship: ${referral.relationshipType?.text}'.toText14(color:AppColors.greyTextColor),
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: Colors.grey[700],
|
||||||
|
// fontSize: 14,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.attach_file,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
SizedBox(width: 4),
|
||||||
|
// Text(
|
||||||
|
'${referral.medicalReportAttachment?.length} file(s)'.toText14(color:AppColors.greyTextColor),
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: Colors.grey[700],
|
||||||
|
// fontSize: 14,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Action buttons
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildDetailItem(IconData icon, String text) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
SizedBox(width: 4),
|
||||||
|
|
||||||
|
text.toText14(color: AppColors.greyTextColor),
|
||||||
|
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color _getStatusColor(String status) {
|
||||||
|
switch (status) {
|
||||||
|
case 'Pending':
|
||||||
|
return AppColors.alertColor;
|
||||||
|
case 'Completed':
|
||||||
|
return AppColors.bgGreenColor;
|
||||||
|
case 'Rejected':
|
||||||
|
return AppColors.primaryRedColor;
|
||||||
|
default:
|
||||||
|
return AppColors.lightGrayColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Widget _buildFilterOption(String filter) {
|
||||||
|
return ListTile(
|
||||||
|
leading: Icon(
|
||||||
|
_selectedFilter == filter ? Icons.radio_button_checked : Icons.radio_button_off,
|
||||||
|
color: _selectedFilter == filter ? Colors.blue[700] : Colors.grey,
|
||||||
|
),
|
||||||
|
title: Text(filter),
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_selectedFilter = filter;
|
||||||
|
});
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,262 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/app_export.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.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/authentication/authentication_view_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.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/create_e_referral_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/hmg_services/models/ui_models/e_referral_form_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||||
|
import 'package:hmg_patient_app_new/presentation/e_referral/search_e_referral.dart';
|
||||||
|
import 'package:hmg_patient_app_new/presentation/e_referral/widget/e-referral_otp.dart';
|
||||||
|
import 'package:hmg_patient_app_new/presentation/e_referral/widget/e_referral_other_details.dart';
|
||||||
|
import 'package:hmg_patient_app_new/presentation/e_referral/widget/e_referral_patient_info.dart';
|
||||||
|
import 'package:hmg_patient_app_new/presentation/e_referral/widget/e_referral_requester_form.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:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/stepper/stepper_widget.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'e-referral_validator.dart';
|
||||||
|
import 'e_referral_form_manager.dart';
|
||||||
|
|
||||||
|
class NewReferralPage extends StatefulWidget {
|
||||||
|
const NewReferralPage({
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NewReferralPage> createState() => _NewReferralPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NewReferralPageState extends State<NewReferralPage> {
|
||||||
|
final PageController _pageController = PageController();
|
||||||
|
final ReferralFormManager _formManager = ReferralFormManager(); // Use manager
|
||||||
|
int _currentStep = 0;
|
||||||
|
|
||||||
|
double widthOfOneState = ((ResponsiveExtension.screenWidth) / 3) - (20.h);
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleNextStep() {
|
||||||
|
switch (_currentStep) {
|
||||||
|
case 0:
|
||||||
|
if (_validateCurrentStep()) {
|
||||||
|
OTPService.openOTPScreen(
|
||||||
|
context: context,
|
||||||
|
formManager: _formManager,
|
||||||
|
onSuccess: _proceedToNextStep,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (_validateCurrentStep()) {
|
||||||
|
_proceedToNextStep();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (_validateCurrentStep()) {
|
||||||
|
_submitReferral();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _validateCurrentStep() {
|
||||||
|
FormValidationErrors stepErrors;
|
||||||
|
|
||||||
|
switch (_currentStep) {
|
||||||
|
case 0:
|
||||||
|
stepErrors = ReferralValidator.validateStep1(_formManager.formData);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
stepErrors = ReferralValidator.validateStep2(_formManager.formData);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
stepErrors = ReferralValidator.validateStep3(_formManager.formData);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
stepErrors = FormValidationErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update errors through manager
|
||||||
|
_formManager.setErrors(stepErrors);
|
||||||
|
|
||||||
|
return !ReferralValidator.hasErrors(stepErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _proceedToNextStep() {
|
||||||
|
_pageController.nextPage(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
);
|
||||||
|
// setState(() {
|
||||||
|
_currentStep++;
|
||||||
|
// });
|
||||||
|
// widget.onStepChanged(_currentStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _submitReferral() {
|
||||||
|
CreateEReferralRequestModel createReferralRequestModel = CreateEReferralRequestModel(
|
||||||
|
isInsuredPatient: _formManager.formData.isPatientInsured,
|
||||||
|
cityCode: _formManager.formData.patientCity!.iD!.toString(),
|
||||||
|
cityName: _formManager.formData.patientCity!.description,
|
||||||
|
requesterName: _formManager.formData.requesterName,
|
||||||
|
requesterContactNo: _formManager.formData.countryEnum.countryCode + _formManager.formData.requesterPhone,
|
||||||
|
requesterRelationship: _formManager.formData.relationship?.iD,
|
||||||
|
otherRelationship: _formManager.formData.relationship!.iD.toString(),
|
||||||
|
fullName: _formManager.formData.patientName,
|
||||||
|
identificationNo: int.tryParse(_formManager.formData!.patientIdentification ?? '0'),
|
||||||
|
patientMobileNumber: _formManager.formData.patientCountryEnum.countryCode + _formManager.formData.patientPhone,
|
||||||
|
preferredBranchCode: _formManager.formData.branch!.iD,
|
||||||
|
medicalReportAttachment: _formManager.formData.medicalReportImages,
|
||||||
|
insuranceCardAttachment: _formManager.formData.insuredPatientImages,
|
||||||
|
preferredBranchName: _formManager.formData.branch!.desciption);
|
||||||
|
|
||||||
|
final hmgServicesVM = context.read<HmgServicesViewModel>();
|
||||||
|
LoaderBottomSheet.showLoader();
|
||||||
|
|
||||||
|
hmgServicesVM.createEReferral(
|
||||||
|
requestModel: createReferralRequestModel,
|
||||||
|
onSuccess: (GenericApiModel response) {
|
||||||
|
|
||||||
|
showSuccessBottomSheet(int.parse(response.data), hmgServicesVM);
|
||||||
|
LoaderBottomSheet.hideLoader();
|
||||||
|
|
||||||
|
},
|
||||||
|
onError: (errorMessage) {
|
||||||
|
// Handle error (e.g., show error message)
|
||||||
|
print(errorMessage);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loadData() {
|
||||||
|
final authVM = context.read<AuthenticationViewModel>();
|
||||||
|
final habibWalletVM = context.read<HabibWalletViewModel>();
|
||||||
|
final hmgServicesVM = context.read<HmgServicesViewModel>();
|
||||||
|
|
||||||
|
hmgServicesVM.getRelationshipType();
|
||||||
|
authVM.loadCountriesData();
|
||||||
|
hmgServicesVM.getAllCities();
|
||||||
|
habibWalletVM.getProjectsList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: AppColors.bgScaffoldColor,
|
||||||
|
body: CollapsingListView(
|
||||||
|
title: "E Referral".needTranslation,
|
||||||
|
isClose: false,
|
||||||
|
search: () async {
|
||||||
|
await Navigator.of(context).push(
|
||||||
|
CustomPageRoute(
|
||||||
|
page: SearchEReferralPage(),
|
||||||
|
fullScreenDialog: true,
|
||||||
|
direction: AxisDirection.down,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
bottomChild: Container(
|
||||||
|
color: Colors.white,
|
||||||
|
padding: EdgeInsets.all(ResponsiveExtension(20).h),
|
||||||
|
child: CustomButton(
|
||||||
|
text: _currentStep <=1 ? LocaleKeys.next.tr() : LocaleKeys.submit.tr(),
|
||||||
|
// icon: AppAssets.search_icon,
|
||||||
|
iconColor: Colors.white,
|
||||||
|
onPressed: () => {_handleNextStep()},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: ChangeNotifierProvider.value(
|
||||||
|
value: _formManager,
|
||||||
|
child: SizedBox(
|
||||||
|
height: ResponsiveExtension.screenHeight * 0.65,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: List.generate(3, (index) {
|
||||||
|
if (_currentStep == index) {
|
||||||
|
return StepperWidget(widthOfOneState, AppColors.primaryRedColor, true, 4.h);
|
||||||
|
} else {
|
||||||
|
return StepperWidget(widthOfOneState, AppColors.greyLightColor, false, 4.h);
|
||||||
|
}
|
||||||
|
})),
|
||||||
|
Expanded(
|
||||||
|
child: PageView(
|
||||||
|
controller: _pageController,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
onPageChanged: (index) => {
|
||||||
|
// setState(() => _currentStep = index)
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
RequesterFormStep(),
|
||||||
|
PatientInformationStep(),
|
||||||
|
OtherDetailsStep(),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
)));
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
showSuccessBottomSheet(int requestId, HmgServicesViewModel hmgServicesViewModel) {
|
||||||
|
return showCommonBottomSheetWithoutHeight(
|
||||||
|
context,
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(16.w),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Utils.getSuccessWidget(loadingText: "Your Referral has been created Successfully.".needTranslation),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
"Here is your Referral #: ".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();
|
||||||
|
_currentStep =0;
|
||||||
|
},
|
||||||
|
textColor: AppColors.whiteColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
isCloseButtonVisible: false,
|
||||||
|
isDismissible: false,
|
||||||
|
isFullScreen: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,172 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
|
||||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
|
||||||
|
|
||||||
class NewEReferral extends StatefulWidget {
|
|
||||||
NewEReferral();
|
|
||||||
|
|
||||||
@override
|
|
||||||
_NewEReferralState createState() => _NewEReferralState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _NewEReferralState extends State<NewEReferral> with TickerProviderStateMixin {
|
|
||||||
late PageController _controller;
|
|
||||||
int _currentIndex = 0;
|
|
||||||
int pageSelected = 2;
|
|
||||||
|
|
||||||
// CreateEReferralRequestModel createEReferralRequestModel = new CreateEReferralRequestModel();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_controller = new PageController();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
changePageViewIndex(pageIndex) {
|
|
||||||
_controller.jumpToPage(pageIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
body: Container(
|
|
||||||
height: double.infinity,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: double.infinity,
|
|
||||||
padding: EdgeInsets.only(left: 12,right: 12,top: 12),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: showProgress(
|
|
||||||
title: "Requester Info".needTranslation,
|
|
||||||
status: _currentIndex == 0
|
|
||||||
? "InProgress".needTranslation
|
|
||||||
: _currentIndex > 0
|
|
||||||
? "Completed".needTranslation
|
|
||||||
: "Locked".needTranslation,
|
|
||||||
color: _currentIndex == 0 ? AppColors.infoColor : AppColors.successColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: showProgress(
|
|
||||||
title:"Patient Info".needTranslation,
|
|
||||||
status: _currentIndex == 1
|
|
||||||
? "InProgress".needTranslation
|
|
||||||
: _currentIndex > 1
|
|
||||||
? "Completed".needTranslation
|
|
||||||
: "Locked".needTranslation,
|
|
||||||
color: _currentIndex == 1
|
|
||||||
? AppColors.infoColor
|
|
||||||
: _currentIndex > 1
|
|
||||||
? AppColors.successColor
|
|
||||||
: AppColors.greyColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
showProgress(
|
|
||||||
title: "Other Info".needTranslation,
|
|
||||||
status: _currentIndex == 2 ? "InProgress".needTranslation :"Locked".needTranslation,
|
|
||||||
color: _currentIndex == 2
|
|
||||||
? AppColors.infoColor
|
|
||||||
: _currentIndex > 3
|
|
||||||
? AppColors.successColor
|
|
||||||
: AppColors.greyColor,
|
|
||||||
isNeedBorder: false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: PageView(
|
|
||||||
physics: NeverScrollableScrollPhysics(),
|
|
||||||
controller: _controller,
|
|
||||||
onPageChanged: (index) {
|
|
||||||
setState(() {
|
|
||||||
_currentIndex = index;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
children: <Widget>[
|
|
||||||
// NewEReferralStepOnePage(
|
|
||||||
// changePageViewIndex: changePageViewIndex,
|
|
||||||
// createEReferralRequestModel: createEReferralRequestModel,
|
|
||||||
// ),
|
|
||||||
// NewEReferralStepTowPage(
|
|
||||||
// changePageViewIndex: changePageViewIndex,
|
|
||||||
// createEReferralRequestModel: createEReferralRequestModel,
|
|
||||||
// ),
|
|
||||||
// NewEReferralStepThreePage(
|
|
||||||
// changePageViewIndex: changePageViewIndex,
|
|
||||||
// createEReferralRequestModel: createEReferralRequestModel,
|
|
||||||
// ),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget showProgress({required String title, required String status, required Color color, bool isNeedBorder = true}) {
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 26,
|
|
||||||
height: 26,
|
|
||||||
// decoration: containerRadius(color, 200),
|
|
||||||
child: Icon(
|
|
||||||
Icons.done,
|
|
||||||
color: Colors.white,
|
|
||||||
size: 16,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (isNeedBorder)
|
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child:Divider(),
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
// mHeight(8),
|
|
||||||
Text(
|
|
||||||
title,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 11,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
letterSpacing: -0.44,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// mHeight(2),
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.all(5),
|
|
||||||
// decoration: containerRadius(color.withOpacity(0.2), 4),
|
|
||||||
child: Text(
|
|
||||||
status,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 8,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
letterSpacing: -0.32,
|
|
||||||
color: color,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,119 @@
|
|||||||
|
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/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/hmg_services/models/req_models/search_e_referral_req_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||||
|
import 'package:hmg_patient_app_new/presentation/e_referral/widget/search_e_referral_form.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/loader/bottomsheet_loader.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/routes/custom_page_route.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'e_referral_form_manager.dart';
|
||||||
|
import 'e_referral_search_result.dart';
|
||||||
|
|
||||||
|
class SearchEReferralPage extends StatefulWidget {
|
||||||
|
|
||||||
|
const SearchEReferralPage({
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SearchEReferralPage> createState() => _SearchEReferralPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SearchEReferralPageState extends State<SearchEReferralPage> {
|
||||||
|
final ReferralFormManager _formManager = ReferralFormManager();
|
||||||
|
late HmgServicesViewModel hmgServicesVM;
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleSearch() {
|
||||||
|
_formManager.validateSearchForm();
|
||||||
|
if (!_formManager.isSearchFormInValid) {
|
||||||
|
_searchReferral();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _searchReferral() {
|
||||||
|
SearchEReferralRequestModel searchEReferralReq;
|
||||||
|
|
||||||
|
if (_formManager.searchCriteria == 0) {
|
||||||
|
searchEReferralReq = SearchEReferralRequestModel(
|
||||||
|
identificationNo: _formManager.searchValue,
|
||||||
|
patientMobileNumber: _formManager.formData.countryEnum.countryCode + _formManager.searchPhone!,
|
||||||
|
referralNumber: 0,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
searchEReferralReq = SearchEReferralRequestModel(referralNumber: int.parse(_formManager.searchValue!), patientMobileNumber: _formManager.formData.patientPhone, identificationNo: '');
|
||||||
|
}
|
||||||
|
|
||||||
|
hmgServicesVM = context.read<HmgServicesViewModel>();
|
||||||
|
LoaderBottomSheet.showLoader();
|
||||||
|
hmgServicesVM.searchEReferral(
|
||||||
|
requestModel: searchEReferralReq,
|
||||||
|
onSuccess: (response) async {
|
||||||
|
LoaderBottomSheet.hideLoader();
|
||||||
|
await Navigator.of(context).push(
|
||||||
|
CustomPageRoute(
|
||||||
|
page: SearchResultPage(),
|
||||||
|
fullScreenDialog: true,
|
||||||
|
direction: AxisDirection.down,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loadData() {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return CollapsingListView(
|
||||||
|
title: "Search E-Referral".needTranslation,
|
||||||
|
isClose: true,
|
||||||
|
bottomChild: Container(
|
||||||
|
color: Colors.white,
|
||||||
|
padding: EdgeInsets.all(ResponsiveExtension(20).h),
|
||||||
|
child: CustomButton(
|
||||||
|
text: LocaleKeys.search.tr(),
|
||||||
|
icon: AppAssets.search_icon,
|
||||||
|
iconColor: Colors.white,
|
||||||
|
onPressed: () => {
|
||||||
|
_handleSearch()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: ChangeNotifierProvider.value(
|
||||||
|
value: _formManager,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_buildHeader(),
|
||||||
|
SearchEReferralFormForm(),
|
||||||
|
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildHeader() {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [SizedBox(height: 8), 'Please enter the required information to search for an e-referral'.needTranslation.toText12()],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,102 @@
|
|||||||
|
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/enums.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/utils/validation_utils.dart';
|
||||||
|
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
|
||||||
|
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||||
|
import 'package:hmg_patient_app_new/presentation/e_referral/e_referral_form_manager.dart';
|
||||||
|
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/bottomsheet/generic_bottom_sheet.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/buttons/custom_button.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/common_models/generic_api_model.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/send_activation_code_ereferral_req_model.dart';
|
||||||
|
|
||||||
|
class OTPService {
|
||||||
|
static void openOTPScreen({
|
||||||
|
required BuildContext context,
|
||||||
|
required ReferralFormManager formManager,
|
||||||
|
required Function onSuccess,
|
||||||
|
}) {
|
||||||
|
_showOTPVerificationSheet(context: context, formManager: formManager, onSuccess: onSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _showOTPVerificationSheet({
|
||||||
|
required BuildContext context,
|
||||||
|
required ReferralFormManager formManager,
|
||||||
|
required Function onSuccess,
|
||||||
|
}) {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
isDismissible: false,
|
||||||
|
useSafeArea: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
builder: (bottomSheetContext) => Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: MediaQuery.of(bottomSheetContext).viewInsets.bottom),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: GenericBottomSheet(
|
||||||
|
isEnableCountryDropdown: true,
|
||||||
|
textController: TextEditingController(),
|
||||||
|
onChange: (value) {
|
||||||
|
formManager.updateRequesterPhone(value ?? '');
|
||||||
|
},
|
||||||
|
onCountryChange: (value) {
|
||||||
|
formManager.updateCountryEnum(value);
|
||||||
|
},
|
||||||
|
autoFocus: true,
|
||||||
|
buttons: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 10),
|
||||||
|
child: CustomButton(
|
||||||
|
text: LocaleKeys.sendOTPSMS.tr(),
|
||||||
|
onPressed: () async {
|
||||||
|
if (ValidationUtils.isValidatePhone(
|
||||||
|
phoneNumber: formManager.formData.requesterPhone,
|
||||||
|
onOkPress: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
)) {
|
||||||
|
Navigator.pop(context);
|
||||||
|
final hmgServicesViewModel = context.read<HmgServicesViewModel>();
|
||||||
|
|
||||||
|
LoaderBottomSheet.showLoader();
|
||||||
|
hmgServicesViewModel.eReferralSendActivationCode(
|
||||||
|
requestModel: SendActivationCodeForEReferralRequestModel(
|
||||||
|
patientMobileNumber: int.parse(formManager.formData.requesterPhone),
|
||||||
|
zipCode: formManager.formData.countryEnum.countryCode,
|
||||||
|
patientOutSA: formManager.formData.countryEnum.countryCode == '966' ? 0 : 1,
|
||||||
|
),
|
||||||
|
onSuccess: (GenericApiModel response) {
|
||||||
|
LoaderBottomSheet.hideLoader();
|
||||||
|
hmgServicesViewModel.navigateToOTPScreen(
|
||||||
|
otpTypeEnum: OTPTypeEnum.sms,
|
||||||
|
phoneNumber: formManager.formData.requesterPhone,
|
||||||
|
loginToken: response.data,
|
||||||
|
onSuccess: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
onSuccess();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (String errorMessage) {
|
||||||
|
LoaderBottomSheet.hideLoader();
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage)));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
backgroundColor: AppColors.primaryRedColor,
|
||||||
|
borderColor: AppColors.primaryRedBorderColor,
|
||||||
|
textColor: AppColors.whiteColor,
|
||||||
|
icon: AppAssets.message,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,319 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/app_export.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/utils/validation_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/models/req_models/create_e_referral_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/presentation/e_referral/e_referral_form_manager.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/app_assets.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/habib_wallet/habib_wallet_view_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/dropdown/dropdown_widget.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/image_picker.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class OtherDetailsStep extends StatefulWidget {
|
||||||
|
const OtherDetailsStep({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<OtherDetailsStep> createState() => _OtherDetailsStepState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _OtherDetailsStepState extends State<OtherDetailsStep> {
|
||||||
|
final TextEditingController _medicalReportController = TextEditingController();
|
||||||
|
final TextEditingController _insuranceController = TextEditingController();
|
||||||
|
|
||||||
|
late ReferralFormManager _formManager;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_formManager = context.read<ReferralFormManager>();
|
||||||
|
_updateMedicalReportText();
|
||||||
|
_updateInsuranceText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(OtherDetailsStep oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
_updateMedicalReportText();
|
||||||
|
_updateInsuranceText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateMedicalReportText() {
|
||||||
|
final hasMedicalReports = _formManager.formData.medicalReportImages.isNotEmpty;
|
||||||
|
_medicalReportController.text = hasMedicalReports
|
||||||
|
? '${_formManager.formData.medicalReportImages.length} file(s) selected'.needTranslation
|
||||||
|
: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateInsuranceText() {
|
||||||
|
final hasInsuranceDocs = _formManager.formData.insuredPatientImages.isNotEmpty;
|
||||||
|
_insuranceController.text = hasInsuranceDocs
|
||||||
|
? '${_formManager.formData.insuredPatientImages.length} file(s) selected'.needTranslation
|
||||||
|
: '';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Consumer<ReferralFormManager>(
|
||||||
|
builder: (context, formManager, child) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
child: ListView(
|
||||||
|
physics: const BouncingScrollPhysics(),
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildSectionTitle('Other Details'.needTranslation),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildMedicalReportField(formManager),
|
||||||
|
_buildBranchField(context, formManager),
|
||||||
|
_buildInsuranceCheckbox(formManager),
|
||||||
|
if (formManager.formData.isPatientInsured) _buildInsuranceField(formManager),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSectionTitle(String title) {
|
||||||
|
return Text(
|
||||||
|
title,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w700, fontSize: 16)
|
||||||
|
).paddingSymmetrical(4, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildMedicalReportField(ReferralFormManager formManager) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
child: TextInputWidget(
|
||||||
|
controller: _medicalReportController,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
hintText: 'Medical Report'.needTranslation,
|
||||||
|
labelText: 'Select Attachment'.needTranslation,
|
||||||
|
suffix: const Icon(Icons.attachment),
|
||||||
|
isReadOnly: true,
|
||||||
|
errorMessage: formManager.errors.medicalReport,
|
||||||
|
hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.medicalReport),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
ImageOptions.showImageOptionsNew(
|
||||||
|
context,
|
||||||
|
false,
|
||||||
|
(String image, File file) {
|
||||||
|
_addMedicalReport(image, file, formManager);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (formManager.formData.medicalReportImages.isNotEmpty)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 8.0,
|
||||||
|
children: formManager.formData.medicalReportImages.asMap().entries.map((entry) {
|
||||||
|
final index = entry.key;
|
||||||
|
return Chip(
|
||||||
|
label: Text('Medical Report ${index + 1}'.needTranslation),
|
||||||
|
deleteIcon: const Icon(Icons.close, size: 16),
|
||||||
|
onDeleted: () {
|
||||||
|
_removeMedicalReport(index, formManager);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).paddingSymmetrical(0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildBranchField(BuildContext context, ReferralFormManager formManager) {
|
||||||
|
return DropdownWidget(
|
||||||
|
labelText: 'Branch',
|
||||||
|
hintText: formManager.formData.branch?.desciption ?? "Select Branch",
|
||||||
|
isEnable: false,
|
||||||
|
hasSelectionCustomIcon: true,
|
||||||
|
labelColor: Colors.black,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||||
|
selectionCustomIcon: AppAssets.arrow_down,
|
||||||
|
leadingIcon: AppAssets.hospital,
|
||||||
|
dropdownItems: [],
|
||||||
|
errorMessage: formManager.errors.branch,
|
||||||
|
hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.branch),
|
||||||
|
).paddingSymmetrical(0, 4).onPress(() {
|
||||||
|
_showBranchBottomSheet(context, formManager);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildInsuranceCheckbox(ReferralFormManager formManager) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Checkbox(
|
||||||
|
value: formManager.formData.isPatientInsured,
|
||||||
|
activeColor: Colors.red,
|
||||||
|
onChanged: (bool? newValue) {
|
||||||
|
final value = newValue ?? false;
|
||||||
|
formManager.updateIsPatientInsured(value);
|
||||||
|
if (!value) {
|
||||||
|
_updateInsuranceText();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.all(5.0),
|
||||||
|
child:
|
||||||
|
"Patient is Insured".needTranslation.toText14(
|
||||||
|
color: Colors.black,
|
||||||
|
weight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
// style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
|
||||||
|
//),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).paddingSymmetrical(0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildInsuranceField(ReferralFormManager formManager) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
child: TextInputWidget(
|
||||||
|
controller: _insuranceController,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
hintText: 'Insurance Document'.needTranslation,
|
||||||
|
labelText: 'Select Attachment'.needTranslation,
|
||||||
|
suffix: const Icon(Icons.attachment),
|
||||||
|
isReadOnly: true,
|
||||||
|
errorMessage: formManager.errors.insuredDocument,
|
||||||
|
hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.insuredDocument),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
ImageOptions.showImageOptionsNew(
|
||||||
|
context,
|
||||||
|
false,
|
||||||
|
(String image, File file) {
|
||||||
|
_addInsuranceDocument(image, file, formManager);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (formManager.formData.insuredPatientImages.isNotEmpty)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 8.0,
|
||||||
|
children: formManager.formData.insuredPatientImages.asMap().entries.map((entry) {
|
||||||
|
final index = entry.key;
|
||||||
|
return Chip(
|
||||||
|
label: Text('Insurance ${index + 1}'),
|
||||||
|
deleteIcon: const Icon(Icons.close, size: 16),
|
||||||
|
onDeleted: () {
|
||||||
|
_removeInsuranceDocument(index, formManager);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showBranchBottomSheet(BuildContext context, ReferralFormManager formManager) {
|
||||||
|
final habibWalletVM = context.read<HabibWalletViewModel>();
|
||||||
|
|
||||||
|
showCommonBottomSheetWithoutHeight(
|
||||||
|
context,
|
||||||
|
title: "Select Branch".needTranslation,
|
||||||
|
child: Consumer<HabibWalletViewModel>(
|
||||||
|
builder: (context, habibWalletVM, child) {
|
||||||
|
final hospitals = habibWalletVM.advancePaymentHospitals;
|
||||||
|
if (hospitals == null || hospitals.isEmpty) {
|
||||||
|
return const Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(16.0),
|
||||||
|
child: Text('No branches available'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DecoratedBox(
|
||||||
|
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
customBorder: BorderRadius.all(Radius.circular(24.h)) ,
|
||||||
|
|
||||||
|
), child: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: EdgeInsets.all(16.h),
|
||||||
|
physics: const BouncingScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final branch = hospitals[index];
|
||||||
|
return ListTile(
|
||||||
|
title: (branch.desciption ?? 'Unknown').toText14(),
|
||||||
|
onTap: () {
|
||||||
|
formManager.updateBranch(branch);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// separatorBuilder: (context, index) => const Divider(),
|
||||||
|
itemCount: hospitals.length,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
useSafeArea: true,
|
||||||
|
isFullScreen: false,
|
||||||
|
isCloseButtonVisible: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _addMedicalReport(String image, File file, ReferralFormManager formManager) {
|
||||||
|
final newAttachment = EReferralAttachment(
|
||||||
|
fileName: 'medical_report_${formManager.formData.medicalReportImages.length + 1}.png',
|
||||||
|
base64String: image
|
||||||
|
);
|
||||||
|
|
||||||
|
formManager.addMedicalReport(newAttachment);
|
||||||
|
_updateMedicalReportText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _removeMedicalReport(int index, ReferralFormManager formManager) {
|
||||||
|
formManager.removeMedicalReport(index);
|
||||||
|
_updateMedicalReportText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _addInsuranceDocument(String image, File file, ReferralFormManager formManager) {
|
||||||
|
final newAttachment = EReferralAttachment(
|
||||||
|
fileName: 'insurance_${formManager.formData.insuredPatientImages.length + 1}.png',
|
||||||
|
base64String: image
|
||||||
|
);
|
||||||
|
|
||||||
|
formManager.addInsuranceDocument(newAttachment);
|
||||||
|
_updateInsuranceText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _removeInsuranceDocument(int index, ReferralFormManager formManager) {
|
||||||
|
formManager.removeInsuranceDocument(index);
|
||||||
|
_updateInsuranceText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_medicalReportController.dispose();
|
||||||
|
_insuranceController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,235 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/app_export.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/utils/validation_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/presentation/e_referral/e_referral_form_manager.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/app_assets.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/dropdown/dropdown_widget.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
|
||||||
|
|
||||||
|
class PatientInformationStep extends StatefulWidget {
|
||||||
|
const PatientInformationStep({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<PatientInformationStep> createState() => PatientInformationStepState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class PatientInformationStepState extends State<PatientInformationStep> {
|
||||||
|
late TextEditingController _identificationController;
|
||||||
|
late TextEditingController _nameController;
|
||||||
|
late TextEditingController _phoneController;
|
||||||
|
|
||||||
|
late FocusNode _identificationFocusNode;
|
||||||
|
late FocusNode _nameFocusNode;
|
||||||
|
late FocusNode _phoneFocusNode;
|
||||||
|
|
||||||
|
late ReferralFormManager _formManager;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_formManager = context.read<ReferralFormManager>();
|
||||||
|
|
||||||
|
_identificationController = TextEditingController();
|
||||||
|
_nameController = TextEditingController();
|
||||||
|
_phoneController = TextEditingController();
|
||||||
|
|
||||||
|
_identificationFocusNode = FocusNode();
|
||||||
|
_nameFocusNode = FocusNode();
|
||||||
|
_phoneFocusNode = FocusNode();
|
||||||
|
|
||||||
|
// Initialize controllers with current values
|
||||||
|
_identificationController.text = _formManager.formData.patientIdentification ?? '';
|
||||||
|
_nameController.text = _formManager.formData.patientName ?? '';
|
||||||
|
_phoneController.text = _formManager.formData.patientPhone ?? '';
|
||||||
|
|
||||||
|
// Auto-focus the identification field when the step loads
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (mounted) {
|
||||||
|
_identificationFocusNode.requestFocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Consumer<ReferralFormManager>(
|
||||||
|
builder: (context, formManager, child) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
child: ListView(
|
||||||
|
physics: const BouncingScrollPhysics(),
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildSectionTitle('Patient information'.needTranslation),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildIdentificationField(formManager),
|
||||||
|
_buildPatientNameField(formManager),
|
||||||
|
// _buildPatientCountryField(context, formManager),
|
||||||
|
_buildPatientPhoneField(formManager),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
_buildSectionTitle('Where the patient located'.needTranslation),
|
||||||
|
_buildPatientCityField(context, formManager),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSectionTitle(String title) {
|
||||||
|
return Text(
|
||||||
|
title,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w700, fontSize: 16)
|
||||||
|
).paddingSymmetrical(4, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildIdentificationField(ReferralFormManager formManager) {
|
||||||
|
return Focus(
|
||||||
|
focusNode: _identificationFocusNode,
|
||||||
|
child: TextInputWidget(
|
||||||
|
controller: _identificationController,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
hintText: 'Enter Identification Number*'.needTranslation,
|
||||||
|
labelText: 'Identification Number'.needTranslation,
|
||||||
|
errorMessage: formManager.errors.patientIdentification,
|
||||||
|
hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.patientIdentification),
|
||||||
|
onChange: (value) {
|
||||||
|
formManager.updatePatientIdentification(value ?? '');
|
||||||
|
},
|
||||||
|
onSubmitted: (value) {
|
||||||
|
_nameFocusNode.requestFocus();
|
||||||
|
},
|
||||||
|
).paddingSymmetrical(0, 4),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPatientNameField(ReferralFormManager formManager) {
|
||||||
|
return Focus(
|
||||||
|
focusNode: _nameFocusNode,
|
||||||
|
child: TextInputWidget(
|
||||||
|
controller: _nameController,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
hintText: 'Patient Name*'.needTranslation,
|
||||||
|
labelText: 'Name'.needTranslation,
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
errorMessage: formManager.errors.patientName,
|
||||||
|
hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.patientName),
|
||||||
|
onChange: (value) {
|
||||||
|
formManager.updatePatientName(value ?? '');
|
||||||
|
},
|
||||||
|
onSubmitted: (value) {
|
||||||
|
// Optionally move to next field or keep focus
|
||||||
|
},
|
||||||
|
).paddingSymmetrical(0, 4),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPatientPhoneField(ReferralFormManager formManager) {
|
||||||
|
return Focus(
|
||||||
|
focusNode: _phoneFocusNode,
|
||||||
|
child: TextInputWidget(
|
||||||
|
labelText: 'Phone Number'.needTranslation,
|
||||||
|
hintText: "5xxxxxxxx",
|
||||||
|
controller: _phoneController,
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
onChange: (value) {
|
||||||
|
formManager.updatePatientPhone(value ?? '');
|
||||||
|
},
|
||||||
|
onCountryChange: (value) {
|
||||||
|
formManager.updatePatientCountryEnum(value);
|
||||||
|
},
|
||||||
|
prefix: '966',
|
||||||
|
isBorderAllowed: false,
|
||||||
|
isAllowLeadingIcon: true,
|
||||||
|
fontSize: 13,
|
||||||
|
isCountryDropDown: true,
|
||||||
|
leadingIcon: AppAssets.smart_phone,
|
||||||
|
errorMessage: formManager.errors.patientPhone,
|
||||||
|
hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.patientPhone)
|
||||||
|
).paddingSymmetrical(0, 8),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPatientCityField(BuildContext context, ReferralFormManager formManager) {
|
||||||
|
return DropdownWidget(
|
||||||
|
labelText: 'City',
|
||||||
|
hintText: formManager.formData.patientCity?.description ?? "Select City".needTranslation,
|
||||||
|
isEnable: false,
|
||||||
|
hasSelectionCustomIcon: true,
|
||||||
|
labelColor: Colors.black,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||||
|
selectionCustomIcon: AppAssets.arrow_down,
|
||||||
|
leadingIcon: AppAssets.globe,
|
||||||
|
dropdownItems: [],
|
||||||
|
errorMessage: formManager.errors.patientCity,
|
||||||
|
hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.patientCity),
|
||||||
|
).paddingSymmetrical(0, 4).onPress(() {
|
||||||
|
_showCityBottomSheet(context, formManager);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void _showCityBottomSheet(BuildContext context, ReferralFormManager formManager) {
|
||||||
|
|
||||||
|
showCommonBottomSheetWithoutHeight(
|
||||||
|
context,
|
||||||
|
title: "Select City".needTranslation,
|
||||||
|
child: Consumer<HmgServicesViewModel>(
|
||||||
|
builder: (context, hmgServicesVM, child) {
|
||||||
|
final cities = hmgServicesVM.getAllCitiesList;
|
||||||
|
if (cities == null || cities.isEmpty) {
|
||||||
|
return const Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(16.0),
|
||||||
|
child: Text('No cities available'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DecoratedBox(
|
||||||
|
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
customBorder: BorderRadius.all(Radius.circular(24.h)) ,
|
||||||
|
|
||||||
|
), child: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: EdgeInsets.all(16.h),
|
||||||
|
physics: const BouncingScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final city = cities[index];
|
||||||
|
return ListTile(
|
||||||
|
title: (city.description ?? 'Unknown').toText14(),
|
||||||
|
onTap: () {
|
||||||
|
formManager.updatePatientCity(city);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// separatorBuilder: (context, index) => const Divider(),
|
||||||
|
itemCount: cities.length,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
useSafeArea: true,
|
||||||
|
isFullScreen: false,
|
||||||
|
isCloseButtonVisible: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_identificationController.dispose();
|
||||||
|
_nameController.dispose();
|
||||||
|
_phoneController.dispose();
|
||||||
|
_identificationFocusNode.dispose();
|
||||||
|
_nameFocusNode.dispose();
|
||||||
|
_phoneFocusNode.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,206 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/app_export.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/utils/validation_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/presentation/e_referral/e_referral_form_manager.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/app_assets.dart';
|
||||||
|
import 'package:hmg_patient_app_new/features/hmg_services/hmg_services_view_model.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/dropdown/dropdown_widget.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
|
||||||
|
|
||||||
|
class RequesterFormStep extends StatefulWidget {
|
||||||
|
const RequesterFormStep({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<RequesterFormStep> createState() => RequesterFormStepState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class RequesterFormStepState extends State<RequesterFormStep> {
|
||||||
|
late TextEditingController _nameController;
|
||||||
|
late TextEditingController _phoneController;
|
||||||
|
late TextEditingController _otherNameController;
|
||||||
|
|
||||||
|
late FocusNode _nameFocusNode;
|
||||||
|
late FocusNode _phoneFocusNode;
|
||||||
|
late FocusNode _otherNameFocusNode;
|
||||||
|
|
||||||
|
late ReferralFormManager _formManager;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_formManager = context.read<ReferralFormManager>();
|
||||||
|
|
||||||
|
_nameController = TextEditingController();
|
||||||
|
_phoneController = TextEditingController();
|
||||||
|
_otherNameController = TextEditingController();
|
||||||
|
|
||||||
|
_nameFocusNode = FocusNode();
|
||||||
|
_phoneFocusNode = FocusNode();
|
||||||
|
_otherNameFocusNode = FocusNode();
|
||||||
|
|
||||||
|
// Initialize controllers with current values
|
||||||
|
_nameController.text = _formManager.formData.requesterName ?? '';
|
||||||
|
_phoneController.text = _formManager.formData.requesterPhone ?? '';
|
||||||
|
_otherNameController.text = _formManager.formData.otherRelationshipName ?? '';
|
||||||
|
|
||||||
|
// Auto-focus the name field when the step loads
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (mounted) {
|
||||||
|
_nameFocusNode.requestFocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Consumer<ReferralFormManager>(
|
||||||
|
builder: (context, formManager, child) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 0.0),
|
||||||
|
child: ListView(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const BouncingScrollPhysics(),
|
||||||
|
children: [
|
||||||
|
// const SizedBox(height: 12),
|
||||||
|
_buildSectionTitle('Referral requester information'.needTranslation),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildNameField(formManager),
|
||||||
|
// _buildPhoneField(formManager),
|
||||||
|
_buildRelationshipField(context, formManager),
|
||||||
|
if (_showOtherNameField(formManager)) _buildOtherNameField(formManager),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSectionTitle(String title) {
|
||||||
|
return Text(
|
||||||
|
title,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w700, fontSize: 16)
|
||||||
|
).paddingSymmetrical(4, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildNameField(ReferralFormManager formManager) {
|
||||||
|
return Focus(
|
||||||
|
focusNode: _nameFocusNode,
|
||||||
|
child: TextInputWidget(
|
||||||
|
controller: _nameController,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
hintText: 'Enter Referral Requester Name*'.needTranslation,
|
||||||
|
labelText: 'Requester Name'.needTranslation,
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
errorMessage: formManager.errors.requesterName,
|
||||||
|
isAllowLeadingIcon: true,
|
||||||
|
leadingIcon: AppAssets.user_circle,
|
||||||
|
hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.requesterName),
|
||||||
|
onChange: (value) {
|
||||||
|
formManager.updateRequesterName(value ?? '');
|
||||||
|
},
|
||||||
|
|
||||||
|
).paddingSymmetrical(0, 8),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Widget _buildRelationshipField(BuildContext context, ReferralFormManager formManager) {
|
||||||
|
return DropdownWidget(
|
||||||
|
labelText: "Relationship".needTranslation,
|
||||||
|
hintText: formManager.formData.relationship?.textEn ?? "Select Relation".needTranslation,
|
||||||
|
isEnable: false,
|
||||||
|
selectedValue: formManager.formData.relationship?.textEn ?? "Select Relation".needTranslation,
|
||||||
|
errorMessage: formManager.errors.relationship,
|
||||||
|
hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.relationship),
|
||||||
|
hasSelectionCustomIcon: false,
|
||||||
|
labelColor: Colors.black,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||||
|
leadingIcon: AppAssets.user_circle,
|
||||||
|
dropdownItems: [],
|
||||||
|
).paddingSymmetrical(0, 8).onPress(() {
|
||||||
|
_showRelationshipBottomSheet(context, formManager);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildOtherNameField(ReferralFormManager formManager) {
|
||||||
|
return Focus(
|
||||||
|
focusNode: _otherNameFocusNode,
|
||||||
|
child: TextInputWidget(
|
||||||
|
controller: _otherNameController,
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
hintText: 'Other Name*'.needTranslation,
|
||||||
|
labelText: 'Other Name'.needTranslation,
|
||||||
|
errorMessage: formManager.errors.otherRelationshipName,
|
||||||
|
onChange: (value) {
|
||||||
|
formManager.updateOtherRelationshipName(value ?? '');
|
||||||
|
},
|
||||||
|
).paddingSymmetrical(0, 4),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _showOtherNameField(ReferralFormManager formManager) {
|
||||||
|
return formManager.formData.relationship != null &&
|
||||||
|
formManager.formData.relationship?.iD == 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showRelationshipBottomSheet(BuildContext context, ReferralFormManager formManager) {
|
||||||
|
final hmgServicesVM = context.read<HmgServicesViewModel>();
|
||||||
|
|
||||||
|
showCommonBottomSheetWithoutHeight(
|
||||||
|
context,
|
||||||
|
title: "Select Relation".needTranslation,
|
||||||
|
child: Consumer<HmgServicesViewModel>(
|
||||||
|
builder: (context, hmgServicesVM, child) {
|
||||||
|
if (hmgServicesVM.relationTypes.isEmpty) {
|
||||||
|
return const Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(16.0),
|
||||||
|
child: Text('No relationships available'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DecoratedBox(
|
||||||
|
decoration: RoundedRectangleBorder().toSmoothCornerDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
customBorder: BorderRadius.all(Radius.circular(24.h)) ,
|
||||||
|
|
||||||
|
), child: ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
padding: EdgeInsets.all(16.h),
|
||||||
|
physics: const BouncingScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final relationship = hmgServicesVM.relationTypes[index];
|
||||||
|
return ListTile(
|
||||||
|
title:relationship.textEn?.toText14(),
|
||||||
|
onTap: () {
|
||||||
|
formManager.updateRelationship(relationship);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
//separatorBuilder: (context, index) => const Divider(),
|
||||||
|
itemCount: hmgServicesVM.relationTypes.length,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
isFullScreen: false,
|
||||||
|
isCloseButtonVisible: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_nameController.dispose();
|
||||||
|
_phoneController.dispose();
|
||||||
|
_otherNameController.dispose();
|
||||||
|
_nameFocusNode.dispose();
|
||||||
|
_phoneFocusNode.dispose();
|
||||||
|
_otherNameFocusNode.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,199 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/utils/validation_utils.dart';
|
||||||
|
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||||
|
import 'package:hmg_patient_app_new/presentation/e_referral/e_referral_form_manager.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/app_assets.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/dropdown/dropdown_widget.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/input_widget.dart';
|
||||||
|
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
|
||||||
|
|
||||||
|
class SearchEReferralFormForm extends StatefulWidget {
|
||||||
|
final VoidCallback? onFormValidated;
|
||||||
|
const SearchEReferralFormForm({super.key, this.onFormValidated});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SearchEReferralFormForm> createState() => SearchEReferralFormFormState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchEReferralFormFormState extends State<SearchEReferralFormForm> {
|
||||||
|
late TextEditingController _searchController;
|
||||||
|
late TextEditingController _phoneController;
|
||||||
|
late FocusNode _searchFocusNode;
|
||||||
|
late FocusNode _phoneFocusNode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_searchController = TextEditingController();
|
||||||
|
_phoneController = TextEditingController();
|
||||||
|
_searchFocusNode = FocusNode();
|
||||||
|
_phoneFocusNode = FocusNode();
|
||||||
|
|
||||||
|
// Initialize controllers with current values from form manager
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (mounted) {
|
||||||
|
final formManager = context.read<ReferralFormManager>();
|
||||||
|
_searchController.text = formManager.searchValue ?? '';
|
||||||
|
_phoneController.text = formManager.searchPhone ?? '';
|
||||||
|
// _searchFocusNode.requestFocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Consumer<ReferralFormManager>(
|
||||||
|
builder: (context, formManager, child) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24.0),
|
||||||
|
child: ListView(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
children: [
|
||||||
|
// const SizedBox(height: 12),
|
||||||
|
_buildSelectionField(context, formManager),
|
||||||
|
_buildNameField(formManager),
|
||||||
|
_buildPhoneField(formManager),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildNameField(ReferralFormManager formManager) {
|
||||||
|
return Focus(
|
||||||
|
focusNode: _searchFocusNode,
|
||||||
|
autofocus: true,
|
||||||
|
child: TextInputWidget(
|
||||||
|
controller: _searchController,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
hintText: formManager.searchCriteria == 0 ? "Enter Identification Number" : "Enter Referral Number",
|
||||||
|
labelText: formManager.searchCriteria == 0 ? "Identification Number" : "Referral Number",
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
errorMessage: formManager.errors.searchValue,
|
||||||
|
hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.searchValue),
|
||||||
|
onChange: (value) {
|
||||||
|
formManager.updateSearchValue(value ?? '');
|
||||||
|
//_validateForm(formManager);
|
||||||
|
},
|
||||||
|
).paddingSymmetrical(0, 8),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPhoneField(ReferralFormManager formManager) {
|
||||||
|
return Focus(
|
||||||
|
focusNode: _phoneFocusNode,
|
||||||
|
autofocus: false,
|
||||||
|
child: TextInputWidget(
|
||||||
|
autoFocus: false,
|
||||||
|
labelText: 'Phone Number',
|
||||||
|
hintText: "5xxxxxxxx",
|
||||||
|
controller: _phoneController,
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
onChange: (value) {
|
||||||
|
formManager.updateSearchPhone(value ?? '');
|
||||||
|
// _validateForm(formManager);
|
||||||
|
},
|
||||||
|
// onSubmitted: (value) {
|
||||||
|
// formManager.updateRequesterPhone(value ?? '');
|
||||||
|
// _validateForm(formManager);
|
||||||
|
// },
|
||||||
|
onCountryChange: (value) {
|
||||||
|
formManager.updateCountryEnum(value);
|
||||||
|
// _validateForm(formManager);
|
||||||
|
},
|
||||||
|
prefix: '966',
|
||||||
|
isBorderAllowed: false,
|
||||||
|
isAllowLeadingIcon: true,
|
||||||
|
fontSize: 13,
|
||||||
|
isCountryDropDown: true,
|
||||||
|
leadingIcon: AppAssets.smart_phone,
|
||||||
|
errorMessage: formManager.errors.searchPhone,
|
||||||
|
hasError: !ValidationUtils.isNullOrEmpty(formManager.errors.searchPhone),
|
||||||
|
).paddingSymmetrical(0, 8),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSelectionField(BuildContext context, ReferralFormManager formManager) {
|
||||||
|
return DropdownWidget(
|
||||||
|
labelText: "Select the Search Criteria",
|
||||||
|
hintText: formManager.searchCriteria == 0 ? "Identification Number" : "Referral Number",
|
||||||
|
isEnable: false,
|
||||||
|
hasSelectionCustomIcon: false,
|
||||||
|
labelColor: Colors.black,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||||
|
leadingIcon: AppAssets.search_icon,
|
||||||
|
dropdownItems: [],
|
||||||
|
).paddingSymmetrical(0, 8).onPress(() {
|
||||||
|
_showCriteriaBottomSheet(context, formManager);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showCriteriaBottomSheet(BuildContext context, ReferralFormManager formManager) {
|
||||||
|
final criteriaList = [
|
||||||
|
{0: 'Identification Number'},
|
||||||
|
{1: 'Referral Number'},
|
||||||
|
];
|
||||||
|
|
||||||
|
showCommonBottomSheetWithoutHeight(
|
||||||
|
context,
|
||||||
|
title: "Select Criteria",
|
||||||
|
child: ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const BouncingScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final criteria = criteriaList[index];
|
||||||
|
final criteriaKey = criteria.keys.first;
|
||||||
|
final criteriaValue = criteria.values.first;
|
||||||
|
|
||||||
|
return ListTile(
|
||||||
|
leading: Radio<int>(
|
||||||
|
value: criteriaKey,
|
||||||
|
groupValue: formManager.searchCriteria,
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
formManager.updateSearchCriteria(value);
|
||||||
|
_searchController.clear();
|
||||||
|
_validateForm(formManager);
|
||||||
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
title: Text(criteriaValue),
|
||||||
|
onTap: () {
|
||||||
|
formManager.updateSearchCriteria(criteriaKey);
|
||||||
|
_searchController.clear();
|
||||||
|
_validateForm(formManager);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (context, index) => const Divider(),
|
||||||
|
itemCount: criteriaList.length,
|
||||||
|
),
|
||||||
|
isFullScreen: false,
|
||||||
|
isCloseButtonVisible: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _validateForm(ReferralFormManager formManager) {
|
||||||
|
// Trigger validation
|
||||||
|
formManager.validateSearchForm();
|
||||||
|
|
||||||
|
// Notify parent if form validation state changes
|
||||||
|
widget.onFormValidated?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_searchController.dispose();
|
||||||
|
_phoneController.dispose();
|
||||||
|
_searchFocusNode.dispose();
|
||||||
|
_phoneFocusNode.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hmg_patient_app_new/core/app_export.dart';
|
||||||
|
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||||
|
|
||||||
|
class StepperWidget extends StatelessWidget {
|
||||||
|
|
||||||
|
double width = 80.w;
|
||||||
|
Color activeColor = AppColors.primaryRedColor;
|
||||||
|
bool hasThumb = true;
|
||||||
|
double? height = 4.h;
|
||||||
|
StepperWidget( this.width, this.activeColor, this.hasThumb, this.height, {super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return oneProgressBar(width, activeColor, hasThumb);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget oneProgressBar(double width, Color color, bool hasThumb) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
AnimatedSize(
|
||||||
|
duration: const Duration(seconds: 1),
|
||||||
|
child: SizedBox(
|
||||||
|
height: 28.h,
|
||||||
|
width: width,
|
||||||
|
child: Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: height,
|
||||||
|
child: Container(
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: color,
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.circular(30.h)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Visibility(
|
||||||
|
visible: hasThumb,
|
||||||
|
child: Positioned(
|
||||||
|
top: -6.h, // move thumb above bar center
|
||||||
|
left: width - 22.h, // move to right end
|
||||||
|
child: thumb(color),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 8.h)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget thumb(Color color) {
|
||||||
|
return Container(
|
||||||
|
width: 18.h,
|
||||||
|
height: 18.h,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: color,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(color: Colors.white, width: 2.h)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue