Merge branch 'main' of bitbucket.org:venbainformationtechnology/ts-tat
This commit is contained in:
commit
5ccb201b7a
@ -336,7 +336,7 @@ class CostCenterListState extends State<CostCenterList> {
|
|||||||
MainAxisSize.min, // Ensures content fits nicely
|
MainAxisSize.min, // Ensures content fits nicely
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Add CostCenter",
|
"Add Cost Center",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: isDesktop ? 13 : 11,
|
fontSize: isDesktop ? 13 : 11,
|
||||||
),
|
),
|
||||||
|
|||||||
@ -396,7 +396,7 @@ class ForexDataState extends State<ForexData> {
|
|||||||
),
|
),
|
||||||
searchFieldProps: TextFieldProps(
|
searchFieldProps: TextFieldProps(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Search Country...",
|
hintText: "Search ...",
|
||||||
hintStyle: GoogleFonts.poppins(fontSize: 11),
|
hintStyle: GoogleFonts.poppins(fontSize: 11),
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 4),
|
contentPadding: EdgeInsets.symmetric(horizontal: 4),
|
||||||
),
|
),
|
||||||
@ -414,7 +414,7 @@ class ForexDataState extends State<ForexData> {
|
|||||||
// Center-align selected item
|
// Center-align selected item
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
child: Text(
|
||||||
selectedItem ?? "Select Country",
|
selectedItem ?? "Select ",
|
||||||
style: GoogleFonts.poppins(fontSize: 11),
|
style: GoogleFonts.poppins(fontSize: 11),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -746,9 +746,9 @@ class ForexDataListState extends State<ForexDataList> {
|
|||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontFamily: "Inter",
|
fontFamily: "Inter",
|
||||||
// color: forex['is_active'] == "1"
|
color: forex['is_active'] == "1"
|
||||||
// ? Colors.green
|
? Colors.green
|
||||||
// : Colors.grey,
|
: Colors.grey,
|
||||||
),
|
),
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
|
|||||||
@ -407,7 +407,7 @@ class GroupDataState extends State<GroupData> {
|
|||||||
),
|
),
|
||||||
searchFieldProps: TextFieldProps(
|
searchFieldProps: TextFieldProps(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Select Policy For International",
|
hintText: "Search ...",
|
||||||
hintStyle: GoogleFonts.poppins(fontSize: 11),
|
hintStyle: GoogleFonts.poppins(fontSize: 11),
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 4),
|
contentPadding: EdgeInsets.symmetric(horizontal: 4),
|
||||||
),
|
),
|
||||||
@ -425,7 +425,7 @@ class GroupDataState extends State<GroupData> {
|
|||||||
// Center-align selected item
|
// Center-align selected item
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
child: Text(
|
||||||
selectedItem ?? "Select Policy For International",
|
selectedItem ?? "Select",
|
||||||
style: GoogleFonts.poppins(fontSize: 11),
|
style: GoogleFonts.poppins(fontSize: 11),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -481,7 +481,7 @@ class GroupDataState extends State<GroupData> {
|
|||||||
),
|
),
|
||||||
searchFieldProps: TextFieldProps(
|
searchFieldProps: TextFieldProps(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Select Policy For Domestic...",
|
hintText: "Search ...",
|
||||||
hintStyle: GoogleFonts.poppins(fontSize: 11),
|
hintStyle: GoogleFonts.poppins(fontSize: 11),
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 4),
|
contentPadding: EdgeInsets.symmetric(horizontal: 4),
|
||||||
),
|
),
|
||||||
@ -499,7 +499,7 @@ class GroupDataState extends State<GroupData> {
|
|||||||
// Center-align selected item
|
// Center-align selected item
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
child: Text(
|
||||||
selectedItem ?? "Select Policy For Domestic",
|
selectedItem ?? "Select ",
|
||||||
style: GoogleFonts.poppins(fontSize: 11),
|
style: GoogleFonts.poppins(fontSize: 11),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -353,7 +353,7 @@ class _GroupListState extends State<GroupList> {
|
|||||||
MainAxisSize.min, // Ensures content fits nicely
|
MainAxisSize.min, // Ensures content fits nicely
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Add New Group",
|
"Add Group",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: isDesktop ? 13 : 11,
|
fontSize: isDesktop ? 13 : 11,
|
||||||
),
|
),
|
||||||
|
|||||||
@ -418,7 +418,7 @@ class HotelsDataState extends State<HotelsData> {
|
|||||||
),
|
),
|
||||||
searchFieldProps: TextFieldProps(
|
searchFieldProps: TextFieldProps(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Search Country...",
|
hintText: "Search ...",
|
||||||
hintStyle: GoogleFonts.poppins(fontSize: 11),
|
hintStyle: GoogleFonts.poppins(fontSize: 11),
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 4),
|
contentPadding: EdgeInsets.symmetric(horizontal: 4),
|
||||||
),
|
),
|
||||||
@ -436,7 +436,7 @@ class HotelsDataState extends State<HotelsData> {
|
|||||||
// Center-align selected item
|
// Center-align selected item
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
child: Text(
|
||||||
selectedItem ?? "Select Country",
|
selectedItem ?? "Select ",
|
||||||
style: GoogleFonts.poppins(fontSize: 11),
|
style: GoogleFonts.poppins(fontSize: 11),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -437,7 +437,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Destination",
|
"Destination *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -485,7 +485,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Hotel Name",
|
"Hotel Name *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -695,7 +695,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Check-in*",
|
"Check-in *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -747,7 +747,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Time (Check-in)",
|
"Time (Check-in) *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -817,7 +817,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
|||||||
child: TextField(
|
child: TextField(
|
||||||
focusNode: _checkOutFocusNode,
|
focusNode: _checkOutFocusNode,
|
||||||
controller: _checkOutController,
|
controller: _checkOutController,
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12, color: Colors.black),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Select Date",
|
labelText: "Select Date",
|
||||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||||
@ -851,7 +851,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Time (Check-out)",
|
"Time (Check-out) *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
|
|||||||
@ -327,7 +327,8 @@ class _BusScreenState extends State<BusScreen> {
|
|||||||
child: DropdownButtonFormField<String>(
|
child: DropdownButtonFormField<String>(
|
||||||
focusNode: _tripTypeFocusNode, // Assign the correct focus node
|
focusNode: _tripTypeFocusNode, // Assign the correct focus node
|
||||||
value: selectedPurpose,
|
value: selectedPurpose,
|
||||||
style: TextStyle(fontSize: 12),
|
// style: TextStyle(fontSize: 12),
|
||||||
|
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding:
|
contentPadding:
|
||||||
@ -401,7 +402,7 @@ class _BusScreenState extends State<BusScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"From",
|
"From *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -446,7 +447,7 @@ class _BusScreenState extends State<BusScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"To",
|
"To *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -491,7 +492,7 @@ class _BusScreenState extends State<BusScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Date",
|
"Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -543,7 +544,7 @@ class _BusScreenState extends State<BusScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Time",
|
"Time *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -561,7 +562,7 @@ class _BusScreenState extends State<BusScreen> {
|
|||||||
child: TextField(
|
child: TextField(
|
||||||
focusNode: _timeFocusNode,
|
focusNode: _timeFocusNode,
|
||||||
controller: _timeController,
|
controller: _timeController,
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12, color: Colors.black),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Select Time",
|
labelText: "Select Time",
|
||||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||||
|
|||||||
@ -55,6 +55,8 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
|
|
||||||
Map<String, String?> selectedValues = {};
|
Map<String, String?> selectedValues = {};
|
||||||
|
|
||||||
|
int rowCount = 1;
|
||||||
|
|
||||||
String? selectedTripType;
|
String? selectedTripType;
|
||||||
Map<int, String?> selectedClasses = {}; // Store class selection for each trip
|
Map<int, String?> selectedClasses = {}; // Store class selection for each trip
|
||||||
Map<int, String?> selectedFrom = {}; // Store class selection for each trip
|
Map<int, String?> selectedFrom = {}; // Store class selection for each trip
|
||||||
@ -251,9 +253,14 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
Map<String, String> tempCountryMap = {};
|
Map<String, String> tempCountryMap = {};
|
||||||
|
|
||||||
for (var country in result) {
|
for (var country in result) {
|
||||||
String city = country['City'] ?? '';
|
// String city = country['City'] ?? '';
|
||||||
String airport = country['Airport'] ?? '';
|
// String airport = country['Airport'] ?? '';
|
||||||
String displayName = '${country['City']} - ${country['Airport']}';
|
// String displayName = '${country['City']} - ${country['Airport']}';
|
||||||
|
|
||||||
|
final code = country['Code'] ?? '';
|
||||||
|
final city = country['City'] ?? '';
|
||||||
|
final airport = country['Airport'] ?? '';
|
||||||
|
final displayName = '$city ($code)\n$airport';
|
||||||
|
|
||||||
tempCountryMap[country['Code']] = displayName;
|
tempCountryMap[country['Code']] = displayName;
|
||||||
}
|
}
|
||||||
@ -563,7 +570,7 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
bool validateFields() {
|
bool validateFields() {
|
||||||
errorMessages.clear(); // Reset errors
|
errorMessages.clear(); // Reset errors
|
||||||
|
|
||||||
int rowCount = 1; // Default row count for One-way
|
rowCount = 1; // Default row count for One-way
|
||||||
if (selectedTripType == "Roundtrip") {
|
if (selectedTripType == "Roundtrip") {
|
||||||
rowCount = 2; // Fixed for Roundtrip
|
rowCount = 2; // Fixed for Roundtrip
|
||||||
} else if (selectedTripType == "Multitrip") {
|
} else if (selectedTripType == "Multitrip") {
|
||||||
@ -579,9 +586,31 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
if (selectedFrom[i] == null) {
|
if (selectedFrom[i] == null) {
|
||||||
errorMessages["from_place_$i"] = "Required";
|
errorMessages["from_place_$i"] = "Required";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (selectedTo[i] == null) {
|
||||||
|
// errorMessages["to_place_$i"] = "Required";
|
||||||
|
// }else if (
|
||||||
|
// selectedFrom[i] == selectedTo[i]) {
|
||||||
|
// errorMessages["to_place_$i"] = "Change Destination";
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
if (selectedTo[i] == null) {
|
if (selectedTo[i] == null) {
|
||||||
errorMessages["to_place_$i"] = "Required";
|
errorMessages["to_place_$i"] = "Required";
|
||||||
|
print("Error: to_place_$i -> Required (selectedTo[$i] is null)");
|
||||||
|
} else if (selectedFrom[i] == selectedTo[i]) {
|
||||||
|
|
||||||
|
if(selectedTripType == "Roundtrip"){
|
||||||
|
errorMessages["to_place_1"] = "Change Destination";
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
errorMessages["to_place_$i"] = "Change Destination";
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Error: to_place_$i -> Change Destination (selectedFrom[$i] == selectedTo[$i])");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// if (textControllers["_to${i}Controller"]?.text.trim().isEmpty ?? true) {
|
// if (textControllers["_to${i}Controller"]?.text.trim().isEmpty ?? true) {
|
||||||
// errorMessages["to_place_$i"] = "Required";
|
// errorMessages["to_place_$i"] = "Required";
|
||||||
// }
|
// }
|
||||||
@ -591,8 +620,13 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
if (textControllers["_time${i}Controller"]?.text.trim().isEmpty ?? true) {
|
if (textControllers["_time${i}Controller"]?.text.trim().isEmpty ?? true) {
|
||||||
errorMessages["time_$i"] = "Required";
|
errorMessages["time_$i"] = "Required";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setState(() {}); // Update UI to show error messages
|
setState(() {}); // Update UI to show error messages
|
||||||
|
|
||||||
return errorMessages
|
return errorMessages
|
||||||
@ -882,6 +916,15 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
multiTripRowCount = 1;
|
multiTripRowCount = 1;
|
||||||
}
|
}
|
||||||
errorMessages.clear();
|
errorMessages.clear();
|
||||||
|
|
||||||
|
for (int i = 1; i <= rowCount; i++) {
|
||||||
|
textControllers["_date${i}Controller"]?.clear();
|
||||||
|
textControllers["_time${i}Controller"]?.clear();
|
||||||
|
|
||||||
|
// Also clear the actual selected data (not just the text in controllers)
|
||||||
|
selectedFrom[i] = null; // Assuming null means no selection
|
||||||
|
selectedTo[i] = null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
print(
|
print(
|
||||||
"Updating form data: Flight -> trip_type -> $selectedTripType",
|
"Updating form data: Flight -> trip_type -> $selectedTripType",
|
||||||
@ -1254,6 +1297,7 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
isCountryLoading
|
isCountryLoading
|
||||||
? Center(child: CircularProgressIndicator())
|
? Center(child: CircularProgressIndicator())
|
||||||
: DropdownSearch<String>(
|
: DropdownSearch<String>(
|
||||||
|
enabled: !(selectedTripType == "Roundtrip" && index == 2),
|
||||||
selectedItem:
|
selectedItem:
|
||||||
selectedFrom[index] != null
|
selectedFrom[index] != null
|
||||||
? countryMap[selectedFrom[index]]
|
? countryMap[selectedFrom[index]]
|
||||||
@ -1273,19 +1317,61 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
style: TextStyle(fontSize: 12),
|
style: TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
menuProps: MenuProps(backgroundColor: Colors.white),
|
menuProps: MenuProps(backgroundColor: Colors.white),
|
||||||
itemBuilder:
|
itemBuilder: (context, item, isSelected) {
|
||||||
(context, item, isSelected) => Padding(
|
final parts = item.split('\n');
|
||||||
padding: const EdgeInsets.symmetric(
|
final cityAndCode = parts[0];
|
||||||
horizontal: 8.0,
|
final airport = parts.length > 1 ? parts[1] : '';
|
||||||
vertical: 6.0,
|
|
||||||
),
|
// Extract city and code from "City (CODE)"
|
||||||
child: Text(
|
final cityMatch = RegExp(r'^(.*)\s+\(([^)]+)\)$').firstMatch(cityAndCode);
|
||||||
item,
|
final city = cityMatch?.group(1) ?? '';
|
||||||
style: TextStyle(
|
final code = cityMatch?.group(2) ?? '';
|
||||||
fontSize: 13,
|
|
||||||
), // 👈 Set your desired text size here
|
return Padding(
|
||||||
),
|
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 6.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
city,
|
||||||
|
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
code,
|
||||||
|
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 1),
|
||||||
|
Text(
|
||||||
|
airport,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 11,
|
||||||
|
color: Colors.grey,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
// itemBuilder:
|
||||||
|
// (context, item, isSelected) => Padding(
|
||||||
|
// padding: const EdgeInsets.symmetric(
|
||||||
|
// horizontal: 8.0,
|
||||||
|
// vertical: 6.0,
|
||||||
|
// ),
|
||||||
|
// child: Text(
|
||||||
|
// item,
|
||||||
|
// style: TextStyle(
|
||||||
|
// fontSize: 13,
|
||||||
|
// ), // 👈 Set your desired text size here
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
),
|
),
|
||||||
items: countryMap.values.toList(),
|
items: countryMap.values.toList(),
|
||||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||||
@ -1294,14 +1380,33 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
contentPadding: EdgeInsets.symmetric(horizontal: 1),
|
contentPadding: EdgeInsets.symmetric(horizontal: 1),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
dropdownBuilder:
|
dropdownBuilder: (context, selectedItem) {
|
||||||
(context, selectedItem) => Align(
|
if (selectedItem == null) {
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.centerLeft,child: const Text("Select", style: TextStyle(fontSize: 12)));
|
||||||
|
}
|
||||||
|
|
||||||
|
final parts = selectedItem.split('\n');
|
||||||
|
final cityAndCode = parts[0];
|
||||||
|
final airport = parts.length > 1 ? parts[1] : '';
|
||||||
|
|
||||||
|
return Align(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
child: Text(
|
||||||
selectedItem ?? "Select",
|
cityAndCode ?? "Select",
|
||||||
style: TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
// dropdownBuilder:
|
||||||
|
// (context, selectedItem) => Align(
|
||||||
|
// alignment: Alignment.centerLeft,
|
||||||
|
// child: Text(
|
||||||
|
// selectedItem ?? "Select",
|
||||||
|
// style: TextStyle(fontSize: 12),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
onChanged: (String? newValue) {
|
onChanged: (String? newValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
// selectedFrom[index] = countryMap.entries
|
// selectedFrom[index] = countryMap.entries
|
||||||
@ -1315,7 +1420,13 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
)
|
)
|
||||||
.key;
|
.key;
|
||||||
|
|
||||||
print(selectedFrom[index]);
|
if(selectedTripType == "Roundtrip"){
|
||||||
|
|
||||||
|
print('rounfTo${selectedFrom[index]}');
|
||||||
|
// textControllers["_to${index+1}Controller"]?.text = selectedFrom[index]!;
|
||||||
|
selectedTo[2]= selectedFrom[index]!;
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -1366,6 +1477,7 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
isCountryLoading
|
isCountryLoading
|
||||||
? Center(child: CircularProgressIndicator())
|
? Center(child: CircularProgressIndicator())
|
||||||
: DropdownSearch<String>(
|
: DropdownSearch<String>(
|
||||||
|
enabled: !(selectedTripType == "Roundtrip" && index == 2),
|
||||||
selectedItem:
|
selectedItem:
|
||||||
selectedTo[index] != null
|
selectedTo[index] != null
|
||||||
? countryMap[selectedTo[index]]
|
? countryMap[selectedTo[index]]
|
||||||
@ -1385,19 +1497,61 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
style: TextStyle(fontSize: 12),
|
style: TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
menuProps: MenuProps(backgroundColor: Colors.white),
|
menuProps: MenuProps(backgroundColor: Colors.white),
|
||||||
itemBuilder:
|
itemBuilder: (context, item, isSelected) {
|
||||||
(context, item, isSelected) => Padding(
|
final parts = item.split('\n');
|
||||||
padding: const EdgeInsets.symmetric(
|
final cityAndCode = parts[0];
|
||||||
horizontal: 8.0,
|
final airport = parts.length > 1 ? parts[1] : '';
|
||||||
vertical: 6.0,
|
|
||||||
),
|
|
||||||
child: Text(
|
// Extract city and code from "City (CODE)"
|
||||||
item,
|
final cityMatch = RegExp(r'^(.*)\s+\(([^)]+)\)$').firstMatch(cityAndCode);
|
||||||
style: TextStyle(
|
final city = cityMatch?.group(1) ?? '';
|
||||||
fontSize: 13,
|
final code = cityMatch?.group(2) ?? '';
|
||||||
), // 👈 Set your desired text size here
|
|
||||||
),
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 6.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
city,
|
||||||
|
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
code,
|
||||||
|
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 1),
|
||||||
|
Text(
|
||||||
|
airport,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 11,
|
||||||
|
color: Colors.grey,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// itemBuilder:
|
||||||
|
// (context, item, isSelected) => Padding(
|
||||||
|
// padding: const EdgeInsets.symmetric(
|
||||||
|
// horizontal: 8.0,
|
||||||
|
// vertical: 6.0,
|
||||||
|
// ),
|
||||||
|
// child: Text(
|
||||||
|
// item,
|
||||||
|
// style: TextStyle(
|
||||||
|
// fontSize: 13,
|
||||||
|
// ), // 👈 Set your desired text size here
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
),
|
),
|
||||||
items: countryMap.values.toList(),
|
items: countryMap.values.toList(),
|
||||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||||
@ -1406,16 +1560,36 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
contentPadding: EdgeInsets.symmetric(horizontal: 1),
|
contentPadding: EdgeInsets.symmetric(horizontal: 1),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
dropdownBuilder:
|
// dropdownBuilder:
|
||||||
(context, selectedItem) => Align(
|
// (context, selectedItem) => Align(
|
||||||
alignment: Alignment.centerLeft,
|
// alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
// child: Text(
|
||||||
selectedItem ?? "Select Country",
|
// selectedItem ?? "Select Country",
|
||||||
style: TextStyle(fontSize: 12),
|
// style: TextStyle(fontSize: 12),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
onChanged: (String? newValue) {
|
|
||||||
|
dropdownBuilder: (context, selectedItem) {
|
||||||
|
if (selectedItem == null) {
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.centerLeft,child: const Text("Select", style: TextStyle(fontSize: 12)));
|
||||||
|
}
|
||||||
|
|
||||||
|
final parts = selectedItem.split('\n');
|
||||||
|
final cityAndCode = parts[0];
|
||||||
|
final airport = parts.length > 1 ? parts[1] : '';
|
||||||
|
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Text(
|
||||||
|
cityAndCode ?? "Select",
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onChanged: (String? newValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
errorMessages.remove("to_place_$index");
|
||||||
selectedTo[index] =
|
selectedTo[index] =
|
||||||
countryMap.entries
|
countryMap.entries
|
||||||
.firstWhere(
|
.firstWhere(
|
||||||
@ -1424,6 +1598,13 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
.key;
|
.key;
|
||||||
|
|
||||||
print(selectedTo[index]);
|
print(selectedTo[index]);
|
||||||
|
|
||||||
|
if(selectedTripType == "Roundtrip"){
|
||||||
|
|
||||||
|
print('rounfTo${selectedTo[index]}');
|
||||||
|
// textControllers["_to${index+1}Controller"]?.text = selectedFrom[index]!;
|
||||||
|
selectedFrom[2]= selectedTo[index]!;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -1431,7 +1612,7 @@ class FlightScreenState extends State<FlightScreen> {
|
|||||||
),
|
),
|
||||||
if (errorMessages["to_place_$index"] != null) ...[
|
if (errorMessages["to_place_$index"] != null) ...[
|
||||||
SizedBox(height: 5), // Space before error message
|
SizedBox(height: 5), // Space before error message
|
||||||
Text("Required", style: TextStyle(color: Colors.red, fontSize: 12)),
|
Text( errorMessages["to_place_$index"]! , style: TextStyle(color: Colors.red, fontSize: 12)),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1154,7 +1154,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
|||||||
showSearchBox: true, // Enables search functionality
|
showSearchBox: true, // Enables search functionality
|
||||||
searchFieldProps: TextFieldProps(
|
searchFieldProps: TextFieldProps(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Search Country...",
|
hintText: "Search ...",
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1171,7 +1171,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
|||||||
// Center-align selected item
|
// Center-align selected item
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
child: Text(
|
||||||
selectedItem ?? "Select Country",
|
selectedItem ?? "Select ",
|
||||||
style: TextStyle(fontSize: 12),
|
style: TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:dropdown_search/dropdown_search.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
@ -39,16 +40,18 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
|||||||
final FocusNode _fromFocusNode = FocusNode();
|
final FocusNode _fromFocusNode = FocusNode();
|
||||||
final FocusNode _dateFocusNode = FocusNode();
|
final FocusNode _dateFocusNode = FocusNode();
|
||||||
final FocusNode _commentsFocusNode = FocusNode();
|
final FocusNode _commentsFocusNode = FocusNode();
|
||||||
|
final FocusNode _nomineeFocusNode = FocusNode();
|
||||||
|
|
||||||
late TextEditingController _tripTypeController = TextEditingController();
|
late TextEditingController _tripTypeController = TextEditingController();
|
||||||
late TextEditingController _startdateController = TextEditingController();
|
late TextEditingController _startdateController = TextEditingController();
|
||||||
late TextEditingController _endDateController = TextEditingController();
|
late TextEditingController _endDateController = TextEditingController();
|
||||||
late TextEditingController _insuranceCommentsController =
|
late TextEditingController _insuranceCommentsController = TextEditingController();
|
||||||
TextEditingController();
|
late TextEditingController _nomineeController = TextEditingController();
|
||||||
|
|
||||||
bool _isHotelNameFocused = false;
|
bool _isHotelNameFocused = false;
|
||||||
bool _dateFocus = false;
|
bool _dateFocus = false;
|
||||||
bool _commentsFocus = false;
|
bool _commentsFocus = false;
|
||||||
|
bool _nomineeFocus = false;
|
||||||
|
|
||||||
String? selectedTripType;
|
String? selectedTripType;
|
||||||
String? selectedInsuranceType;
|
String? selectedInsuranceType;
|
||||||
@ -61,6 +64,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
|||||||
"start_date": _startdateController.text,
|
"start_date": _startdateController.text,
|
||||||
"end_date": _endDateController.text,
|
"end_date": _endDateController.text,
|
||||||
"comments": _insuranceCommentsController.text,
|
"comments": _insuranceCommentsController.text,
|
||||||
|
"nominee_name" : _nomineeController.text,
|
||||||
"created_by": widget.loginUser,
|
"created_by": widget.loginUser,
|
||||||
"updated_by": widget.loginUser,
|
"updated_by": widget.loginUser,
|
||||||
};
|
};
|
||||||
@ -98,12 +102,20 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_nomineeFocusNode.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
_nomineeFocus = _nomineeFocusNode.hasFocus;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
_insuranceCommentsController =
|
_insuranceCommentsController =
|
||||||
TextEditingController(text: widget.selectedItem?["comments"] ?? "");
|
TextEditingController(text: widget.selectedItem?["comments"] ?? "");
|
||||||
_startdateController =
|
_startdateController =
|
||||||
TextEditingController(text: widget.selectedItem?["start_date"] ?? "");
|
TextEditingController(text: widget.selectedItem?["start_date"] ?? "");
|
||||||
_endDateController =
|
_endDateController =
|
||||||
TextEditingController(text: widget.selectedItem?['end_date'] ?? "");
|
TextEditingController(text: widget.selectedItem?['end_date'] ?? "");
|
||||||
|
_nomineeController =
|
||||||
|
TextEditingController(text: widget.selectedItem?['nominee_name'] ?? "");
|
||||||
|
|
||||||
// Set the selected value if available
|
// Set the selected value if available
|
||||||
if (widget.selectedItem != null &&
|
if (widget.selectedItem != null &&
|
||||||
@ -249,6 +261,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
|||||||
_tripTypeController.dispose();
|
_tripTypeController.dispose();
|
||||||
_startdateController.dispose();
|
_startdateController.dispose();
|
||||||
_insuranceCommentsController.dispose();
|
_insuranceCommentsController.dispose();
|
||||||
|
_nomineeController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +324,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Insurance Type",
|
"Insurance Type", // not in use
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -370,7 +383,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
|||||||
child: DropdownButtonFormField<String>(
|
child: DropdownButtonFormField<String>(
|
||||||
focusNode: _tripTypeFocusNode, // Assign the correct focus node
|
focusNode: _tripTypeFocusNode, // Assign the correct focus node
|
||||||
value: selectedInsuranceType,
|
value: selectedInsuranceType,
|
||||||
style: TextStyle(fontSize: 12),
|
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding:
|
contentPadding:
|
||||||
@ -396,6 +409,93 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
List<Widget> _buildInsuranceTypeDropdown(bool isDesktop) {
|
||||||
|
// List<dynamic> purposeList = widget.apiData?['insurance_type_of_insurance'] ?? [];
|
||||||
|
List<Map<String, dynamic>> purposeList = (widget.apiData?['insurance_type_of_insurance'] as List<dynamic>?)
|
||||||
|
?.map((e) => Map<String, dynamic>.from(e as Map))
|
||||||
|
.toList() ?? [];
|
||||||
|
|
||||||
|
// Find selected item object based on key
|
||||||
|
Map<String, dynamic>? selectedItem = purposeList.firstWhere(
|
||||||
|
(item) => item['dropdown_key'] == selectedInsuranceType,
|
||||||
|
orElse: () => {},
|
||||||
|
);
|
||||||
|
|
||||||
|
return [
|
||||||
|
CustomTextFieldWrapper(
|
||||||
|
isFocused: false,
|
||||||
|
isDesktop: isDesktop,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 35,
|
||||||
|
width: double.infinity,
|
||||||
|
child: DropdownSearch<Map<String, dynamic>>(
|
||||||
|
popupProps: PopupProps.menu(
|
||||||
|
showSearchBox: false,
|
||||||
|
fit: FlexFit.loose,
|
||||||
|
constraints: BoxConstraints(maxHeight: 10),
|
||||||
|
menuProps: const MenuProps(backgroundColor: Colors.white),
|
||||||
|
itemBuilder: (context, item, isSelected) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 10,
|
||||||
|
vertical: 8,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
item['dropdown_value'] ?? '',
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12, // 👈 Smaller font size
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
dropdownDecoratorProps: const DropDownDecoratorProps(
|
||||||
|
dropdownSearchDecoration: InputDecoration(
|
||||||
|
border: InputBorder.none, // No underline
|
||||||
|
|
||||||
|
contentPadding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10,
|
||||||
|
vertical: 5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
dropdownBuilder: (context, selectedItem) {
|
||||||
|
if (selectedItem == null || selectedItem.isEmpty) {
|
||||||
|
return Text(
|
||||||
|
"Select Insurance Type",
|
||||||
|
style: GoogleFonts.poppins(color: Colors.grey, fontSize: 13),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Text(
|
||||||
|
selectedItem['dropdown_value'] ?? '',
|
||||||
|
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
selectedItem: selectedItem!.isNotEmpty ? selectedItem : null,
|
||||||
|
itemAsString: (item) => item['dropdown_value'] ?? '',
|
||||||
|
onChanged: purposeList.isNotEmpty
|
||||||
|
? (Map<String, dynamic>? newItem) {
|
||||||
|
if (newItem != null) {
|
||||||
|
setState(() {
|
||||||
|
selectedInsuranceType = newItem['dropdown_key'];
|
||||||
|
errorMessages.remove("type_of_insurance");
|
||||||
|
});
|
||||||
|
print("Selected Insurance Type: $selectedInsuranceType");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
items: purposeList,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<Widget> _buildSecondRow(bool isDesktop) {
|
List<Widget> _buildSecondRow(bool isDesktop) {
|
||||||
List<dynamic> purposeList =
|
List<dynamic> purposeList =
|
||||||
widget.apiData?['insurance_type_of_insurance'] ?? [];
|
widget.apiData?['insurance_type_of_insurance'] ?? [];
|
||||||
@ -524,47 +624,103 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Insurance Type",
|
"Insurance Type *",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: const Color(0xFF575A74),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 5),
|
||||||
|
|
||||||
|
// ▼ Dropdown Wrapper ▼
|
||||||
|
CustomTextFieldWrapper(
|
||||||
|
isFocused: _isHotelNameFocused,
|
||||||
|
isDesktop: isDesktop,
|
||||||
|
width: isDesktop ? MediaQuery.of(context).size.width * 0.17 : null,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 35,
|
||||||
|
width: double.infinity,
|
||||||
|
child: DropdownButtonFormField<String>(
|
||||||
|
focusNode: _tripTypeFocusNode,
|
||||||
|
value: selectedInsuranceType,
|
||||||
|
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||||
|
),
|
||||||
|
hint: Text(
|
||||||
|
"Select ",
|
||||||
|
style: GoogleFonts.poppins(color: Colors.grey, fontSize: 13),
|
||||||
|
),
|
||||||
|
items: purposeList.map<DropdownMenuItem<String>>((item) {
|
||||||
|
return DropdownMenuItem<String>(
|
||||||
|
value: item['dropdown_key'],
|
||||||
|
child: Text(
|
||||||
|
item['dropdown_value'] ?? '',
|
||||||
|
style: GoogleFonts.poppins(fontSize: 12),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
onChanged: purposeList.isNotEmpty
|
||||||
|
? (String? newValue) {
|
||||||
|
setState(() {
|
||||||
|
selectedInsuranceType = newValue;
|
||||||
|
if ((selectedInsuranceType ?? '').isNotEmpty) {
|
||||||
|
errorMessages.remove("type_of_insurance");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
print("Selected Insurance Type: $selectedInsuranceType");
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
if (isDesktop)
|
||||||
|
Spacer()
|
||||||
|
else
|
||||||
|
SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Nominee",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w600,
|
||||||
color: Color(0xFF575A74)),
|
color: Color(0xFF575A74)),
|
||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldWrapper(
|
CustomTextFieldWrapper(
|
||||||
isFocused: _isHotelNameFocused,
|
isFocused: _nomineeFocus,
|
||||||
isDesktop: isDesktop,
|
isDesktop: isDesktop,
|
||||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.34 : null,
|
width: isDesktop ? MediaQuery.of(context).size.width * 0.15 : null,
|
||||||
|
// width: isDesktop ? MediaQuery.of(context).size.width * 0.34 : null,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: DropdownButtonFormField<String>(
|
child: TextField(
|
||||||
focusNode: _tripTypeFocusNode, // Assign the correct focus node
|
focusNode: _nomineeFocusNode,
|
||||||
value: selectedInsuranceType,
|
controller: _nomineeController,
|
||||||
style: TextStyle(fontSize: 12),
|
style: TextStyle(fontSize: 12),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
|
labelText: "Nominee",
|
||||||
|
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||||
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding:
|
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||||
EdgeInsets.symmetric(horizontal: 10), // Proper padding
|
// contentPadding: EdgeInsets.symmetric(horizontal: 1,vertical: 1),
|
||||||
),
|
),
|
||||||
onChanged: purposeList.isNotEmpty
|
|
||||||
? (newValue) {
|
|
||||||
setState(() {
|
|
||||||
selectedInsuranceType = newValue;
|
|
||||||
if (selectedInsuranceType!.isNotEmpty) {
|
|
||||||
errorMessages.remove("type_of_insurance");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
print(selectedInsuranceType);
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
|
|
||||||
items: dropdownItems,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -580,7 +736,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Start Date",
|
"Start Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -609,7 +765,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
|||||||
controller: _startdateController,
|
controller: _startdateController,
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Select Date",
|
labelText: "Select ",
|
||||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
@ -641,7 +797,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"End Date",
|
"End Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -682,7 +838,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
|||||||
controller: _endDateController,
|
controller: _endDateController,
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Select Date",
|
labelText: "Select ",
|
||||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
|
|||||||
@ -114,7 +114,7 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
|||||||
// Check validation for each field
|
// Check validation for each field
|
||||||
for (String field in requiredFields) {
|
for (String field in requiredFields) {
|
||||||
if (data[field] == null || data[field].toString().trim().isEmpty) {
|
if (data[field] == null || data[field].toString().trim().isEmpty) {
|
||||||
errorMessages[field] = "This field is required";
|
errorMessages[field] = "Required";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Special Type",
|
"Special Type *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -266,7 +266,7 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
|||||||
if (errorMessages["special_request"] != null) ...[
|
if (errorMessages["special_request"] != null) ...[
|
||||||
SizedBox(height: 5), // Space before error message
|
SizedBox(height: 5), // Space before error message
|
||||||
Text(
|
Text(
|
||||||
"Select Type",
|
"Required",
|
||||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -279,7 +279,7 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Comments",
|
"Comments *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
|||||||
@ -524,7 +524,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"City",
|
"City *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -562,7 +562,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Pickup Location",
|
"Pickup Location *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -600,7 +600,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Date",
|
"Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -648,7 +648,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Time",
|
"Time *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -700,7 +700,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Comments",
|
"Comments *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
|||||||
@ -369,7 +369,7 @@ class _TrainScreenState extends State<TrainScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Train Number",
|
"Train Number *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -584,7 +584,7 @@ class _TrainScreenState extends State<TrainScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"From",
|
"From *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -694,7 +694,7 @@ class _TrainScreenState extends State<TrainScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"To",
|
"To *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -767,7 +767,7 @@ class _TrainScreenState extends State<TrainScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Date",
|
"Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -816,7 +816,7 @@ class _TrainScreenState extends State<TrainScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Time",
|
"Time *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
|||||||
@ -438,68 +438,12 @@ class _VisaScreenState extends State<VisaScreen> {
|
|||||||
selectedPurpose ??=
|
selectedPurpose ??=
|
||||||
dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
|
dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
|
||||||
return [
|
return [
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
"Type of Visa",
|
|
||||||
style: GoogleFonts.poppins(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Color(0xFF575A74)),
|
|
||||||
),
|
|
||||||
SizedBox(height: 5),
|
|
||||||
CustomTextFieldWrapper(
|
|
||||||
isFocused: _tripTypeFocused,
|
|
||||||
isDesktop: isDesktop,
|
|
||||||
width: isDesktop
|
|
||||||
? MediaQuery.of(context).size.width * 0.34
|
|
||||||
: MediaQuery.of(context).size.width * 0.66,
|
|
||||||
child: SizedBox(
|
|
||||||
height: 40,
|
|
||||||
child: DropdownButtonFormField<String>(
|
|
||||||
focusNode: _tripTypeFocusNode, // Assign the correct focus node
|
|
||||||
value: selectedPurpose,
|
|
||||||
style: TextStyle(fontSize: 12),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
border: InputBorder.none,
|
|
||||||
contentPadding:
|
|
||||||
EdgeInsets.symmetric(horizontal: 10), // Proper padding
|
|
||||||
),
|
|
||||||
onChanged: purposeList.isNotEmpty
|
|
||||||
? (newValue) {
|
|
||||||
setState(() {
|
|
||||||
selectedPurpose = newValue;
|
|
||||||
});
|
|
||||||
print(
|
|
||||||
"Updating form data: Flight -> trip_type -> ${newValue ?? ""}");
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
|
|
||||||
items: dropdownItems,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (errorMessages["type_of_visa"] != null) ...[
|
|
||||||
SizedBox(height: 5), // Space before error message
|
|
||||||
Text(
|
|
||||||
"Required",
|
|
||||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (isDesktop)
|
|
||||||
Spacer()
|
|
||||||
else
|
|
||||||
SizedBox(
|
|
||||||
height: 8,
|
|
||||||
),
|
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Country",
|
"Country *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -509,7 +453,10 @@ class _VisaScreenState extends State<VisaScreen> {
|
|||||||
CustomTextFieldWrapper(
|
CustomTextFieldWrapper(
|
||||||
isFocused: _isHotelNameFocused,
|
isFocused: _isHotelNameFocused,
|
||||||
isDesktop: isDesktop,
|
isDesktop: isDesktop,
|
||||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.15 : null,
|
// width: isDesktop ? MediaQuery.of(context).size.width * 0.15 : null,
|
||||||
|
width: isDesktop
|
||||||
|
? MediaQuery.of(context).size.width * 0.34
|
||||||
|
: MediaQuery.of(context).size.width * 0.66,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: DropdownSearch<String>(
|
child: DropdownSearch<String>(
|
||||||
@ -518,7 +465,7 @@ class _VisaScreenState extends State<VisaScreen> {
|
|||||||
showSearchBox: true, // Enables search functionality
|
showSearchBox: true, // Enables search functionality
|
||||||
searchFieldProps: TextFieldProps(
|
searchFieldProps: TextFieldProps(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Search Country...",
|
hintText: "Search ...",
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -536,7 +483,7 @@ class _VisaScreenState extends State<VisaScreen> {
|
|||||||
// Center-align selected item
|
// Center-align selected item
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
child: Text(
|
||||||
selectedItem ?? "Select Country",
|
selectedItem ?? "Select ",
|
||||||
style: TextStyle(fontSize: 12),
|
style: TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -564,6 +511,7 @@ class _VisaScreenState extends State<VisaScreen> {
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
if (isDesktop)
|
if (isDesktop)
|
||||||
Spacer()
|
Spacer()
|
||||||
else
|
else
|
||||||
@ -574,7 +522,65 @@ class _VisaScreenState extends State<VisaScreen> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Start Date",
|
"Type of Visa",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Color(0xFF575A74)),
|
||||||
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
CustomTextFieldWrapper(
|
||||||
|
isFocused: _tripTypeFocused,
|
||||||
|
isDesktop: isDesktop,
|
||||||
|
width: isDesktop ? MediaQuery.of(context).size.width * 0.15 : null,
|
||||||
|
// width: isDesktop
|
||||||
|
// ? MediaQuery.of(context).size.width * 0.34
|
||||||
|
// : MediaQuery.of(context).size.width * 0.66,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: DropdownButtonFormField<String>(
|
||||||
|
focusNode: _tripTypeFocusNode, // Assign the correct focus node
|
||||||
|
value: selectedPurpose,
|
||||||
|
style: TextStyle(fontSize: 12),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding:
|
||||||
|
EdgeInsets.symmetric(horizontal: 10), // Proper padding
|
||||||
|
),
|
||||||
|
onChanged: purposeList.isNotEmpty
|
||||||
|
? (newValue) {
|
||||||
|
setState(() {
|
||||||
|
selectedPurpose = newValue;
|
||||||
|
});
|
||||||
|
print(
|
||||||
|
"Updating form data: Flight -> trip_type -> ${newValue ?? ""}");
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
|
||||||
|
items: dropdownItems,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (errorMessages["type_of_visa"] != null) ...[
|
||||||
|
SizedBox(height: 5), // Space before error message
|
||||||
|
Text(
|
||||||
|
"Required",
|
||||||
|
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (isDesktop)
|
||||||
|
Spacer()
|
||||||
|
else
|
||||||
|
SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Start Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
|||||||
@ -968,7 +968,7 @@ class _ListPlansState extends State<ListPlans> {
|
|||||||
height: 15,
|
height: 15,
|
||||||
),
|
),
|
||||||
tooltip:
|
tooltip:
|
||||||
'Edit Trip/Plans Details',
|
'Edit Trip Details',
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(
|
Navigator.pop(
|
||||||
context,
|
context,
|
||||||
@ -1222,7 +1222,7 @@ class _ListPlansState extends State<ListPlans> {
|
|||||||
height: 15,
|
height: 15,
|
||||||
),
|
),
|
||||||
tooltip:
|
tooltip:
|
||||||
'Edit Trip/plan Details',
|
'Edit Trip Details',
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(
|
Navigator.pop(
|
||||||
context,
|
context,
|
||||||
|
|||||||
@ -322,7 +322,8 @@ class _PolicyListState extends State<PolicyList> {
|
|||||||
controller: searchController,
|
controller: searchController,
|
||||||
onChanged: filterPolicy,
|
onChanged: filterPolicy,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Search for a Policy",
|
hintText: "Search ...",
|
||||||
|
|
||||||
hintStyle: TextStyle(
|
hintStyle: TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: Color(0xFF9E9DBD),
|
color: Color(0xFF9E9DBD),
|
||||||
@ -383,7 +384,7 @@ class _PolicyListState extends State<PolicyList> {
|
|||||||
MainAxisSize.min, // Ensures content fits nicely
|
MainAxisSize.min, // Ensures content fits nicely
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Add New Policy",
|
"Add Policy",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: isDesktop ? 13 : 11,
|
fontSize: isDesktop ? 13 : 11,
|
||||||
),
|
),
|
||||||
@ -413,7 +414,7 @@ class _PolicyListState extends State<PolicyList> {
|
|||||||
controller: searchController,
|
controller: searchController,
|
||||||
onChanged: filterPolicy,
|
onChanged: filterPolicy,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Search for a Policy",
|
hintText: "Search ...",
|
||||||
hintStyle: TextStyle(
|
hintStyle: TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: Color(0xFF9E9DBD),
|
color: Color(0xFF9E9DBD),
|
||||||
|
|||||||
@ -580,7 +580,8 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
// travelDetailsData = [travellerDetailsKey.currentState?.travel_Detials];
|
// travelDetailsData = [travellerDetailsKey.currentState?.travel_Detials];
|
||||||
|
|
||||||
travelDetailsData = travellerDetailsKey.currentState?.travel_Detials;
|
travelDetailsData = travellerDetailsKey.currentState?.travel_Detials;
|
||||||
errorMessagesTravel = travellerDetailsKey.currentState!.errorMessages;
|
// errorMessagesTravel = travellerDetailsKey.currentState!.errorMessages;
|
||||||
|
|
||||||
|
|
||||||
print("TRAVEL DETAILS FROM CHILD: $travelDetailsData");
|
print("TRAVEL DETAILS FROM CHILD: $travelDetailsData");
|
||||||
|
|
||||||
@ -654,10 +655,24 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
void handleSubmit() async {
|
void handleSubmit() async {
|
||||||
print("USR Detail Submit");
|
print("USR Detail Submit");
|
||||||
// printFormData();
|
// printFormData();
|
||||||
travelDetailsData = travellerDetailsKey.currentState?.travel_Detials;
|
|
||||||
|
bool isValid = travellerDetailsKey.currentState?.boolValidation() ?? false;
|
||||||
|
|
||||||
|
print("isValid- $isValid");
|
||||||
|
if (!isValid) {
|
||||||
|
print("Validation failed. Please check the inputs.");
|
||||||
|
setState(() {});
|
||||||
|
return; // ❌ STOP execution here if not valid
|
||||||
|
}
|
||||||
|
|
||||||
|
travelDetailsData = travellerDetailsKey.currentState?.travel_Detials;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print("travelDetailsData - $travelDetailsData");
|
print("travelDetailsData - $travelDetailsData");
|
||||||
errorMessagesTravel = travellerDetailsKey.currentState!.errorMessages;
|
|
||||||
|
print("travelDetailsData - $travelDetailsData");
|
||||||
|
// errorMessagesTravel = travellerDetailsKey.currentState!.errorMessages;
|
||||||
|
|
||||||
print("TRAVEL DETAILS FROM CHILD");
|
print("TRAVEL DETAILS FROM CHILD");
|
||||||
// print("TRAVEL DETAILS FROM CHILD: $travelDetailsData");
|
// print("TRAVEL DETAILS FROM CHILD: $travelDetailsData");
|
||||||
@ -673,8 +688,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
// Map<String, dynamic> data = userDetials;
|
// Map<String, dynamic> data = userDetials;
|
||||||
|
|
||||||
if (!isValidData(data) &&
|
if (!isValidData(data) &&
|
||||||
isValidDataTwo(data) &&
|
isValidDataTwo(data) ) {
|
||||||
errorMessagesTravel.isNotEmpty) {
|
|
||||||
print("USERDETAILS : $userDetials");
|
print("USERDETAILS : $userDetials");
|
||||||
print("Validation Failed: Required fields are missing.");
|
print("Validation Failed: Required fields are missing.");
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@ -683,7 +697,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
print("USERDETAILS : $userDetials");
|
print("USERDETAILS : $userDetials");
|
||||||
orgId = await getOrgId();
|
orgId = await getOrgId();
|
||||||
|
|
||||||
// createUserData(userDetials);
|
createUserData(userDetials);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -391,7 +391,7 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
|||||||
buildDelegationStartDateField(isDesktop),
|
buildDelegationStartDateField(isDesktop),
|
||||||
Spacer(), // Space after Last Name
|
Spacer(), // Space after Last Name
|
||||||
buildDelegationEndDateField(isDesktop),
|
buildDelegationEndDateField(isDesktop),
|
||||||
SizedBox(width: 15),
|
SizedBox(width: 16),
|
||||||
buildReset(isDesktop),
|
buildReset(isDesktop),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -1475,7 +1475,7 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldUserWrapper(
|
CustomTextFieldUserWrapper(
|
||||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.18 : null,
|
width: isDesktop ? MediaQuery.of(context).size.width * 0.2 : null,
|
||||||
isFocused: false,
|
isFocused: false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
|
|||||||
@ -639,7 +639,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
children: [
|
children: [
|
||||||
if (!widget.apiselectedUser) ...[
|
if (!widget.apiselectedUser) ...[
|
||||||
buildPassword(),
|
buildPassword(),
|
||||||
SizedBox(width: 15),
|
SizedBox(width: MediaQuery.of(context).size.width*0.015),
|
||||||
buildRole(),
|
buildRole(),
|
||||||
] else ...[
|
] else ...[
|
||||||
// TextButton(
|
// TextButton(
|
||||||
@ -736,9 +736,11 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
buildAddress(),
|
buildAddress(),
|
||||||
SizedBox(width: 15),
|
Spacer(),
|
||||||
|
// SizedBox(width: 15),
|
||||||
buildCountryField(),
|
buildCountryField(),
|
||||||
SizedBox(width: 15),
|
Spacer(),
|
||||||
|
// SizedBox(width: 15),
|
||||||
buildPostalCodeField(),
|
buildPostalCodeField(),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@ -154,6 +154,31 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool boolValidation() {
|
||||||
|
final passportText = controllers["passportNumber"]?.text ?? "";
|
||||||
|
|
||||||
|
if (_selectedTripType == "Indian") {
|
||||||
|
// Match exactly 8 alphanumeric characters
|
||||||
|
final isValid = RegExp(r'^[a-zA-Z0-9]{8}$').hasMatch(passportText);
|
||||||
|
|
||||||
|
if (!isValid) {
|
||||||
|
setState(() {
|
||||||
|
errorMessages["passport_number"] =
|
||||||
|
"Enter 8 characters";
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
errorMessages.remove("passport_number");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Future<void> apiCheckDuplicate(
|
Future<void> apiCheckDuplicate(
|
||||||
String label,
|
String label,
|
||||||
String field,
|
String field,
|
||||||
@ -708,7 +733,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
|
|
||||||
Future<void> loadCountryList() async {
|
Future<void> loadCountryList() async {
|
||||||
final newTripType = "2";
|
final newTripType = "2";
|
||||||
final result = await apiService.fetchFlightsCountryList(newTripType);
|
final result = await apiService.fetchAirlineList();
|
||||||
|
// final result = await apiService.fetchFlightsCountryList(newTripType);
|
||||||
|
|
||||||
print("resultFlight: $result ");
|
print("resultFlight: $result ");
|
||||||
|
|
||||||
@ -1212,6 +1238,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
: (String? newValue) {
|
: (String? newValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_selectedTripType = newValue;
|
_selectedTripType = newValue;
|
||||||
|
controllers["passportNumber"]?.clear();
|
||||||
print("_selectedTripType - $_selectedTripType");
|
print("_selectedTripType - $_selectedTripType");
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -1254,20 +1281,6 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
],
|
],
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_clearError("passport_number");
|
_clearError("passport_number");
|
||||||
final regex = RegExp(r'^[a-zA-Z0-9]{0,8}$');
|
|
||||||
if (!regex.hasMatch(value)) {
|
|
||||||
setState(() {
|
|
||||||
if (_selectedTripType == "Indian") {
|
|
||||||
errorMessages["passport_number"] =
|
|
||||||
"Only 8 characters allowed (letters & numbers)";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
setState(() {
|
|
||||||
errorMessages.remove("passport_number");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
apiCheckDuplicate(
|
apiCheckDuplicate(
|
||||||
"Passport Number",
|
"Passport Number",
|
||||||
"passport_number",
|
"passport_number",
|
||||||
@ -1438,23 +1451,42 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
DateTime today = DateTime(now.year, now.month, now.day);
|
DateTime today = DateTime(now.year, now.month, now.day);
|
||||||
// DateTime today = DateTime(now.year now.day, now.month,);
|
// DateTime today = DateTime(now.year now.day, now.month,);
|
||||||
|
|
||||||
// Parse dateOfIssue safely
|
DateTime? validFromDate;
|
||||||
DateTime firstDate;
|
|
||||||
try {
|
try {
|
||||||
firstDate = DateFormat(
|
String? fromDateText = controllers["dateOfIssue"]?.text.trim();
|
||||||
"yyyy-MM-dd",
|
print("dateOfIssue From Text: $fromDateText");
|
||||||
).parse(controllers["dateOfIssue"]!.text);
|
if (fromDateText!.isNotEmpty) {
|
||||||
|
validFromDate = DateFormat('dd-MM-yyyy').parseStrict(fromDateText);
|
||||||
|
print("dateOfIssue Valid From: $validFromDate");
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
firstDate = today; // fallback if parsing fails
|
print("Error parsing valid from date: $e");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use max(today, validFromDate) as firstDate
|
||||||
|
// DateTime firstDate = today;
|
||||||
|
DateTime firstDate = validFromDate ?? today;
|
||||||
|
|
||||||
|
// Parse dateOfIssue safely
|
||||||
|
// DateTime firstDate;
|
||||||
|
// try {
|
||||||
|
// firstDate = DateFormat(
|
||||||
|
// "yyyy-MM-dd",
|
||||||
|
// ).parse(controllers["dateOfIssue"]!.text);
|
||||||
|
// } catch (e) {
|
||||||
|
// firstDate = today; // fallback if parsing fails
|
||||||
|
// }
|
||||||
|
|
||||||
DateTime? pickedDate = await showDatePicker(
|
DateTime? pickedDate = await showDatePicker(
|
||||||
context: context,
|
context: context,
|
||||||
initialDate:
|
// initialDate:
|
||||||
_selectedDateOfExpiry != null &&
|
// _selectedDateOfExpiry != null &&
|
||||||
_selectedDateOfExpiry!.isAfter(firstDate)
|
// _selectedDateOfExpiry!.isAfter(firstDate)
|
||||||
? _selectedDateOfExpiry!
|
// ? _selectedDateOfExpiry!
|
||||||
: today,
|
// : today,
|
||||||
|
|
||||||
|
initialDate:firstDate,
|
||||||
firstDate: firstDate,
|
firstDate: firstDate,
|
||||||
// firstDate: DateTime(1900),
|
// firstDate: DateTime(1900),
|
||||||
lastDate: DateTime(2100),
|
lastDate: DateTime(2100),
|
||||||
@ -1857,6 +1889,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
dropdownDecoratorProps: const DropDownDecoratorProps(
|
dropdownDecoratorProps: const DropDownDecoratorProps(
|
||||||
dropdownSearchDecoration: InputDecoration(
|
dropdownSearchDecoration: InputDecoration(
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
|
hintText: "Select Seat",
|
||||||
contentPadding: EdgeInsets.symmetric(
|
contentPadding: EdgeInsets.symmetric(
|
||||||
horizontal: 10,
|
horizontal: 10,
|
||||||
vertical: 5,
|
vertical: 5,
|
||||||
@ -1877,7 +1910,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Text(
|
return Text(
|
||||||
selectedItem['dropdown_value'] ?? '',
|
selectedItem['dropdown_value'] ?? "Select Seat",
|
||||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -2027,7 +2060,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
vertical: 8,
|
vertical: 8,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
item['dropdown_value'] ?? '',
|
item['dropdown_value'] ?? "Select Seat",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
@ -2729,9 +2762,14 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
countryList = apiAirlineCountryData!;
|
countryList = apiAirlineCountryData!;
|
||||||
print("TestcountryList2 - $countryList");
|
print("TestcountryList2 - $countryList");
|
||||||
|
|
||||||
|
// countryMap = {
|
||||||
|
// for (var country in countryList)
|
||||||
|
// country['Code'] as String: '${country['City']} - ${country['Airport']}',
|
||||||
|
// };
|
||||||
|
|
||||||
countryMap = {
|
countryMap = {
|
||||||
for (var country in countryList)
|
for (var country in countryList)
|
||||||
country['Code'] as String: '${country['City']} - ${country['Airport']}',
|
country['airline'] as String: '${country['airline_name']}',
|
||||||
};
|
};
|
||||||
|
|
||||||
countryCodes = countryMap.keys.toList();
|
countryCodes = countryMap.keys.toList();
|
||||||
@ -2777,10 +2815,10 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldUserTravellerWrapper(
|
CustomTextFieldUserTravellerWrapper(
|
||||||
width:
|
// width:
|
||||||
widget.isDesktop
|
// widget.isDesktop
|
||||||
? MediaQuery.of(context).size.width * 0.17
|
// ? MediaQuery.of(context).size.width * 0.17
|
||||||
: null,
|
// : null,
|
||||||
isFocused: false,
|
isFocused: false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
@ -3825,21 +3863,45 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
Future<void> _selectValidUpToDate(BuildContext context) async {
|
Future<void> _selectValidUpToDate(BuildContext context) async {
|
||||||
DateTime now = DateTime.now();
|
DateTime now = DateTime.now();
|
||||||
DateTime today = DateTime(now.year, now.month, now.day);
|
DateTime today = DateTime(now.year, now.month, now.day);
|
||||||
|
print("buildVisaValidUpTo ");
|
||||||
|
print("buildVisaValidUpTo - ${entry["controller_valid_from"].text}");
|
||||||
|
|
||||||
|
|
||||||
// Parse date from notifier if available, else use today
|
// Parse date from notifier if available, else use today
|
||||||
DateTime initialDate = today;
|
DateTime initialDate = today;
|
||||||
|
|
||||||
// Use previously selected date if valid
|
// Use previously selected date if valid
|
||||||
if (_selectedCheckOutDate != null &&
|
// if (_selectedCheckOutDate != null &&
|
||||||
_selectedCheckOutDate!.isAfter(today)) {
|
// _selectedCheckOutDate!.isAfter(today)) {
|
||||||
initialDate = _selectedCheckOutDate!;
|
// initialDate = _selectedCheckOutDate!;
|
||||||
|
// }
|
||||||
|
|
||||||
|
DateTime? validFromDate;
|
||||||
|
|
||||||
|
try {
|
||||||
|
String fromDateText = entry["controller_valid_from"].text.trim();
|
||||||
|
print("Valid From Text: $fromDateText");
|
||||||
|
if (fromDateText.isNotEmpty) {
|
||||||
|
validFromDate = DateFormat('dd-MM-yyyy').parseStrict(fromDateText);
|
||||||
|
print("Parsed Valid From: $validFromDate");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print("Error parsing valid from date: $e");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use max(today, validFromDate) as firstDate
|
||||||
|
// DateTime firstDate = today;
|
||||||
|
DateTime firstDate = validFromDate ?? today;
|
||||||
|
if (validFromDate != null && validFromDate.isAfter(today)) {
|
||||||
|
firstDate = validFromDate;
|
||||||
|
}
|
||||||
final pickedDate = await showDatePicker(
|
final pickedDate = await showDatePicker(
|
||||||
context: context,
|
context: context,
|
||||||
// initialDate: initialDate,
|
// initialDate: initialDate,
|
||||||
// firstDate: initialDate,
|
// firstDate: initialDate,
|
||||||
firstDate: DateTime(1900),
|
// firstDate: DateTime(1900),
|
||||||
|
initialDate: firstDate,
|
||||||
|
firstDate: firstDate,
|
||||||
lastDate: DateTime(2100),
|
lastDate: DateTime(2100),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1137,15 +1137,54 @@ class _UserListScreenState extends State<UserListScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
|
// Expanded(
|
||||||
|
// child:
|
||||||
|
// isDesktop
|
||||||
|
// ? SingleChildScrollView(
|
||||||
|
// scrollDirection: Axis.vertical,
|
||||||
|
// child: table, // <-- your existing table
|
||||||
|
// )
|
||||||
|
// : buildMobileCardView(paginatedUser),
|
||||||
|
// ),
|
||||||
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child:
|
child:
|
||||||
isDesktop
|
isDesktop
|
||||||
? SingleChildScrollView(
|
? (searchController.text.isNotEmpty &&
|
||||||
scrollDirection: Axis.vertical,
|
filteredUsers.isEmpty
|
||||||
child: table, // <-- your existing table
|
? Center(
|
||||||
)
|
child: Text(
|
||||||
: buildMobileCardView(paginatedUser),
|
"No users found",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.vertical,
|
||||||
|
child: table,
|
||||||
|
))
|
||||||
|
: (searchController.text.isNotEmpty &&
|
||||||
|
filteredUsers.isEmpty
|
||||||
|
? Center(
|
||||||
|
child: Text(
|
||||||
|
"No users found",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: buildMobileCardView(paginatedUser)),
|
||||||
|
// child: isDesktop
|
||||||
|
// ? SingleChildScrollView(
|
||||||
|
// scrollDirection: Axis.vertical,
|
||||||
|
// child: table, // <-- your existing table
|
||||||
|
// )
|
||||||
|
// : buildMobileCardView(paginatedPlans),
|
||||||
),
|
),
|
||||||
|
|
||||||
PaginationControls(
|
PaginationControls(
|
||||||
currentPage: currentPage,
|
currentPage: currentPage,
|
||||||
itemsPerPage: itemsPerPage,
|
itemsPerPage: itemsPerPage,
|
||||||
|
|||||||
@ -102,6 +102,41 @@ class ApiService {
|
|||||||
throw Exception('Failed to load country list');
|
throw Exception('Failed to load country list');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Future<List<dynamic>> fetchAirlineList() async {
|
||||||
|
final String apiUrldata = '$apiUrl/api/getAirlineMaster';
|
||||||
|
final token = await getToken();
|
||||||
|
|
||||||
|
if (token == null) {
|
||||||
|
throw Exception('Token not found. Please log in.');
|
||||||
|
}
|
||||||
|
|
||||||
|
final response = await http.get(
|
||||||
|
Uri.parse(apiUrldata),
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Bearer $token',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
try {
|
||||||
|
final data = json.decode(response.body);
|
||||||
|
print("Airline - $data");
|
||||||
|
|
||||||
|
if (!data.containsKey('data') || data['data'] is! List) {
|
||||||
|
throw Exception(
|
||||||
|
"Invalid response format: 'data' field is missing or not a List",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data['data'];
|
||||||
|
} catch (e) {
|
||||||
|
throw Exception('Error parsing response: $e');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw Exception('Failed to load country list');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<dynamic>> fetchUsers() async {
|
Future<List<dynamic>> fetchUsers() async {
|
||||||
String? ordId = await getOrgId();
|
String? ordId = await getOrgId();
|
||||||
|
|||||||
@ -42,7 +42,7 @@ class UserActionsMenu extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
child: Tooltip(
|
child: Tooltip(
|
||||||
message: 'View User Details',
|
message: 'View Details',
|
||||||
child: Icon(Icons.remove_red_eye,
|
child: Icon(Icons.remove_red_eye,
|
||||||
color: Color(0xFF475569), size: 18)
|
color: Color(0xFF475569), size: 18)
|
||||||
),
|
),
|
||||||
@ -61,7 +61,7 @@ class UserActionsMenu extends StatelessWidget {
|
|||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
child: Tooltip(
|
child: Tooltip(
|
||||||
message: 'Edit User Details',
|
message: 'Edit Details',
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
'assets/images/IconsImg/edit.png',
|
'assets/images/IconsImg/edit.png',
|
||||||
width: 20,
|
width: 20,
|
||||||
|
|||||||
20
pubspec.lock
20
pubspec.lock
@ -21,10 +21,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.13.0"
|
version: "2.12.0"
|
||||||
bcrypt:
|
bcrypt:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -149,10 +149,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.3"
|
version: "1.3.2"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -465,18 +465,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
|
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.20.2"
|
version: "0.19.0"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
|
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.9"
|
version: "10.0.8"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1014,10 +1014,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
|
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "15.0.0"
|
version: "14.3.1"
|
||||||
vsc_quill_delta_to_html:
|
vsc_quill_delta_to_html:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
# sdk: ^3.6.1
|
# sdk: ^3.6.1
|
||||||
sdk: ^3.7.2
|
sdk: ^3.7.2
|
||||||
# Dependencies specify other packages that your package needs in order to work.
|
# Dependencies specify other packages that your package needs in order to work.
|
||||||
# To automatically upgrade your package dependencies to the latest versions
|
# To automatically upgrade your package dependencies to the latest versions
|
||||||
@ -44,7 +44,7 @@ dependencies:
|
|||||||
responsive_builder: ^0.7.1
|
responsive_builder: ^0.7.1
|
||||||
shared_preferences: ^2.5.2
|
shared_preferences: ^2.5.2
|
||||||
easy_stepper: ^0.8.5+1
|
easy_stepper: ^0.8.5+1
|
||||||
intl: ^0.20.2
|
intl: ^0.19.0
|
||||||
dropdown_search: ^5.0.6
|
dropdown_search: ^5.0.6
|
||||||
file_picker: ^10.0.0
|
file_picker: ^10.0.0
|
||||||
bcrypt: ^1.1.3
|
bcrypt: ^1.1.3
|
||||||
@ -134,4 +134,4 @@ flutter:
|
|||||||
# weight: 700
|
# weight: 700
|
||||||
#
|
#
|
||||||
# For details regarding fonts from package dependencies,
|
# For details regarding fonts from package dependencies,
|
||||||
# see https://flutter.dev/to/font-from-package
|
# see https://flutter.dev/to/font-from-packagej
|
||||||
Loading…
Reference in New Issue
Block a user