user mangmnt validations
This commit is contained in:
parent
16e58dca07
commit
4121213bff
@ -867,26 +867,30 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: Image.asset(
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
if (plan.statusValue ==
|
||||
"Pending Approval" ||
|
||||
plan.statusValue ==
|
||||
"Partially Approved")
|
||||
IconButton(
|
||||
icon: Image.asset(
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
),
|
||||
tooltip:
|
||||
'Edit The Trip Details',
|
||||
onPressed: () {
|
||||
Navigator.pop(
|
||||
context,
|
||||
);
|
||||
ApiService.viewPlan(
|
||||
context,
|
||||
plan.planId,
|
||||
isViewMode:
|
||||
false,
|
||||
);
|
||||
},
|
||||
),
|
||||
tooltip:
|
||||
'Edit The Trip Details',
|
||||
onPressed: () {
|
||||
Navigator.pop(
|
||||
context,
|
||||
);
|
||||
ApiService.viewPlan(
|
||||
context,
|
||||
plan.planId,
|
||||
isViewMode:
|
||||
false,
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons
|
||||
|
||||
@ -347,6 +347,8 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
(plan.userName?.toLowerCase().contains(lowerQuery) ?? false) ||
|
||||
(plan.travellerName?.toLowerCase().contains(lowerQuery) ??
|
||||
false) ||
|
||||
(plan.approverName?.toLowerCase().contains(lowerQuery) ??
|
||||
false) ||
|
||||
(plan.tripType?.toLowerCase().contains(lowerQuery) ?? false) ||
|
||||
(plan.createdOn?.toLowerCase().contains(lowerQuery) ?? false) ||
|
||||
(plan.statusValue?.toLowerCase().contains(lowerQuery) ?? false);
|
||||
@ -674,7 +676,7 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
),
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Emp Code',
|
||||
'Traveller',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
@ -683,7 +685,7 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
),
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Traveller',
|
||||
'Approver',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
@ -753,19 +755,40 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
plan.employeeCode ?? " - ",
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
|
||||
children: [
|
||||
SizedBox(height: 1),
|
||||
Text(
|
||||
plan.userName.isNotEmpty
|
||||
? plan.userName
|
||||
: plan.travellerName,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
),
|
||||
SizedBox(height: 3),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"(${plan.employeeCode})" ??
|
||||
" - ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 10,
|
||||
// fontFamily: "Inter",
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
plan.userName.isNotEmpty
|
||||
? plan.userName
|
||||
: plan.travellerName,
|
||||
plan.approverName ?? " ",
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
@ -877,40 +900,44 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: Image.asset(
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
if (plan.statusValue ==
|
||||
"Pending Approval" ||
|
||||
plan.statusValue ==
|
||||
"Partially Approved")
|
||||
IconButton(
|
||||
icon: Image.asset(
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
),
|
||||
tooltip:
|
||||
'Edit The Trip Details',
|
||||
onPressed: () {
|
||||
print(
|
||||
"Approver Edit : ${plan.approverId}",
|
||||
);
|
||||
print(
|
||||
"Approver Edit2 : ${plan.delegaterId}",
|
||||
);
|
||||
print(
|
||||
"Approver Edit3 : ${plan.approver_status}",
|
||||
);
|
||||
Navigator.pop(
|
||||
context,
|
||||
);
|
||||
ApiService.viewPlanForApprover(
|
||||
context,
|
||||
plan.planId,
|
||||
plan.approverId,
|
||||
plan.delegaterId,
|
||||
plan.approver_status,
|
||||
isViewMode:
|
||||
false,
|
||||
isApprover:
|
||||
true,
|
||||
);
|
||||
},
|
||||
),
|
||||
tooltip:
|
||||
'Edit The Trip Details',
|
||||
onPressed: () {
|
||||
print(
|
||||
"Approver Edit : ${plan.approverId}",
|
||||
);
|
||||
print(
|
||||
"Approver Edit2 : ${plan.delegaterId}",
|
||||
);
|
||||
print(
|
||||
"Approver Edit3 : ${plan.approver_status}",
|
||||
);
|
||||
Navigator.pop(
|
||||
context,
|
||||
);
|
||||
ApiService.viewPlanForApprover(
|
||||
context,
|
||||
plan.planId,
|
||||
plan.approverId,
|
||||
plan.delegaterId,
|
||||
plan.approver_status,
|
||||
isViewMode:
|
||||
false,
|
||||
isApprover:
|
||||
true,
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons
|
||||
@ -1135,31 +1162,37 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: Image.asset(
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
),
|
||||
tooltip:
|
||||
'Edit The Trip Details',
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
print(
|
||||
"Approver Edit3 : ${plan.approver_status}",
|
||||
);
|
||||
if (plan.statusValue ==
|
||||
"Pending Approval" ||
|
||||
plan.statusValue ==
|
||||
"Partially Approved")
|
||||
IconButton(
|
||||
icon: Image.asset(
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
),
|
||||
tooltip:
|
||||
'Edit The Trip Details',
|
||||
onPressed: () {
|
||||
Navigator.pop(
|
||||
context,
|
||||
);
|
||||
print(
|
||||
"Approver Edit3 : ${plan.approver_status}",
|
||||
);
|
||||
|
||||
ApiService.viewPlanForApprover(
|
||||
context,
|
||||
plan.planId,
|
||||
plan.approverId,
|
||||
plan.delegaterId,
|
||||
plan.approver_status,
|
||||
isViewMode: false,
|
||||
isApprover: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
ApiService.viewPlanForApprover(
|
||||
context,
|
||||
plan.planId,
|
||||
plan.approverId,
|
||||
plan.delegaterId,
|
||||
plan.approver_status,
|
||||
isViewMode: false,
|
||||
isApprover: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.cancel_rounded,
|
||||
|
||||
@ -766,7 +766,7 @@ class _TravelerFormState extends State<TravelerForm> {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
"Create Traveler",
|
||||
"Create Traveller",
|
||||
style: GoogleFonts.poppins(color: Colors.black54),
|
||||
),
|
||||
SizedBox(height: 7),
|
||||
|
||||
@ -127,7 +127,6 @@ class ForexDataState extends State<ForexData> {
|
||||
selectedCountryName =
|
||||
data['country_name']; // For dropdown label or display
|
||||
selectedCurrency = data['currency']; // Optional if used elsewhere
|
||||
|
||||
controllers['currency']?.text = data['currency'] ?? '';
|
||||
controllers['cash']?.text = data['cash_percentage'] ?? '';
|
||||
controllers['card']?.text = data['card_percentage'] ?? '';
|
||||
@ -336,6 +335,16 @@ class ForexDataState extends State<ForexData> {
|
||||
|
||||
selectedCountry ??= null;
|
||||
|
||||
void setCurrencyFromSelectedCountry(String selectedCountryCode) {
|
||||
final matchedCountry = countryList.firstWhere(
|
||||
(item) => item['country_code'] == selectedCountryCode,
|
||||
orElse: () => {},
|
||||
);
|
||||
|
||||
final currency = matchedCountry['currency'] ?? '';
|
||||
controllers["currency"]?.text = currency;
|
||||
}
|
||||
|
||||
return AlertDialog(
|
||||
backgroundColor: Colors.white,
|
||||
contentPadding: const EdgeInsets.fromLTRB(34, 30, 34, 30),
|
||||
@ -426,6 +435,7 @@ class ForexDataState extends State<ForexData> {
|
||||
.firstWhere((entry) => entry.value == newValue)
|
||||
.key;
|
||||
selectedCountryName = newValue;
|
||||
setCurrencyFromSelectedCountry(selectedCountry!);
|
||||
});
|
||||
},
|
||||
),
|
||||
@ -457,6 +467,7 @@ class ForexDataState extends State<ForexData> {
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
color: Colors.transparent,
|
||||
|
||||
// width: isDesktop
|
||||
// ? MediaQuery.of(context).size.width * 0.330
|
||||
// : MediaQuery.of(context).size.width * 0.66,
|
||||
@ -464,9 +475,13 @@ class ForexDataState extends State<ForexData> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
controller: controllers["currency"],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
color: Colors.black,
|
||||
),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Currency",
|
||||
enabled: false,
|
||||
labelStyle: TextStyle(fontSize: 11, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
|
||||
@ -458,7 +458,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
print("flightFirstTripDateNotifier is null or empty");
|
||||
}
|
||||
|
||||
final flightDateEnd = flightFirstTripDateNotifier.value;
|
||||
final flightDateEnd = flightLastTripDateNotifier.value;
|
||||
|
||||
if (flightDateEnd != null && flightDateEnd.trim().isNotEmpty) {
|
||||
try {
|
||||
@ -2174,7 +2174,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Delivery Location",
|
||||
"Delivery Location *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
@ -2194,6 +2194,9 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_deliveryLocation"],
|
||||
controller: textControllers["_deliveryLocation"],
|
||||
onChanged: (value) {
|
||||
errorMessages.remove("delivery_location");
|
||||
},
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Location",
|
||||
@ -2239,10 +2242,10 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
onChanged: (bool? value) {
|
||||
setState(() {
|
||||
isChecked = value!;
|
||||
if (isChecked) {
|
||||
textControllers["_cardNumber"]
|
||||
?.clear(); // Clear the value when isChecked is true
|
||||
}
|
||||
// if (isChecked) {
|
||||
// textControllers["_cardNumber"]
|
||||
// ?.clear(); // Clear the value when isChecked is true
|
||||
// }
|
||||
});
|
||||
},
|
||||
),
|
||||
|
||||
@ -311,7 +311,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Number of Passenger",
|
||||
"Number of Passenger*",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
@ -404,7 +404,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
// focusNode: _taxiReqFocusNode,
|
||||
items: purposeList.cast<Map<String, dynamic>>(),
|
||||
selectedItem: purposeList.firstWhere(
|
||||
(item) => item['dropdown_key'] == selectedCarType,
|
||||
(item) => item['dropdown_key'] == selectedCarType,
|
||||
orElse: () => {},
|
||||
),
|
||||
itemAsString: (item) => item['dropdown_value'] ?? '',
|
||||
@ -456,16 +456,14 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
);
|
||||
},
|
||||
onChanged:
|
||||
purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedCarType = newValue as String?;
|
||||
});
|
||||
print(
|
||||
"Updating form data: -> ${newValue ?? ""}",
|
||||
);
|
||||
}
|
||||
: null,
|
||||
purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedCarType = newValue as String?;
|
||||
});
|
||||
print("Updating form data: -> ${newValue ?? ""}");
|
||||
}
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -544,9 +542,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
isFocused: _taxiReqFocused,
|
||||
isDesktop: isDesktop,
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
@ -554,7 +552,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
// focusNode: _taxiReqFocusNode,
|
||||
items: purposeList.cast<Map<String, dynamic>>(),
|
||||
selectedItem: purposeList.firstWhere(
|
||||
(item) => item['dropdown_key'] == selectedReqTaxi,
|
||||
(item) => item['dropdown_key'] == selectedReqTaxi,
|
||||
orElse: () => {},
|
||||
),
|
||||
itemAsString: (item) => item['dropdown_value'] ?? '',
|
||||
@ -591,31 +589,23 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
if (selectedItem == null || selectedItem.isEmpty) {
|
||||
return Text(
|
||||
"Select ",
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.grey,
|
||||
fontSize: 13,
|
||||
),
|
||||
style: GoogleFonts.poppins(color: Colors.grey, fontSize: 13),
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
selectedItem['dropdown_value'] ?? '',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
),
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
);
|
||||
},
|
||||
onChanged:
|
||||
purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedReqTaxi = newValue as String?;
|
||||
});
|
||||
print(
|
||||
"Updating form data: -> ${newValue ?? ""}",
|
||||
);
|
||||
}
|
||||
: null,
|
||||
purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedReqTaxi = newValue as String?;
|
||||
});
|
||||
print("Updating form data: -> ${newValue ?? ""}");
|
||||
}
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -282,6 +282,8 @@ class _CreatePlansState extends State<CreatePlan> {
|
||||
context.go('/listAllPlan');
|
||||
} else if (currentUri == "/createPlan") {
|
||||
context.go('/listPlan');
|
||||
} else if (currentUri == "/approver/plans") {
|
||||
context.go('/approvallist');
|
||||
} else {
|
||||
isApprover ? context.go('/approvallist') : context.go('/listPlan');
|
||||
}
|
||||
|
||||
@ -1420,6 +1420,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
disabledBackgroundColor:
|
||||
layoutColor, // Ensure color remains when disabled
|
||||
disabledForegroundColor: Colors.white,
|
||||
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: layoutColor, width: 2),
|
||||
@ -1482,9 +1483,10 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Colors.white, width: 2),
|
||||
side: BorderSide(color: layoutColor, width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 18),
|
||||
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||
),
|
||||
onPressed: handleBack,
|
||||
// onPressed:
|
||||
|
||||
@ -314,8 +314,8 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
_buildPassportDataRow1(widget.isDesktop),
|
||||
SizedBox(height: 10),
|
||||
// _buildPassportDataRow1(widget.isDesktop),
|
||||
// SizedBox(height: 10),
|
||||
_buildFirstRow(widget.isDesktop),
|
||||
SizedBox(height: 10),
|
||||
_buildSecondRow(widget.isDesktop),
|
||||
|
||||
@ -203,11 +203,6 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
print("Invalid passport date format");
|
||||
}
|
||||
|
||||
if (errorMessages.isNotEmpty) {
|
||||
print("Validation failed with errors: $errorMessages");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Additional validation starts - travelDetailsData passport
|
||||
// DateTime? start_Date = travelDetailsData?['date_of_issue'];
|
||||
// DateTime? end_Date = travelDetailsData?['date_of_expiry'];
|
||||
@ -232,28 +227,44 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
// }
|
||||
// }
|
||||
|
||||
// valid_from: 20-06-2025, valid_upto: 19-06-2025
|
||||
// DateTime? valid_from = data?['valid_from'];
|
||||
// DateTime? valid_upto = data?['valid_upto'];
|
||||
//
|
||||
// if (valid_from != null &&
|
||||
// valid_upto != null &&
|
||||
// valid_from.toString().isNotEmpty &&
|
||||
// valid_upto.toString().isNotEmpty) {
|
||||
// try {
|
||||
// final format = DateFormat("dd-MM-yyyy");
|
||||
// final checkValidFrom = format.parse("$valid_from");
|
||||
// final checkValidUpto = format.parse("$valid_upto");
|
||||
//
|
||||
// if (checkValidUpto.isBefore(checkValidFrom)) {
|
||||
// // return "valid upto cannot be earlier than valid from";
|
||||
// }
|
||||
// } catch (e) {
|
||||
// // return "valid upto cannot be earlier than valid from";
|
||||
//
|
||||
// // errorMessages["end_date"] = "Invalid date format";
|
||||
// }
|
||||
// }
|
||||
// ✅ Visa entries: Validate valid_from < valid_upto for each entry
|
||||
for (var entry in visaEntries) {
|
||||
final localId = entry["local_id"];
|
||||
final fromText = entry["controller_valid_from"]?.text.trim();
|
||||
final toText = entry["controller_valid_upto"]?.text.trim();
|
||||
|
||||
if (fromText != null &&
|
||||
toText != null &&
|
||||
fromText.isNotEmpty &&
|
||||
toText.isNotEmpty) {
|
||||
try {
|
||||
final fromDate = format.parseStrict(fromText);
|
||||
final toDate = format.parseStrict(toText);
|
||||
|
||||
if (toDate.isBefore(fromDate)) {
|
||||
print("VisaErroer1");
|
||||
errorMessages["valid_upto${entry['local_id']}"] =
|
||||
"Invalid date range";
|
||||
// errorMessages["valid_upto_$localId"] =
|
||||
// "Valid Upto can't be before Valid From";
|
||||
} else {
|
||||
print("VisaErroer2");
|
||||
// errorMessages.remove("valid_upto$localId");
|
||||
errorMessages.remove("valid_upto${entry['local_id']}");
|
||||
}
|
||||
} catch (e) {
|
||||
print("VisaErroer3");
|
||||
errorMessages["valid_upto${entry['local_id']}"] =
|
||||
"Invalid date format";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errorMessages.isNotEmpty) {
|
||||
print("Validation failed with errors: $errorMessages");
|
||||
setState(() {}); // Refresh UI to show errors
|
||||
return false;
|
||||
}
|
||||
print("travel validation end");
|
||||
return true;
|
||||
}
|
||||
@ -2205,7 +2216,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
vertical: 8,
|
||||
),
|
||||
child: Text(
|
||||
item['dropdown_value'] ?? '',
|
||||
item['dropdown_value'] ?? 'Select',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
@ -2217,7 +2228,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
dropdownDecoratorProps: const DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintText: "Select Seat",
|
||||
hintText: "Select",
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 5,
|
||||
@ -2230,7 +2241,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
dropdownBuilder: (context, selectedItem) {
|
||||
if (selectedItem == null || selectedItem.isEmpty) {
|
||||
return Text(
|
||||
"Select Seat", // fallback text
|
||||
"Select ", // fallback text
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
@ -2238,7 +2249,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
selectedItem['dropdown_value'] ?? "Select Seat",
|
||||
selectedItem['dropdown_value'] ?? "Select ",
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
);
|
||||
},
|
||||
@ -2618,7 +2629,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
vertical: 8,
|
||||
),
|
||||
child: Text(
|
||||
item['dropdown_value'] ?? '',
|
||||
item['dropdown_value'] ?? 'Select Seat',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
@ -4168,6 +4179,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||
);
|
||||
|
||||
print("CheckOut - $_selectedCheckOutDate");
|
||||
print("CheckIn - $_selectedCheckInDate");
|
||||
|
||||
if (pickedDate != null && pickedDate != _selectedCheckOutDate) {
|
||||
setState(() {
|
||||
_selectedCheckInDate = pickedDate;
|
||||
@ -4178,9 +4192,14 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
// Revalidate expiry
|
||||
if (_selectedCheckOutDate != null &&
|
||||
_selectedCheckOutDate!.isBefore(_selectedCheckInDate!)) {
|
||||
errorMessages["valid_upto"] = "Invalid Date Range";
|
||||
print("Entry - $entry");
|
||||
print("errorMessages - $errorMessages");
|
||||
errorMessages["valid_upto${entry['local_id']}"] =
|
||||
"Invalid Date Range";
|
||||
// errorMessages["valid_upto"] = "Invalid Date Range";
|
||||
} else {
|
||||
errorMessages.remove("valid_upto");
|
||||
errorMessages.remove("valid_upto${entry['local_id']}");
|
||||
// errorMessages.remove("valid_upto");
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -4295,9 +4314,10 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
|
||||
if (_selectedCheckInDate != null &&
|
||||
_selectedCheckOutDate!.isBefore(_selectedCheckInDate!)) {
|
||||
errorMessages["valid_upto"] = "Invalid Date Range";
|
||||
errorMessages["valid_upto${entry['local_id']}"] =
|
||||
"Invalid Date Range";
|
||||
} else {
|
||||
errorMessages.remove("valid_upto");
|
||||
errorMessages.remove("valid_upto${entry['local_id']}");
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -4326,6 +4346,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
errorMessages.remove("valid_upto${entry['local_id']}");
|
||||
await _selectValidUpToDate(context);
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
@ -4352,10 +4373,10 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["valid_upto"] != null) ...[
|
||||
if (errorMessages["valid_upto${entry['local_id']}"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["valid_upto"]!,
|
||||
errorMessages["valid_upto${entry['local_id']}"]!,
|
||||
style: GoogleFonts.poppins(color: Colors.red, fontSize: 10),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
|
||||
@ -15,6 +15,7 @@ class Plan {
|
||||
|
||||
final String userName;
|
||||
final String travellerName;
|
||||
final String approverName;
|
||||
final String statusValue;
|
||||
final String createdOn;
|
||||
final String? approverId;
|
||||
@ -35,6 +36,7 @@ class Plan {
|
||||
required this.isBillable,
|
||||
required this.userName,
|
||||
required this.travellerName,
|
||||
required this.approverName,
|
||||
required this.statusValue,
|
||||
required this.createdOn,
|
||||
this.approverId,
|
||||
@ -64,6 +66,10 @@ class Plan {
|
||||
json["traveller_name"] == null
|
||||
? ''
|
||||
: json["traveller_name"]!.toString(),
|
||||
approverName:
|
||||
json["approver_name"] == null
|
||||
? ''
|
||||
: json["approver_name"]!.toString(),
|
||||
statusValue: json["status_value"]!.toString(),
|
||||
createdOn: json["created_on"],
|
||||
approverId:
|
||||
|
||||
@ -21,7 +21,6 @@ class PlanPopupMenu extends StatelessWidget {
|
||||
required this.layoutColor,
|
||||
}) : super(key: key);
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Align(
|
||||
@ -30,91 +29,99 @@ class PlanPopupMenu extends StatelessWidget {
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.zero,
|
||||
offset: Offset(0, 30),
|
||||
icon: Icon(
|
||||
Icons.more_vert,
|
||||
color: Color(0xFF475569),
|
||||
size: 15,
|
||||
),
|
||||
itemBuilder: (context) => [
|
||||
CustomPopupMenuEntry(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 2, vertical: 4),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.remove_red_eye, size: 18),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
ApiService.viewPlan(context, plan.planId,
|
||||
isViewMode: true);
|
||||
},
|
||||
),
|
||||
|
||||
// IconButton(
|
||||
// icon: Image.asset('assets/images/IconsImg/edit.png',
|
||||
// width: 20, height: 15),
|
||||
// onPressed: () {
|
||||
// Navigator.pop(context);
|
||||
// ApiService.viewPlan(context, plan.planId,
|
||||
// isViewMode: false);
|
||||
// },
|
||||
// ),
|
||||
|
||||
IconButton(
|
||||
icon: Icon(Icons.cancel_rounded, size: 18),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
deletePlan(plan.planId);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.download,
|
||||
color: Color(0xFF114D8B), size: 18),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
apiService.getPdfDownload(plan.planId);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
Icons.comment,
|
||||
color: Color(0xFF475569),
|
||||
size: 11,
|
||||
icon: Icon(Icons.more_vert, color: Color(0xFF475569), size: 15),
|
||||
itemBuilder:
|
||||
(context) => [
|
||||
CustomPopupMenuEntry(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 2, vertical: 4),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.remove_red_eye, size: 18),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
ApiService.viewPlan(
|
||||
context,
|
||||
plan.planId,
|
||||
isViewMode: true,
|
||||
);
|
||||
},
|
||||
),
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => CommentModalList(
|
||||
// planId: plan.planId,
|
||||
planId: plan.planId.toString(),
|
||||
layoutColorForUser: layoutColor!,
|
||||
role: "User"),
|
||||
);
|
||||
}),
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
Icons.comment,
|
||||
color: Color(0xFF475569),
|
||||
size: 11,
|
||||
|
||||
// IconButton(
|
||||
// icon: Image.asset('assets/images/IconsImg/edit.png',
|
||||
// width: 20, height: 15),
|
||||
// onPressed: () {
|
||||
// Navigator.pop(context);
|
||||
// ApiService.viewPlan(context, plan.planId,
|
||||
// isViewMode: false);
|
||||
// },
|
||||
// ),
|
||||
IconButton(
|
||||
icon: Icon(Icons.cancel_rounded, size: 18),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
deletePlan(plan.planId);
|
||||
},
|
||||
),
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => CommentModal(
|
||||
// planId: plan.planId,
|
||||
planId: plan.planId.toString(),
|
||||
layoutColorForUser: layoutColor!,
|
||||
role: "Travel Agent"),
|
||||
);
|
||||
}),
|
||||
],
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.download,
|
||||
color: Color(0xFF114D8B),
|
||||
size: 18,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
apiService.getPdfDownload(plan.planId);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
Icons.comment,
|
||||
color: Color(0xFF475569),
|
||||
size: 11,
|
||||
),
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder:
|
||||
(context) => CommentModalList(
|
||||
// planId: plan.planId,
|
||||
planId: plan.planId.toString(),
|
||||
layoutColorForUser: layoutColor!,
|
||||
role: "User",
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
Icons.comment,
|
||||
color: Color(0xFF475569),
|
||||
size: 11,
|
||||
),
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder:
|
||||
(context) => CommentModal(
|
||||
// planId: plan.planId,
|
||||
planId: plan.planId.toString(),
|
||||
layoutColorForUser: layoutColor!,
|
||||
role: "Travel Agent",
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user