From a8712dcb68b5278d11c3240431da1b411a90ec9c Mon Sep 17 00:00:00 2001 From: venbaittech Date: Mon, 9 Jun 2025 15:01:30 +0530 Subject: [PATCH] merge --- lib/Screens/itnerary/accomodations.dart | 2 +- lib/Screens/itnerary/bus.dart | 299 +++++++++--------- lib/Screens/itnerary/forex.dart | 3 +- lib/Screens/itnerary/miscellaneous.dart | 157 ++++----- lib/Screens/itnerary/taxi.dart | 150 +++++---- lib/Screens/itnerary/train.dart | 2 +- lib/Screens/itnerary/visa.dart | 275 ++++++++-------- lib/Screens/plans/create_plans.dart | 36 ++- .../plans/dynamic_itinerary_stepper.dart | 6 + 9 files changed, 484 insertions(+), 446 deletions(-) diff --git a/lib/Screens/itnerary/accomodations.dart b/lib/Screens/itnerary/accomodations.dart index 1ec7cea..0149c0a 100644 --- a/lib/Screens/itnerary/accomodations.dart +++ b/lib/Screens/itnerary/accomodations.dart @@ -387,7 +387,7 @@ class _AccomodationScreenState extends State { child: Column( children: [ Padding( - padding: const EdgeInsets.all(28.0), + padding: const EdgeInsets.only(top: 30.0), child: Center( child: Column(children: _buildAccomadtionForm(isDesktop)), ), diff --git a/lib/Screens/itnerary/bus.dart b/lib/Screens/itnerary/bus.dart index 8923afa..d0f30e7 100644 --- a/lib/Screens/itnerary/bus.dart +++ b/lib/Screens/itnerary/bus.dart @@ -13,12 +13,13 @@ class BusScreen extends StatefulWidget { final Map? selectedItem; final String? loginUser; - BusScreen( - {required this.onClose, - this.apiData, - required this.onSaveBus, - required this.selectedItem, - required this.loginUser}); + BusScreen({ + required this.onClose, + this.apiData, + required this.onSaveBus, + required this.selectedItem, + required this.loginUser, + }); @override _BusScreenState createState() => _BusScreenState(); @@ -195,51 +196,54 @@ class _BusScreenState extends State { @override Widget build(BuildContext context) { - return ResponsiveBuilder(builder: (context, sizingInfo) { - bool isMobile = sizingInfo.isMobile; - bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop; + return ResponsiveBuilder( + builder: (context, sizingInfo) { + bool isMobile = sizingInfo.isMobile; + bool isDesktop = + sizingInfo.deviceScreenType == DeviceScreenType.desktop; - return Container( - // color: Colors.white, - child: Form( - key: _formKey, - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - children: [ - // Align( - // alignment: Alignment.centerRight, - // child: InkWell( - // onTap: () { - // widget.onClose(false); - // }, - // child: Icon( - // Icons.close, - // size: 18, - // color: Color(0xFF575A74), - // ), - // ), - // ), - // Text("Bus Booking List", - // style: TextStyle( - // fontSize: 18, - // fontWeight: FontWeight.bold, - // color: Color(0xFF575A74))), - // SizedBox( - // height: 6, - // ), - Padding( - padding: const EdgeInsets.all(28.0), - child: Center( - child: Column(children: _buildAccomadtionForm(isDesktop)), + return Container( + // color: Colors.white, + child: Form( + key: _formKey, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + // Align( + // alignment: Alignment.centerRight, + // child: InkWell( + // onTap: () { + // widget.onClose(false); + // }, + // child: Icon( + // Icons.close, + // size: 18, + // color: Color(0xFF575A74), + // ), + // ), + // ), + // Text("Bus Booking List", + // style: TextStyle( + // fontSize: 18, + // fontWeight: FontWeight.bold, + // color: Color(0xFF575A74))), + // SizedBox( + // height: 6, + // ), + Padding( + padding: const EdgeInsets.only(top: 30.0), + child: Center( + child: Column(children: _buildAccomadtionForm(isDesktop)), + ), ), - ) - ], + ], + ), ), ), - ), - ); - }); + ); + }, + ); } List _buildAccomadtionForm(bool isDesktop) { @@ -252,7 +256,7 @@ class _BusScreenState extends State { List> rowBuilders = [ // _builClassType(isDesktop), - _buildSecondRow(isDesktop) + _buildSecondRow(isDesktop), ]; return [ @@ -275,41 +279,42 @@ class _BusScreenState extends State { Text( "Trip Type", style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Color(0xFF575A74)), + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xFF575A74), + ), ), SizedBox(height: 5), isDesktop ? Row(children: _buildTripType(isDesktop)) - : Column(children: _buildTripType(isDesktop)) + : Column(children: _buildTripType(isDesktop)), ], ), - if (isDesktop) - Spacer() - else - SizedBox( - height: 8, - ), + if (isDesktop) Spacer() else SizedBox(height: 8), ]; } List _buildTripType(bool isDesktop) { List purposeList = widget.apiData?['flight_trip_type'] ?? []; - List> dropdownItems = purposeList - .map((item) => DropdownMenuItem( - value: item['dropdown_key'], - child: Text(item['dropdown_value']), - )) - .toList(); + List> dropdownItems = + purposeList + .map( + (item) => DropdownMenuItem( + value: item['dropdown_key'], + child: Text(item['dropdown_value']), + ), + ) + .toList(); if (dropdownItems.isEmpty) { dropdownItems.add( DropdownMenuItem( value: null, - child: Text("No options available", - style: TextStyle(color: Colors.grey)), + child: Text( + "No options available", + style: TextStyle(color: Colors.grey), + ), ), ); } @@ -331,18 +336,21 @@ class _BusScreenState extends State { style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), decoration: InputDecoration( border: InputBorder.none, - contentPadding: - EdgeInsets.symmetric(horizontal: 10), // Proper padding + contentPadding: EdgeInsets.symmetric( + horizontal: 10, + ), // Proper padding ), - onChanged: purposeList.isNotEmpty - ? (newValue) { - setState(() { - selectedPurpose = newValue; - }); - print( - "Updating form data: Flight -> trip_type -> ${newValue ?? ""}"); - } - : null, + onChanged: + purposeList.isNotEmpty + ? (newValue) { + setState(() { + selectedPurpose = newValue; + }); + print( + "Updating form data: Flight -> trip_type -> ${newValue ?? ""}", + ); + } + : null, items: dropdownItems, ), @@ -361,10 +369,11 @@ class _BusScreenState extends State { DateTime? pickedDate = await showDatePicker( context: context, - initialDate: _selectedCheckOutDate != null && - _selectedCheckOutDate!.isAfter(today) - ? _selectedCheckOutDate! - : today, + initialDate: + _selectedCheckOutDate != null && + _selectedCheckOutDate!.isAfter(today) + ? _selectedCheckOutDate! + : today, firstDate: today, lastDate: DateTime(2100), ); @@ -399,11 +408,10 @@ class _BusScreenState extends State { pickedTime.minute, ); - final isToday = selectedDate.year == now.year && - selectedDate.month == now.month && - selectedDate.day == now.day; + selectedDate.month == now.month && + selectedDate.day == now.day; bool isPastTime = selectedDateTime.isBefore(now); @@ -411,19 +419,26 @@ class _BusScreenState extends State { setState(() { errorMessages["time"] = "You can't select a past time."; _selectedCheckOutTime = null; // ✅ Reset time variable - _timeController.text = ""; // ✅ Clear text field + _timeController.text = ""; // ✅ Clear text field }); return; - }else{ setState(() { - _selectedCheckOutTime = pickedTime; - // Formatting time to HH:mm (24-hour format) - final now = DateTime.now(); - final formattedTime = DateFormat('HH:mm').format( - DateTime(now.year, now.month, now.day, pickedTime.hour, - pickedTime.minute), - ); - _timeController.text = formattedTime; - }); } + } else { + setState(() { + _selectedCheckOutTime = pickedTime; + // Formatting time to HH:mm (24-hour format) + final now = DateTime.now(); + final formattedTime = DateFormat('HH:mm').format( + DateTime( + now.year, + now.month, + now.day, + pickedTime.hour, + pickedTime.minute, + ), + ); + _timeController.text = formattedTime; + }); + } } } @@ -434,9 +449,10 @@ class _BusScreenState extends State { Text( "From *", style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Color(0xFF575A74)), + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xFF575A74), + ), ), SizedBox(height: 5), CustomTextFieldItnerarySubWrapper( @@ -460,28 +476,21 @@ class _BusScreenState extends State { ), if (errorMessages["from"] != null) ...[ SizedBox(height: 5), // Space before error message - Text( - "Required", - style: TextStyle(color: Colors.red, fontSize: 12), - ), + Text("Required", style: TextStyle(color: Colors.red, fontSize: 12)), ], ], ), - if (isDesktop) - Spacer() - else - SizedBox( - height: 8, - ), + if (isDesktop) Spacer() else SizedBox(height: 8), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "To *", style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Color(0xFF575A74)), + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xFF575A74), + ), ), SizedBox(height: 5), CustomTextFieldItnerarySubWrapper( @@ -505,28 +514,21 @@ class _BusScreenState extends State { ), if (errorMessages["to"] != null) ...[ SizedBox(height: 5), // Space before error message - Text( - "Required", - style: TextStyle(color: Colors.red, fontSize: 12), - ), + Text("Required", style: TextStyle(color: Colors.red, fontSize: 12)), ], ], ), - if (isDesktop) - Spacer() - else - SizedBox( - height: 8, - ), + if (isDesktop) Spacer() else SizedBox(height: 8), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Date *", style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Color(0xFF575A74)), + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xFF575A74), + ), ), SizedBox(height: 5), CustomTextFieldItnerarySubWrapper( @@ -547,8 +549,11 @@ class _BusScreenState extends State { floatingLabelBehavior: FloatingLabelBehavior.never, border: InputBorder.none, contentPadding: EdgeInsets.symmetric(vertical: 16), - suffixIcon: Icon(Icons.calendar_today, - size: 16, color: Colors.grey), + suffixIcon: Icon( + Icons.calendar_today, + size: 16, + color: Colors.grey, + ), ), ), ), @@ -557,28 +562,21 @@ class _BusScreenState extends State { ), if (errorMessages["date"] != null) ...[ SizedBox(height: 5), // Space before error message - Text( - "Required", - style: TextStyle(color: Colors.red, fontSize: 12), - ), + Text("Required", style: TextStyle(color: Colors.red, fontSize: 12)), ], ], ), - if (isDesktop) - Spacer() - else - SizedBox( - height: 8, - ), + if (isDesktop) Spacer() else SizedBox(height: 8), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Time *", style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Color(0xFF575A74)), + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xFF575A74), + ), ), SizedBox(height: 5), CustomTextFieldItnerarySubWrapper( @@ -599,8 +597,11 @@ class _BusScreenState extends State { floatingLabelBehavior: FloatingLabelBehavior.never, border: InputBorder.none, contentPadding: EdgeInsets.symmetric(vertical: 16), - suffixIcon: - Icon(Icons.access_time, size: 16, color: Colors.grey), + suffixIcon: Icon( + Icons.access_time, + size: 16, + color: Colors.grey, + ), ), ), ), @@ -627,9 +628,10 @@ class _BusScreenState extends State { Text( "Comments", style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Color(0xFF575A74)), + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xFF575A74), + ), ), SizedBox(height: 5), CustomTextFieldWrapper( @@ -675,9 +677,7 @@ class _BusScreenState extends State { }, style: ElevatedButton.styleFrom( backgroundColor: Colors.grey[400], // Light grey color - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), ), child: Text( @@ -686,7 +686,6 @@ class _BusScreenState extends State { ), ), SizedBox(width: 10), // Space between buttons - // Save Changes Button ElevatedButton( onPressed: () { @@ -694,9 +693,7 @@ class _BusScreenState extends State { }, style: ElevatedButton.styleFrom( backgroundColor: Color(0xFF114D8B), // Primary color for save - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), ), child: Text( diff --git a/lib/Screens/itnerary/forex.dart b/lib/Screens/itnerary/forex.dart index 7acd3e7..5c2c070 100644 --- a/lib/Screens/itnerary/forex.dart +++ b/lib/Screens/itnerary/forex.dart @@ -1203,7 +1203,8 @@ class _ForexScreenState extends State { // height: 8, // ), if (isDesktop) - SizedBox(width: MediaQuery.of(context).size.width * 0.048) + Spacer() + // SizedBox(width: MediaQuery.of(context).size.width * 0.048) else SizedBox(height: 8), Column( diff --git a/lib/Screens/itnerary/miscellaneous.dart b/lib/Screens/itnerary/miscellaneous.dart index 93029f3..3088666 100644 --- a/lib/Screens/itnerary/miscellaneous.dart +++ b/lib/Screens/itnerary/miscellaneous.dart @@ -14,13 +14,14 @@ class MiscellaneousScreen extends StatefulWidget { final int? selectedIndex; final String? loginUser; - MiscellaneousScreen( - {required this.onClose, - required this.apiData, - required this.onSaveMiscellaneous, - this.selectedItem, - this.selectedIndex, - required this.loginUser}); + MiscellaneousScreen({ + required this.onClose, + required this.apiData, + required this.onSaveMiscellaneous, + this.selectedItem, + this.selectedIndex, + required this.loginUser, + }); @override _MiscellaneousScreenState createState() => _MiscellaneousScreenState(); @@ -87,8 +88,9 @@ class _MiscellaneousScreenState extends State { }); }); - _commentsController = - TextEditingController(text: widget.selectedItem?["comments"] ?? ""); + _commentsController = TextEditingController( + text: widget.selectedItem?["comments"] ?? "", + ); // Set the selected value if available if (widget.selectedItem != null && @@ -143,29 +145,32 @@ class _MiscellaneousScreenState extends State { @override Widget build(BuildContext context) { - return ResponsiveBuilder(builder: (context, sizingInfo) { - bool isMobile = sizingInfo.isMobile; - bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop; + return ResponsiveBuilder( + builder: (context, sizingInfo) { + bool isMobile = sizingInfo.isMobile; + bool isDesktop = + sizingInfo.deviceScreenType == DeviceScreenType.desktop; - return Container( - child: Form( - key: _formKey, - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(28.0), - child: Center( - child: Column(children: _buildAccomadtionForm(isDesktop)), + return Container( + child: Form( + key: _formKey, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(top: 30.0), + child: Center( + child: Column(children: _buildAccomadtionForm(isDesktop)), + ), ), - ) - ], + ], + ), ), ), - ), - ); - }); + ); + }, + ); } List _buildAccomadtionForm(bool isDesktop) { @@ -193,14 +198,15 @@ class _MiscellaneousScreenState extends State { Text( "Special Type *", style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Color(0xFF575A74)), + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xFF575A74), + ), ), SizedBox(height: 5), isDesktop ? Row(children: _buildTripType(isDesktop)) - : Column(children: _buildTripType(isDesktop)) + : Column(children: _buildTripType(isDesktop)), ], ), ]; @@ -211,19 +217,24 @@ class _MiscellaneousScreenState extends State { widget.apiData?['miscellaneous_special_request'] ?? []; // selectedInsuranceType = purposeList.isNotEmpty ? purposeList.first['dropdown_value'] : null; - List> dropdownItems = purposeList - .map((item) => DropdownMenuItem( - value: item['dropdown_key'], - child: Text(item['dropdown_value']), - )) - .toList(); + List> dropdownItems = + purposeList + .map( + (item) => DropdownMenuItem( + value: item['dropdown_key'], + child: Text(item['dropdown_value']), + ), + ) + .toList(); if (dropdownItems.isEmpty) { dropdownItems.add( DropdownMenuItem( value: null, - child: Text("No options available", - style: TextStyle(color: Colors.grey)), + child: Text( + "No options available", + style: TextStyle(color: Colors.grey), + ), ), ); } @@ -236,9 +247,10 @@ class _MiscellaneousScreenState extends State { CustomTextFieldWrapper( isFocused: _isHotelNameFocused, isDesktop: isDesktop, - width: isDesktop - ? MediaQuery.of(context).size.width * 0.34 - : MediaQuery.of(context).size.width * 0.66, + width: + isDesktop + ? MediaQuery.of(context).size.width * 0.34 + : MediaQuery.of(context).size.width * 0.66, child: SizedBox( height: 40, child: DropdownButtonFormField( @@ -247,28 +259,27 @@ class _MiscellaneousScreenState extends State { style: TextStyle(fontSize: 12), decoration: InputDecoration( border: InputBorder.none, - contentPadding: - EdgeInsets.symmetric(horizontal: 10), // Proper padding + contentPadding: EdgeInsets.symmetric( + horizontal: 10, + ), // Proper padding ), - onChanged: purposeList.isNotEmpty - ? (newValue) { - setState(() { - selectedSpecialType = newValue; - }); + onChanged: + purposeList.isNotEmpty + ? (newValue) { + setState(() { + selectedSpecialType = newValue; + }); - print(selectedSpecialType); - } - : null, + print(selectedSpecialType); + } + : null, items: dropdownItems, ), ), ), if (errorMessages["special_request"] != null) ...[ SizedBox(height: 5), // Space before error message - Text( - "Required", - style: TextStyle(color: Colors.red, fontSize: 12), - ), + Text("Required", style: TextStyle(color: Colors.red, fontSize: 12)), ], ]; } @@ -281,17 +292,19 @@ class _MiscellaneousScreenState extends State { Text( "Comments *", style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Color(0xFF575A74)), + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xFF575A74), + ), ), SizedBox(height: 5), CustomTextFieldWrapper( isFocused: _commentsFocus, // Dropdown doesn't use focus isDesktop: isDesktop, - width: isDesktop - ? MediaQuery.of(context).size.width * 0.34 - : MediaQuery.of(context).size.width * 0.66, + width: + isDesktop + ? MediaQuery.of(context).size.width * 0.34 + : MediaQuery.of(context).size.width * 0.66, child: SizedBox( height: 40, child: TextField( @@ -310,17 +323,12 @@ class _MiscellaneousScreenState extends State { ), if (errorMessages["comments"] != null) ...[ SizedBox(height: 5), // Space before error message - Text( - "Required", - style: TextStyle(color: Colors.red, fontSize: 12), - ), + Text("Required", style: TextStyle(color: Colors.red, fontSize: 12)), ], ], ), if (isDesktop) Spacer(), - SizedBox( - height: 5, - ), + SizedBox(height: 5), Row( mainAxisAlignment: MainAxisAlignment.end, children: _handleAction(isDesktop), @@ -338,9 +346,7 @@ class _MiscellaneousScreenState extends State { }, style: ElevatedButton.styleFrom( backgroundColor: Colors.grey[400], // Light grey color - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), ), child: Text( @@ -349,7 +355,6 @@ class _MiscellaneousScreenState extends State { ), ), SizedBox(width: 10), // Space between buttons - // Save Changes Button ElevatedButton( onPressed: () { @@ -357,9 +362,7 @@ class _MiscellaneousScreenState extends State { }, style: ElevatedButton.styleFrom( backgroundColor: Color(0xFF114D8B), // Primary color for save - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), ), child: Text( diff --git a/lib/Screens/itnerary/taxi.dart b/lib/Screens/itnerary/taxi.dart index 2f559fa..ecf7116 100644 --- a/lib/Screens/itnerary/taxi.dart +++ b/lib/Screens/itnerary/taxi.dart @@ -99,7 +99,7 @@ class _TaxiScreenState extends State { _addFocusListener( _destinationFocusNode, - (focus) => _destinationFocus = focus, + (focus) => _destinationFocus = focus, ); _addFocusListener(_locationFocusNode, (focus) => _locationFocus = focus); _addFocusListener(_dateFocusNode, (focus) => _dateFocus = focus); @@ -107,7 +107,7 @@ class _TaxiScreenState extends State { _addFocusListener(_taxiReqFocusNode, (focus) => _taxiReqFocused = focus); _addFocusListener( _numPassengerFocusNode, - (focus) => _numPassengerFocus = focus, + (focus) => _numPassengerFocus = focus, ); _addFocusListener(_commentsFocusNode, (focus) => _commentsFocus = focus); @@ -219,7 +219,7 @@ class _TaxiScreenState extends State { child: Column( children: [ Padding( - padding: const EdgeInsets.all(28.0), + padding: const EdgeInsets.only(top: 30.0), child: Center( child: Column(children: _buildAccomadtionForm(isDesktop)), ), @@ -262,14 +262,14 @@ class _TaxiScreenState extends State { List purposeList = widget.apiData?['taxt_car_type'] ?? []; List> dropdownItems = - purposeList - .map( - (item) => DropdownMenuItem( - value: item['dropdown_key'], - child: Text(item['dropdown_value']), - ), - ) - .toList(); + purposeList + .map( + (item) => DropdownMenuItem( + value: item['dropdown_key'], + child: Text(item['dropdown_value']), + ), + ) + .toList(); if (dropdownItems.isEmpty) { dropdownItems.add( @@ -285,7 +285,7 @@ class _TaxiScreenState extends State { // Default selected value selectedCarType ??= - dropdownItems.isNotEmpty ? dropdownItems.first.value : null; + dropdownItems.isNotEmpty ? dropdownItems.first.value : null; return [ Column( @@ -378,16 +378,16 @@ class _TaxiScreenState extends State { ), // Proper padding ), onChanged: - purposeList.isNotEmpty - ? (newValue) { - setState(() { - selectedCarType = newValue; - }); - print( - "Updating form data: Flight -> trip_type -> ${newValue ?? ""}", - ); - } - : null, + purposeList.isNotEmpty + ? (newValue) { + setState(() { + selectedCarType = newValue; + }); + print( + "Updating form data: Flight -> trip_type -> ${newValue ?? ""}", + ); + } + : null, items: dropdownItems, ), @@ -403,14 +403,14 @@ class _TaxiScreenState extends State { List purposeList = widget.apiData?['taxi_car_required_for'] ?? []; List> dropdownItems = - purposeList - .map( - (item) => DropdownMenuItem( - value: item['dropdown_key'], - child: Text(item['dropdown_value']), - ), - ) - .toList(); + purposeList + .map( + (item) => DropdownMenuItem( + value: item['dropdown_key'], + child: Text(item['dropdown_value']), + ), + ) + .toList(); if (dropdownItems.isEmpty) { dropdownItems.add( @@ -426,16 +426,16 @@ class _TaxiScreenState extends State { // Default selected value selectedReqTaxi ??= - dropdownItems.isNotEmpty ? dropdownItems.first.value : null; + dropdownItems.isNotEmpty ? dropdownItems.first.value : null; return [ CustomTextFieldWrapper( isFocused: _taxiReqFocused, isDesktop: isDesktop, width: - isDesktop - ? MediaQuery.of(context).size.width * 0.34 - : MediaQuery.of(context).size.width * 0.66, + isDesktop + ? MediaQuery.of(context).size.width * 0.34 + : MediaQuery.of(context).size.width * 0.66, child: SizedBox( height: 40, child: DropdownButtonFormField( @@ -449,16 +449,16 @@ class _TaxiScreenState extends State { ), // Proper padding ), onChanged: - purposeList.isNotEmpty - ? (newValue) { - setState(() { - selectedReqTaxi = newValue; - }); - print( - "Updating form data: Flight -> trip_type -> ${newValue ?? ""}", - ); - } - : null, + purposeList.isNotEmpty + ? (newValue) { + setState(() { + selectedReqTaxi = newValue; + }); + print( + "Updating form data: Flight -> trip_type -> ${newValue ?? ""}", + ); + } + : null, items: dropdownItems, ), @@ -478,10 +478,10 @@ class _TaxiScreenState extends State { DateTime? pickedDate = await showDatePicker( context: context, initialDate: - _selectedCheckOutDate != null && - _selectedCheckOutDate!.isAfter(today) - ? _selectedCheckOutDate! - : today, + _selectedCheckOutDate != null && + _selectedCheckOutDate!.isAfter(today) + ? _selectedCheckOutDate! + : today, firstDate: today, lastDate: DateTime(2100), ); @@ -516,11 +516,10 @@ class _TaxiScreenState extends State { pickedTime.minute, ); - final isToday = selectedDate.year == now.year && - selectedDate.month == now.month && - selectedDate.day == now.day; + selectedDate.month == now.month && + selectedDate.day == now.day; bool isPastTime = selectedDateTime.isBefore(now); @@ -528,20 +527,27 @@ class _TaxiScreenState extends State { setState(() { errorMessages["time"] = "You can't select a past time."; _selectedCheckOutTime = null; // ✅ Reset time variable - _timeController.text = ""; // ✅ Clear text field + _timeController.text = ""; // ✅ Clear text field }); return; - }else{ setState(() { - _selectedCheckOutTime = pickedTime; - // Formatting time to HH:mm (24-hour format) - final now = DateTime.now(); - final formattedTime = DateFormat('HH:mm').format( - DateTime(now.year, now.month, now.day, pickedTime.hour, - pickedTime.minute), - ); - errorMessages["time"] = ""; - _timeController.text = formattedTime; - }); } + } else { + setState(() { + _selectedCheckOutTime = pickedTime; + // Formatting time to HH:mm (24-hour format) + final now = DateTime.now(); + final formattedTime = DateFormat('HH:mm').format( + DateTime( + now.year, + now.month, + now.day, + pickedTime.hour, + pickedTime.minute, + ), + ); + errorMessages["time"] = ""; + _timeController.text = formattedTime; + }); + } } } @@ -713,7 +719,10 @@ class _TaxiScreenState extends State { child: SizedBox( height: 40, child: GestureDetector( - onTap: () => _selectCheckOutTime(context), + onTap: () { + _timeController.text = ""; + _selectCheckOutTime(context); + }, child: AbsorbPointer( child: TextField( focusNode: _timeFocusNode, @@ -739,7 +748,10 @@ class _TaxiScreenState extends State { if (errorMessages["time"] != null) ...[ SizedBox(height: 5), // Space before error message // Text("Required", style: TextStyle(color: Colors.red, fontSize: 12)), - Text(errorMessages["time"]!, style: TextStyle(color: Colors.red, fontSize: 12)), + Text( + errorMessages["time"]!, + style: TextStyle(color: Colors.red, fontSize: 12), + ), ], ], ), @@ -764,9 +776,9 @@ class _TaxiScreenState extends State { isFocused: _commentsFocus, // Dropdown doesn't use focus isDesktop: isDesktop, width: - isDesktop - ? MediaQuery.of(context).size.width * 0.34 - : MediaQuery.of(context).size.width * 0.66, + isDesktop + ? MediaQuery.of(context).size.width * 0.34 + : MediaQuery.of(context).size.width * 0.66, child: SizedBox( height: 40, @@ -834,4 +846,4 @@ class _TaxiScreenState extends State { ), ]; } -} \ No newline at end of file +} diff --git a/lib/Screens/itnerary/train.dart b/lib/Screens/itnerary/train.dart index 248938c..72e4a08 100644 --- a/lib/Screens/itnerary/train.dart +++ b/lib/Screens/itnerary/train.dart @@ -324,7 +324,7 @@ class _TrainScreenState extends State { // height: 6, // ), Padding( - padding: const EdgeInsets.all(28.0), + padding: const EdgeInsets.only(top: 30.0), child: Center( child: Column(children: _buildAccomadtionForm(isDesktop)), ), diff --git a/lib/Screens/itnerary/visa.dart b/lib/Screens/itnerary/visa.dart index a507456..2e8f2da 100644 --- a/lib/Screens/itnerary/visa.dart +++ b/lib/Screens/itnerary/visa.dart @@ -18,14 +18,15 @@ class VisaScreen extends StatefulWidget { final Map? selectedItem; final String? loginUser; - VisaScreen( - {required this.onClose, - required this.onSaveVisa, - this.apiData, - required this.selectedItem, - required this.apiCountryData, - required this.loginUser, - required this.flightData}); + VisaScreen({ + required this.onClose, + required this.onSaveVisa, + this.apiData, + required this.selectedItem, + required this.apiCountryData, + required this.loginUser, + required this.flightData, + }); @override _VisaScreenState createState() => _VisaScreenState(); @@ -99,14 +100,18 @@ class _VisaScreenState extends State { _addFocusListener(_tripTypeFocusNode, (focus) => _tripTypeFocused = focus); _addFocusListener( - _hotelNameFocusNode, (focus) => _isHotelNameFocused = focus); + _hotelNameFocusNode, + (focus) => _isHotelNameFocused = focus, + ); _addFocusListener(_dateFocusNode, (focus) => _dateFocus = focus); _addFocusListener(_commentsFocusNode, (focus) => _commentsFocus = focus); - _visaCommentsController = - TextEditingController(text: widget.selectedItem?["comments"] ?? ""); - _dateController = - TextEditingController(text: widget.selectedItem?["start_date"] ?? ""); + _visaCommentsController = TextEditingController( + text: widget.selectedItem?["comments"] ?? "", + ); + _dateController = TextEditingController( + text: widget.selectedItem?["start_date"] ?? "", + ); // Set the selected value if available if (widget.selectedItem != null && @@ -130,8 +135,9 @@ class _VisaScreenState extends State { // ✅ Only set controller after value is updated // final parsedDate = // DateTime.tryParse(flightFirstTripDateNotifier.value ?? ''); - final parsedDate = DateFormat("dd-MM-yyyy") - .parse(flightFirstTripDateNotifier.value ?? ''); + final parsedDate = DateFormat( + "dd-MM-yyyy", + ).parse(flightFirstTripDateNotifier.value ?? ''); if (parsedDate != null) { _dateController.text = DateFormat('dd-MM-yyyy').format(parsedDate); } @@ -181,17 +187,16 @@ class _VisaScreenState extends State { } Map getFlightTripDateRange( - List> flightData) { - final allTrips = flightData - .expand((flight) => flight['trips'] ?? []) - .whereType>() - .toList(); + List> flightData, + ) { + final allTrips = + flightData + .expand((flight) => flight['trips'] ?? []) + .whereType>() + .toList(); if (allTrips.isEmpty) { - return { - 'firstTripDate': null, - 'lastTripDate': null, - }; + return {'firstTripDate': null, 'lastTripDate': null}; } allTrips.sort((a, b) { @@ -229,7 +234,7 @@ class _VisaScreenState extends State { List requiredFields = [ "type_of_visa", "country_code", - "start_date" + "start_date", ]; // Check validation for each field @@ -260,29 +265,32 @@ class _VisaScreenState extends State { @override Widget build(BuildContext context) { - return ResponsiveBuilder(builder: (context, sizingInfo) { - bool isMobile = sizingInfo.isMobile; - bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop; + return ResponsiveBuilder( + builder: (context, sizingInfo) { + bool isMobile = sizingInfo.isMobile; + bool isDesktop = + sizingInfo.deviceScreenType == DeviceScreenType.desktop; - return Container( - child: Form( - key: _formKey, - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(28.0), - child: Center( - child: Column(children: _buildAccomadtionForm(isDesktop)), + return Container( + child: Form( + key: _formKey, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(top: 30.0), + child: Center( + child: Column(children: _buildAccomadtionForm(isDesktop)), + ), ), - ) - ], + ], + ), ), ), - ), - ); - }); + ); + }, + ); } List _buildAccomadtionForm(bool isDesktop) { @@ -308,14 +316,7 @@ class _VisaScreenState extends State { } List _buildFirstRow(isDesktop) { - return [ - if (isDesktop) - Spacer() - else - SizedBox( - height: 8, - ), - ]; + return [if (isDesktop) Spacer() else SizedBox(height: 8)]; } List _buildTripType(bool isDesktop) { @@ -354,7 +355,7 @@ class _VisaScreenState extends State { // Map country codes to country names countryMap = { for (var item in countryList) - item['country_code'] as String: item['country_name'] as String + item['country_code'] as String: item['country_name'] as String, }; // Extract only country codes for processing @@ -417,19 +418,24 @@ class _VisaScreenState extends State { List purposeList = widget.apiData?['visa_type_of_visa'] ?? []; - List> dropdownItems = purposeList - .map((item) => DropdownMenuItem( - value: item['dropdown_key'], - child: Text(item['dropdown_value']), - )) - .toList(); + List> dropdownItems = + purposeList + .map( + (item) => DropdownMenuItem( + value: item['dropdown_key'], + child: Text(item['dropdown_value']), + ), + ) + .toList(); if (dropdownItems.isEmpty) { dropdownItems.add( DropdownMenuItem( value: null, - child: Text("No options available", - style: TextStyle(color: Colors.grey)), + child: Text( + "No options available", + style: TextStyle(color: Colors.grey), + ), ), ); } @@ -438,25 +444,26 @@ class _VisaScreenState extends State { selectedPurpose ??= dropdownItems.isNotEmpty ? dropdownItems.first.value : null; return [ - Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Country *", style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Color(0xFF575A74)), + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xFF575A74), + ), ), SizedBox(height: 5), CustomTextFieldWrapper( isFocused: _isHotelNameFocused, 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, + width: + isDesktop + ? MediaQuery.of(context).size.width * 0.34 + : MediaQuery.of(context).size.width * 0.66, child: SizedBox( height: 40, child: DropdownSearch( @@ -474,25 +481,25 @@ class _VisaScreenState extends State { dropdownDecoratorProps: DropDownDecoratorProps( dropdownSearchDecoration: InputDecoration( border: InputBorder.none, - contentPadding: EdgeInsets.symmetric( - horizontal: 1, + contentPadding: EdgeInsets.symmetric(horizontal: 1), + ), + ), + dropdownBuilder: + (context, selectedItem) => Align( + // Center-align selected item + alignment: Alignment.centerLeft, + child: Text( + selectedItem ?? "Select ", + style: TextStyle(fontSize: 12), + ), ), - ), - ), - dropdownBuilder: (context, selectedItem) => Align( - // Center-align selected item - alignment: Alignment.centerLeft, - child: Text( - selectedItem ?? "Select ", - style: TextStyle(fontSize: 12), - ), - ), onChanged: (String? newValue) { setState(() { // Find the country_code based on selected country_name - selectedCountry = countryMap.entries - .firstWhere((entry) => entry.value == newValue) - .key; + selectedCountry = + countryMap.entries + .firstWhere((entry) => entry.value == newValue) + .key; if (selectedCountry!.isNotEmpty) { errorMessages.remove("country_code"); @@ -504,29 +511,22 @@ class _VisaScreenState extends State { ), if (errorMessages["country_code"] != null) ...[ SizedBox(height: 5), // Space before error message - Text( - "Required", - style: TextStyle(color: Colors.red, fontSize: 12), - ), + Text("Required", style: TextStyle(color: Colors.red, fontSize: 12)), ], ], ), - if (isDesktop) - Spacer() - else - SizedBox( - height: 8, - ), + if (isDesktop) Spacer() else SizedBox(height: 8), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Type of Visa", style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Color(0xFF575A74)), + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xFF575A74), + ), ), SizedBox(height: 5), CustomTextFieldWrapper( @@ -544,18 +544,21 @@ class _VisaScreenState extends State { style: TextStyle(fontSize: 12), decoration: InputDecoration( border: InputBorder.none, - contentPadding: - EdgeInsets.symmetric(horizontal: 10), // Proper padding + contentPadding: EdgeInsets.symmetric( + horizontal: 10, + ), // Proper padding ), - onChanged: purposeList.isNotEmpty - ? (newValue) { - setState(() { - selectedPurpose = newValue; - }); - print( - "Updating form data: Flight -> trip_type -> ${newValue ?? ""}"); - } - : null, + onChanged: + purposeList.isNotEmpty + ? (newValue) { + setState(() { + selectedPurpose = newValue; + }); + print( + "Updating form data: Flight -> trip_type -> ${newValue ?? ""}", + ); + } + : null, items: dropdownItems, ), @@ -563,28 +566,21 @@ class _VisaScreenState extends State { ), if (errorMessages["type_of_visa"] != null) ...[ SizedBox(height: 5), // Space before error message - Text( - "Required", - style: TextStyle(color: Colors.red, fontSize: 12), - ), + Text("Required", style: TextStyle(color: Colors.red, fontSize: 12)), ], ], ), - if (isDesktop) - Spacer() - else - SizedBox( - height: 8, - ), + if (isDesktop) Spacer() else SizedBox(height: 8), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Start Date *", style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Color(0xFF575A74)), + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xFF575A74), + ), ), SizedBox(height: 5), CustomTextFieldWrapper( @@ -613,8 +609,11 @@ class _VisaScreenState extends State { floatingLabelBehavior: FloatingLabelBehavior.never, border: InputBorder.none, contentPadding: EdgeInsets.symmetric(vertical: 16), - suffixIcon: Icon(Icons.calendar_today, - size: 16, color: Colors.grey), + suffixIcon: Icon( + Icons.calendar_today, + size: 16, + color: Colors.grey, + ), ), ), ), @@ -623,10 +622,7 @@ class _VisaScreenState extends State { ), if (errorMessages["start_date"] != null) ...[ SizedBox(height: 5), // Space before error message - Text( - "Required", - style: TextStyle(color: Colors.red, fontSize: 12), - ), + Text("Required", style: TextStyle(color: Colors.red, fontSize: 12)), ], ], ), @@ -641,17 +637,19 @@ class _VisaScreenState extends State { Text( "Comments", style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w500, - color: Color(0xFF575A74)), + fontSize: 12, + fontWeight: FontWeight.w500, + color: Color(0xFF575A74), + ), ), SizedBox(height: 5), CustomTextFieldWrapper( isFocused: _commentsFocus, // Dropdown doesn't use focus isDesktop: isDesktop, - width: isDesktop - ? MediaQuery.of(context).size.width * 0.34 - : MediaQuery.of(context).size.width * 0.66, + width: + isDesktop + ? MediaQuery.of(context).size.width * 0.34 + : MediaQuery.of(context).size.width * 0.66, child: SizedBox( height: 40, child: TextField( @@ -671,9 +669,7 @@ class _VisaScreenState extends State { ], ), if (isDesktop) Spacer(), - SizedBox( - height: 5, - ), + SizedBox(height: 5), Column( children: [ Row( @@ -694,9 +690,7 @@ class _VisaScreenState extends State { }, style: ElevatedButton.styleFrom( backgroundColor: Colors.grey[400], // Light grey color - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), ), child: Text( @@ -705,7 +699,6 @@ class _VisaScreenState extends State { ), ), SizedBox(width: 10), // Space between buttons - // Save Changes Button ElevatedButton( onPressed: () { @@ -713,9 +706,7 @@ class _VisaScreenState extends State { }, style: ElevatedButton.styleFrom( backgroundColor: Color(0xFF114D8B), // Primary color for save - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), ), child: Text( diff --git a/lib/Screens/plans/create_plans.dart b/lib/Screens/plans/create_plans.dart index 5cead2f..45420d7 100644 --- a/lib/Screens/plans/create_plans.dart +++ b/lib/Screens/plans/create_plans.dart @@ -903,10 +903,15 @@ class CreateNewPlansState extends State { setState(() { apiCostData = plansJson; + + print("apiCostData...1"); costCenterMap = { for (var item in apiCostData!) + // item['department_id'].toString(): item['name'].toString(), item['cost_center_id'].toString(): item['name'].toString(), }; + + print("apiCostData...122"); costCenterIds = costCenterMap.keys.toList(); // Optionally auto-select the first item if not already selected @@ -1030,8 +1035,9 @@ class CreateNewPlansState extends State { // Handle Submit bool validateForm() { + print("validateForm"); validationErrors.clear(); // Clear previous errors - + print("validateForm.....1"); // Ensure either "user_id" or "traveller_id" is provided if ((planUsrId == null || planUsrId!.isEmpty) && (planTravlrId == null || planTravlrId!.isEmpty)) { @@ -1040,7 +1046,7 @@ class CreateNewPlansState extends State { validationErrors["traveller_id"] = "Either User ID or Traveller ID is required"; } - + print("validateForm.....2"); final requiredFields = { if (TripPlanAction != "Plan Creation Not Allowed") // "trip_type": _selectedTripType, @@ -1049,14 +1055,14 @@ class CreateNewPlansState extends State { "functional_department": selectedFuncDept, "purpose_of_travel": selectedPurpose, }; - + print("validateForm.....3"); for (var entry in requiredFields.entries) { if (entry.value == null || entry.value!.isEmpty) { validationErrors[entry.key] = "Required"; // "${entry.key.replaceAll('_', ' ').toUpperCase()} Required"; } } - + print("validateForm.....1"); // Validate at least one service is selected final serviceLists = [ flightList, @@ -1179,7 +1185,9 @@ class CreateNewPlansState extends State { void handleSubmit() { setState(() async { + print("Hansle Submit....11"); if (validateForm() && temporaryMessage == null) { + print("Hansle Submit....11222"); // if (selectedPlanId != null && selectedPlanId!.isNotEmpty) { // planData['plan_id'] = selectedPlanId; // Add plan_id for update // } @@ -1251,6 +1259,26 @@ class CreateNewPlansState extends State { } else { print("Failed to submit plan. Status: ${response.statusCode}"); print("Error: ${response.body}"); + + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text("Trip Creation Failed"), + content: Text( + "There was a problem submitting your plan. Please try again.", + ), + actions: [ + TextButton( + child: Text("OK"), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); } } catch (e) { print(" Error submitting plan: $e"); diff --git a/lib/Screens/plans/dynamic_itinerary_stepper.dart b/lib/Screens/plans/dynamic_itinerary_stepper.dart index fb143f7..be930a6 100644 --- a/lib/Screens/plans/dynamic_itinerary_stepper.dart +++ b/lib/Screens/plans/dynamic_itinerary_stepper.dart @@ -101,6 +101,12 @@ class DynamicItineraryState extends State { super.didChangeDependencies(); if (widget.tripType != _tripType) { + // setState(() { + // selectedOption = ""; + // isSelected = false; + // selectedIndex = null; + // selectedItem = null; + // }); updateTripType(widget.tripType); } }