From bf1cd002e151356b864d676c90a796de9061349c Mon Sep 17 00:00:00 2001 From: SurendarSuri30 Date: Sat, 7 Jun 2025 18:14:05 +0530 Subject: [PATCH] round trip validation --- lib/Screens/itnerary/flights.dart | 273 +++++++++++++++--- lib/Screens/itnerary/visa.dart | 56 ---- .../create_user/create_user.dart | 6 +- 3 files changed, 230 insertions(+), 105 deletions(-) diff --git a/lib/Screens/itnerary/flights.dart b/lib/Screens/itnerary/flights.dart index 111a598..2fe0357 100644 --- a/lib/Screens/itnerary/flights.dart +++ b/lib/Screens/itnerary/flights.dart @@ -55,6 +55,8 @@ class FlightScreenState extends State { Map selectedValues = {}; + int rowCount = 1; + String? selectedTripType; Map selectedClasses = {}; // Store class selection for each trip Map selectedFrom = {}; // Store class selection for each trip @@ -251,9 +253,14 @@ class FlightScreenState extends State { Map tempCountryMap = {}; for (var country in result) { - String city = country['City'] ?? ''; - String airport = country['Airport'] ?? ''; - String displayName = '${country['City']} - ${country['Airport']}'; + // String city = country['City'] ?? ''; + // String airport = 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; } @@ -563,7 +570,7 @@ class FlightScreenState extends State { bool validateFields() { errorMessages.clear(); // Reset errors - int rowCount = 1; // Default row count for One-way + rowCount = 1; // Default row count for One-way if (selectedTripType == "Roundtrip") { rowCount = 2; // Fixed for Roundtrip } else if (selectedTripType == "Multitrip") { @@ -579,9 +586,31 @@ class FlightScreenState extends State { if (selectedFrom[i] == null) { 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) { 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) { // errorMessages["to_place_$i"] = "Required"; // } @@ -591,8 +620,13 @@ class FlightScreenState extends State { if (textControllers["_time${i}Controller"]?.text.trim().isEmpty ?? true) { errorMessages["time_$i"] = "Required"; } + + } + + + setState(() {}); // Update UI to show error messages return errorMessages @@ -882,6 +916,15 @@ class FlightScreenState extends State { multiTripRowCount = 1; } 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( "Updating form data: Flight -> trip_type -> $selectedTripType", @@ -1254,6 +1297,7 @@ class FlightScreenState extends State { isCountryLoading ? Center(child: CircularProgressIndicator()) : DropdownSearch( + enabled: !(selectedTripType == "Roundtrip" && index == 2), selectedItem: selectedFrom[index] != null ? countryMap[selectedFrom[index]] @@ -1273,19 +1317,61 @@ class FlightScreenState extends State { style: TextStyle(fontSize: 12), ), menuProps: MenuProps(backgroundColor: Colors.white), - 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 - ), + itemBuilder: (context, item, isSelected) { + final parts = item.split('\n'); + final cityAndCode = parts[0]; + final airport = parts.length > 1 ? parts[1] : ''; + + // Extract city and code from "City (CODE)" + final cityMatch = RegExp(r'^(.*)\s+\(([^)]+)\)$').firstMatch(cityAndCode); + final city = cityMatch?.group(1) ?? ''; + final code = cityMatch?.group(2) ?? ''; + + 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(), dropdownDecoratorProps: DropDownDecoratorProps( @@ -1294,14 +1380,33 @@ class FlightScreenState extends State { contentPadding: EdgeInsets.symmetric(horizontal: 1), ), ), - dropdownBuilder: - (context, selectedItem) => Align( + 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( - selectedItem ?? "Select", - style: TextStyle(fontSize: 12), - ), - ), + child: Text( + cityAndCode ?? "Select", + style: const TextStyle(fontSize: 12), + ), + ); + }, + + // dropdownBuilder: + // (context, selectedItem) => Align( + // alignment: Alignment.centerLeft, + // child: Text( + // selectedItem ?? "Select", + // style: TextStyle(fontSize: 12), + // ), + // ), onChanged: (String? newValue) { setState(() { // selectedFrom[index] = countryMap.entries @@ -1315,7 +1420,13 @@ class FlightScreenState extends State { ) .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 { isCountryLoading ? Center(child: CircularProgressIndicator()) : DropdownSearch( + enabled: !(selectedTripType == "Roundtrip" && index == 2), selectedItem: selectedTo[index] != null ? countryMap[selectedTo[index]] @@ -1385,19 +1497,61 @@ class FlightScreenState extends State { style: TextStyle(fontSize: 12), ), menuProps: MenuProps(backgroundColor: Colors.white), - 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 - ), + itemBuilder: (context, item, isSelected) { + final parts = item.split('\n'); + final cityAndCode = parts[0]; + final airport = parts.length > 1 ? parts[1] : ''; + + + // Extract city and code from "City (CODE)" + final cityMatch = RegExp(r'^(.*)\s+\(([^)]+)\)$').firstMatch(cityAndCode); + final city = cityMatch?.group(1) ?? ''; + final code = cityMatch?.group(2) ?? ''; + + 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(), dropdownDecoratorProps: DropDownDecoratorProps( @@ -1406,16 +1560,36 @@ class FlightScreenState extends State { contentPadding: EdgeInsets.symmetric(horizontal: 1), ), ), - dropdownBuilder: - (context, selectedItem) => Align( - alignment: Alignment.centerLeft, - child: Text( - selectedItem ?? "Select Country", - style: TextStyle(fontSize: 12), - ), - ), - onChanged: (String? newValue) { + // dropdownBuilder: + // (context, selectedItem) => Align( + // alignment: Alignment.centerLeft, + // child: Text( + // selectedItem ?? "Select Country", + // style: TextStyle(fontSize: 12), + // ), + // ), + + 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(() { + errorMessages.remove("to_place_$index"); selectedTo[index] = countryMap.entries .firstWhere( @@ -1424,6 +1598,13 @@ class FlightScreenState extends State { .key; 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 { ), if (errorMessages["to_place_$index"] != null) ...[ 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)), ], ], ), diff --git a/lib/Screens/itnerary/visa.dart b/lib/Screens/itnerary/visa.dart index 68d3815..a507456 100644 --- a/lib/Screens/itnerary/visa.dart +++ b/lib/Screens/itnerary/visa.dart @@ -438,63 +438,7 @@ class _VisaScreenState extends State { selectedPurpose ??= dropdownItems.isNotEmpty ? dropdownItems.first.value : null; 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( - 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: [ diff --git a/lib/Screens/userManagement/create_user/create_user.dart b/lib/Screens/userManagement/create_user/create_user.dart index 0c55db6..8a1b59f 100644 --- a/lib/Screens/userManagement/create_user/create_user.dart +++ b/lib/Screens/userManagement/create_user/create_user.dart @@ -580,7 +580,7 @@ class _CreateUserFormDetialsState extends State { // travelDetailsData = [travellerDetailsKey.currentState?.travel_Detials]; travelDetailsData = travellerDetailsKey.currentState?.travel_Detials; - errorMessagesTravel = travellerDetailsKey.currentState!.errorMessages; + // errorMessagesTravel = travellerDetailsKey.currentState!.errorMessages; print("TRAVEL DETAILS FROM CHILD: $travelDetailsData"); @@ -672,7 +672,7 @@ class _CreateUserFormDetialsState extends State { print("travelDetailsData - $travelDetailsData"); print("travelDetailsData - $travelDetailsData"); - errorMessagesTravel = travellerDetailsKey.currentState!.errorMessages; + // errorMessagesTravel = travellerDetailsKey.currentState!.errorMessages; print("TRAVEL DETAILS FROM CHILD"); // print("TRAVEL DETAILS FROM CHILD: $travelDetailsData"); @@ -697,7 +697,7 @@ class _CreateUserFormDetialsState extends State { print("USERDETAILS : $userDetials"); orgId = await getOrgId(); - // createUserData(userDetials); + createUserData(userDetials); } }