travelAgentLst

This commit is contained in:
venbaittech 2025-06-20 14:44:50 +05:30
parent 29eedb3162
commit e33af3cd8a
13 changed files with 1013 additions and 440 deletions

View File

@ -216,8 +216,8 @@ class _TravelAgentListPlansState extends State<TravelAgentListPlans> {
if (response.statusCode == 200) {
final data = json.decode(response.body);
List<dynamic> plansJson = [];
// List<dynamic> plansJson = data['data'];
// List<dynamic> plansJson = [];
List<dynamic> plansJson = data['data'];
return plansJson.map((json) => Plan.fromJson(json)).toList();
} else {
throw Exception('Failed to load plans');

View File

@ -30,6 +30,8 @@ class _LoginWidgetState extends State<LoginWidget> {
final ApiService apiService = ApiService();
bool _moved = false;
bool _isLoading = false;
final _formKey = GlobalKey<FormState>();
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
@ -103,6 +105,10 @@ class _LoginWidgetState extends State<LoginWidget> {
Future<void> _login(BuildContext context) async {
if (_formKey.currentState!.validate()) {
setState(() {
_isLoading = true;
});
const String url = '$apiUrl/auth/login';
try {
@ -193,6 +199,10 @@ class _LoginWidgetState extends State<LoginWidget> {
fontSize: 16.0,
webBgColor: "linear-gradient(to right, #dc1c13, #dc1c13)",
);
} finally {
setState(() {
_isLoading = false;
});
}
}
}
@ -619,7 +629,13 @@ class _LoginWidgetState extends State<LoginWidget> {
children: [
Expanded(
child: ElevatedButton(
onPressed: () => _login(context),
// onPressed: () => _login(context),
onPressed:
_isLoading
? null
: () => _login(
context,
), // disable when loading
style: ElevatedButton.styleFrom(
backgroundColor: Color(
0xFF12B24B,
@ -639,23 +655,35 @@ class _LoginWidgetState extends State<LoginWidget> {
horizontal: 24,
vertical: 5,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"Sign In",
style: GoogleFonts.poppins(
fontWeight: FontWeight.w800,
fontSize: 13.5,
),
),
SizedBox(width: 3),
Icon(
Icons.arrow_forward_sharp,
color: Colors.white,
),
],
),
child:
_isLoading
? SizedBox(
height: 20,
width: 20,
child:
CircularProgressIndicator(
color: Colors.white,
strokeWidth: 2,
),
)
: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"Sign In",
style: GoogleFonts.poppins(
fontWeight:
FontWeight.w800,
fontSize: 13.5,
),
),
SizedBox(width: 3),
Icon(
Icons.arrow_forward_sharp,
color: Colors.white,
),
],
),
),
),
),

View File

@ -763,7 +763,10 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
child: SizedBox(
height: 40,
child: GestureDetector(
onTap: () => _selectCheckInDate(context),
onTap: () {
_checkInFocusNode.requestFocus();
_selectCheckInDate(context);
},
child: AbsorbPointer(
child: TextField(
focusNode: _checkInFocusNode,
@ -816,6 +819,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
height: 40,
child: GestureDetector(
onTap: () {
_checkInTimeFocusNode.requestFocus();
_checkInTimeController.text = "";
_selectCheckInTime(context);
},
@ -870,7 +874,10 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
child: SizedBox(
height: 40,
child: GestureDetector(
onTap: () => _selectCheckOutDate(context),
onTap: () {
_checkOutFocusNode.requestFocus();
_selectCheckOutDate(context);
},
child: AbsorbPointer(
child: TextField(
focusNode: _checkOutFocusNode,
@ -922,7 +929,10 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
child: SizedBox(
height: 40,
child: GestureDetector(
onTap: () => _selectCheckOutTime(context),
onTap: () {
_checkOutTimeFocusNode.requestFocus();
_selectCheckOutTime(context);
},
child: AbsorbPointer(
child: TextField(
focusNode: _checkOutTimeFocusNode,

View File

@ -5,6 +5,7 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:responsive_builder/responsive_builder.dart';
import '../../utils/auth_utils.dart';
import '../../widgets/custom_radio_button.dart';
import '../../widgets/custom_text_field.dart';
import '../../widgets/custom_text_itnerary_sub.dart';
@ -64,6 +65,9 @@ class FlightScreenState extends State<FlightScreen> {
String? selectedvisa_available;
int multiTripRowCount = 1;
// Color? layoutColor;
Color layoutColor = Colors.grey;
List<String> dataHeader = [
"_tripType",
"_class",
@ -89,7 +93,9 @@ class FlightScreenState extends State<FlightScreen> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
loadInitialData();
});
print("TripType - ${widget.tripType}");
// final newTripType = widget.tripTypeNotifier.value;
@ -280,6 +286,24 @@ class FlightScreenState extends State<FlightScreen> {
return 1; // Default for Oneway
}
void loadInitialData() async {
String? layoutString = await getLayoutColor();
// setState(() {
// layoutColor =
// layoutString != null
// ? Color(int.parse(layoutString))
// : Colors.redAccent;
// });
setState(() {
layoutColor =
layoutString != null
? Color(int.parse(layoutString))
: Colors.redAccent;
});
}
void _initializeFields() {
print("_initializeFields-----------------");
@ -982,7 +1006,9 @@ class FlightScreenState extends State<FlightScreen> {
return [
CustomTextFieldWrapper(
// isFocused: _tripTypeFocused,
isFocused: focusStates["_tripType1Focused"] ?? false,
// isFocused: focusStates["_tripType1Focused"] ?? false,
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: isDesktop,
width: isDesktop ? MediaQuery.of(context).size.width * 0.32 : null,
child: SizedBox(
@ -1008,8 +1034,35 @@ class FlightScreenState extends State<FlightScreen> {
.toList(),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 1),
// border: InputBorder.none,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(focusStates["_tripType1Focused"] ?? false)
? layoutColor!
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(focusStates["_tripType1Focused"] ?? false)
? layoutColor
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: layoutColor, width: 1),
),
contentPadding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
),
),
onChanged: (newValue) {
@ -1427,7 +1480,9 @@ class FlightScreenState extends State<FlightScreen> {
SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper(
// isFocused: _fromFocus,
isFocused: focusStates["_from${index}Focused"] ?? false,
// isFocused: focusStates["_from${index}Focused"] ?? false,
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
// isFocused: focusStates["_from${fieldIndex}Focused"] ?? false,
isDesktop: isDesktop,
child: SizedBox(
@ -1548,9 +1603,38 @@ class FlightScreenState extends State<FlightScreen> {
items: countryMap.values.toList(),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(focusStates["_from${index}Focused"] ??
false)
? layoutColor!
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(focusStates["_from${index}Focused"] ??
false)
? layoutColor
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: layoutColor,
width: 1,
),
),
contentPadding: EdgeInsets.symmetric(
horizontal: 1,
horizontal: 10,
vertical: 5,
),
),
),
@ -1652,160 +1736,214 @@ class FlightScreenState extends State<FlightScreen> {
),
SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper(
isFocused: focusStates["_to${index}Focused"] ?? false,
// isFocused: focusStates["_to${index}Focused"] ?? false,
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: isDesktop,
child: SizedBox(
height: 40,
child:
isCountryLoading
? Center(child: CircularProgressIndicator())
: DropdownSearch<String>(
enabled:
!(selectedTripType == "Roundtrip" && index == 2),
selectedItem:
selectedTo[index] != null
? countryMap[selectedTo[index]]
: null,
popupProps: PopupProps.menu(
fit: FlexFit.loose,
constraints: BoxConstraints(maxHeight: 220),
showSearchBox: true, // Enables search functionality
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
hintText: "Search...",
contentPadding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 1,
: Focus(
focusNode: focusNodes["_to${index}FocusNode"],
onFocusChange: (hasFocus) {
setState(() {
focusStates["_to${index}Focused"] = hasFocus;
});
},
child: GestureDetector(
//
onTap: () {
// Request focus when user taps
focusNodes["_to${index}FocusNode"]?.requestFocus();
},
child: DropdownSearch<String>(
enabled:
!(selectedTripType == "Roundtrip" &&
index == 2),
selectedItem:
selectedTo[index] != null
? countryMap[selectedTo[index]]
: null,
popupProps: PopupProps.menu(
fit: FlexFit.loose,
constraints: BoxConstraints(maxHeight: 220),
showSearchBox:
true, // Enables search functionality
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
hintText: "Search...",
contentPadding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 1,
),
),
style: TextStyle(fontSize: 12),
),
),
style: TextStyle(fontSize: 12),
),
menuProps: MenuProps(backgroundColor: Colors.white),
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,
menuProps: MenuProps(
backgroundColor: Colors.white,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
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: [
Text(
city,
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
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(
code,
airport,
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
fontSize: 11,
color: Colors.grey,
overflow: TextOverflow.ellipsis,
),
),
],
),
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(
dropdownSearchDecoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(focusStates["_to${index}Focused"] ??
false)
? layoutColor!
: Colors.white,
width: 0.5,
),
],
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(focusStates["_to${index}Focused"] ??
false)
? layoutColor
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: layoutColor,
width: 1,
),
),
contentPadding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
),
);
},
// 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(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 1),
),
// 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(
(entry) => entry.value == newValue,
)
.key;
print(selectedTo[index]);
if (selectedTripType == "Roundtrip") {
print('rounfTo${selectedTo[index]}');
// textControllers["_to${index+1}Controller"]?.text = selectedFrom[index]!;
selectedFrom[2] = selectedTo[index]!;
}
});
},
),
),
// 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(
(entry) => entry.value == newValue,
)
.key;
print(selectedTo[index]);
if (selectedTripType == "Roundtrip") {
print('rounfTo${selectedTo[index]}');
// textControllers["_to${index+1}Controller"]?.text = selectedFrom[index]!;
selectedFrom[2] = selectedTo[index]!;
}
});
},
),
),
),
@ -1885,74 +2023,119 @@ class FlightScreenState extends State<FlightScreen> {
),
SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper(
isFocused: focusStates["_class${index}Focused"] ?? false,
// isFocused: focusStates["_class${index}Focused"] ?? false,
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: isDesktop,
child: SizedBox(
height: 35,
height: 40,
width: double.infinity,
child: DropdownSearch<Map<String, dynamic>>(
items: purposeList.cast<Map<String, dynamic>>(),
selectedItem: purposeList.firstWhere(
(item) => item['dropdown_key'] == selectedClasses[index],
orElse: () => {},
),
itemAsString: (item) => item['dropdown_value'] ?? '',
popupProps: PopupProps.menu(
showSearchBox: false,
fit: FlexFit.loose,
menuProps: const MenuProps(backgroundColor: Colors.white),
itemBuilder: (context, item, isSelected) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
child: Focus(
focusNode: focusNodes["_class${index}FocusNode"],
onFocusChange: (hasFocus) {
setState(() {
focusStates["_class${index}Focused"] = hasFocus;
});
},
child: GestureDetector(
//
onTap: () {
// Request focus when user taps
focusNodes["_class${index}FocusNode"]?.requestFocus();
},
child: DropdownSearch<Map<String, dynamic>>(
items: purposeList.cast<Map<String, dynamic>>(),
selectedItem: purposeList.firstWhere(
(item) => item['dropdown_key'] == selectedClasses[index],
orElse: () => {},
),
itemAsString: (item) => item['dropdown_value'] ?? '',
popupProps: PopupProps.menu(
showSearchBox: false,
fit: FlexFit.loose,
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,
color: Colors.black,
),
),
);
},
),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
// border: InputBorder.none,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(focusStates["_class${index}Focused"] ?? false)
? layoutColor!
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(focusStates["_class${index}Focused"] ?? false)
? layoutColor
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: layoutColor, width: 1),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
),
child: Text(
item['dropdown_value'] ?? '',
),
dropdownBuilder: (context, selectedItem) {
if (selectedItem == null || selectedItem.isEmpty) {
return Text(
"Select Class",
style: GoogleFonts.poppins(
color: Colors.grey,
fontSize: 13,
),
);
}
return Text(
selectedItem['dropdown_value'] ?? '',
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
),
);
},
),
dropdownDecoratorProps: const DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
);
},
onChanged:
purposeList.isNotEmpty
? (Map<String, dynamic>? newValue) {
setState(() {
selectedClasses[index] =
newValue?['dropdown_key'];
print(
"Selected Class: ${selectedClasses[index]}",
);
});
}
: null,
),
),
dropdownBuilder: (context, selectedItem) {
if (selectedItem == null || selectedItem.isEmpty) {
return Text(
"Select Class",
style: GoogleFonts.poppins(
color: Colors.grey,
fontSize: 13,
),
);
}
return Text(
selectedItem['dropdown_value'] ?? '',
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
);
},
onChanged:
purposeList.isNotEmpty
? (Map<String, dynamic>? newValue) {
setState(() {
selectedClasses[index] = newValue?['dropdown_key'];
print("Selected Class: ${selectedClasses[index]}");
});
}
: null,
),
),
),
@ -1987,7 +2170,10 @@ class FlightScreenState extends State<FlightScreen> {
child: SizedBox(
height: 40,
child: GestureDetector(
onTap: () => _selectCheckOutDate(context),
onTap: () {
focusNodes["_date${index}FocusNode"]?.requestFocus();
_selectCheckOutDate(context);
},
child: AbsorbPointer(
child: TextField(
focusNode: focusNodes["_date${index}FocusNode"],
@ -1995,13 +2181,44 @@ class FlightScreenState extends State<FlightScreen> {
controller: textControllers["_date${index}Controller"],
readOnly: true,
style: const TextStyle(fontSize: 12),
decoration: const InputDecoration(
decoration: InputDecoration(
labelText: "Select Date",
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
labelStyle: const TextStyle(
fontSize: 12,
color: Colors.grey,
),
floatingLabelBehavior: FloatingLabelBehavior.never,
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16),
suffixIcon: Icon(
// border: OutlineInputBorder(
// borderRadius: BorderRadius.circular(8),
// borderSide: BorderSide(
// color:
// (focusStates["_date${index}Focused"] ?? false)
// ? layoutColor!
// : Colors.white,
// width: 0.5,
// ),
// ),
// enabledBorder: OutlineInputBorder(
// borderSide: BorderSide(
// color:
// (focusStates["_date${index}Focused"] ?? false)
// ? layoutColor
// : Colors.white,
// // : const Color(0xFFD6D5E6),
// width: 0.5,
// // const Color(0xFFD6D5E6),
// ),
// ),
// focusedBorder: OutlineInputBorder(
// borderSide: BorderSide(color: layoutColor, width: 1),
// ),
// contentPadding: const EdgeInsets.symmetric(
// horizontal: 10,
// vertical: 5,
// ),
suffixIcon: const Icon(
Icons.calendar_today,
size: 16,
color: Colors.grey,
@ -2042,6 +2259,7 @@ class FlightScreenState extends State<FlightScreen> {
height: 40,
child: GestureDetector(
onTap: () {
focusNodes["_time${index}FocusNode"]?.requestFocus();
textControllers["_time${index}Controller"]?.text = "";
_clearError("time_$index");
// validateTimeDifference(index);
@ -2214,74 +2432,116 @@ class FlightScreenState extends State<FlightScreen> {
SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper(
// use same wrapper as class
isFocused: focusStates["_visa1Focused"] ?? false,
// isFocused: focusStates["_visa1Focused"] ?? false,
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: isDesktop,
child: SizedBox(
height: 35,
width: double.infinity,
child: DropdownSearch<Map<String, dynamic>>(
items: visa_available.cast<Map<String, dynamic>>(),
selectedItem: visa_available.firstWhere(
(item) => item['dropdown_key'] == selectedvisa_available,
orElse: () => {},
),
itemAsString: (item) => item['dropdown_value'] ?? '',
popupProps: PopupProps.menu(
showSearchBox: false,
fit: FlexFit.loose,
menuProps: const MenuProps(backgroundColor: Colors.white),
itemBuilder: (context, item, isSelected) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
child: Focus(
focusNode: focusNodes["_visa1FocusNode"],
onFocusChange: (hasFocus) {
setState(() {
focusStates["_visa1Focused"] = hasFocus;
});
},
child: GestureDetector(
//
onTap: () {
// Request focus when user taps
focusNodes["_visa1FocusNode"]?.requestFocus();
},
child: DropdownSearch<Map<String, dynamic>>(
items: visa_available.cast<Map<String, dynamic>>(),
selectedItem: visa_available.firstWhere(
(item) => item['dropdown_key'] == selectedvisa_available,
orElse: () => {},
),
itemAsString: (item) => item['dropdown_value'] ?? '',
popupProps: PopupProps.menu(
showSearchBox: false,
fit: FlexFit.loose,
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,
color: Colors.black,
),
),
);
},
),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
// border: InputBorder.none,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(focusStates["_visa1Focused"] ?? false)
? layoutColor!
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(focusStates["_visa1Focused"] ?? false)
? layoutColor
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: layoutColor, width: 1),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
),
child: Text(
item['dropdown_value'] ?? '',
),
dropdownBuilder: (context, selectedItem) {
if (selectedItem == null || selectedItem.isEmpty) {
return Text(
"Select Option",
style: GoogleFonts.poppins(
color: Colors.grey,
fontSize: 13,
),
);
}
return Text(
selectedItem['dropdown_value'] ?? '',
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
),
);
},
),
dropdownDecoratorProps: const DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
);
},
onChanged:
visa_available.isNotEmpty
? (Map<String, dynamic>? newValue) {
setState(() {
selectedvisa_available =
newValue?['dropdown_key'];
print("Selected Visa: $selectedvisa_available");
});
}
: null,
),
),
dropdownBuilder: (context, selectedItem) {
if (selectedItem == null || selectedItem.isEmpty) {
return Text(
"Select Option",
style: GoogleFonts.poppins(
color: Colors.grey,
fontSize: 13,
),
);
}
return Text(
selectedItem['dropdown_value'] ?? '',
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
);
},
onChanged:
visa_available.isNotEmpty
? (Map<String, dynamic>? newValue) {
setState(() {
selectedvisa_available = newValue?['dropdown_key'];
print("Selected Visa: $selectedvisa_available");
});
}
: null,
),
),
),

View File

@ -135,7 +135,6 @@ class _ForexScreenState extends State<ForexScreen> {
String? selectedQuotedAmount;
int? selectedCashPercent;
int? selectedCardPercent;
bool userEdited = false;
Map<String, dynamic> get forexData {
@ -399,7 +398,10 @@ class _ForexScreenState extends State<ForexScreen> {
focusStates[field] = false;
}
}
print("textControllers - $textControllers");
print("Focus States KeysII: ${focusStates.keys.toList()}");
print("Focus Nodes KeysII: ${focusNodes.keys.toList()}");
print("Text Controllers KeysII: ${textControllers.keys.toList()}");
// Add focus listeners
focusNodes.forEach((key, focusNode) {
@ -1347,64 +1349,85 @@ class _ForexScreenState extends State<ForexScreen> {
// ),
// ),
CustomTextFieldForexWrapper(
isFocused: focusStates["_countries"] ?? false,
isFocused: focusStates["_countriesFocused"] ?? false,
isDesktop: isDesktop,
child: SizedBox(
height: 40,
child: DropdownSearch<String>(
selectedItem: countryMap[selectedCountry],
popupProps: PopupProps.menu(
showSearchBox: true,
fit: FlexFit.loose,
constraints: BoxConstraints(maxHeight: 250),
menuProps: const MenuProps(backgroundColor: Colors.white),
itemBuilder:
(context, item, isSelected) => Container(
color: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 6,
),
child: Text(
item,
style: GoogleFonts.poppins(fontSize: 11.5),
),
),
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
hintText: "Search ...",
contentPadding: EdgeInsets.symmetric(horizontal: 10),
),
),
),
items: countryMap.values.toList(),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 1),
),
),
dropdownBuilder:
(context, selectedItem) => Align(
alignment: Alignment.centerLeft,
child: Text(
selectedItem ?? "Select ",
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
),
),
onChanged: (String? newValue) {
child: Focus(
focusNode: focusNodes["_countriesFocusNode"],
onFocusChange: (hasFocus) {
setState(() {
// Find the country_code based on selected country_name
selectedCountry =
countryMap.entries
.firstWhere((entry) => entry.value == newValue)
.key;
_onCountryChanged(selectedCountry);
focusStates["_countriesFocused"] = hasFocus;
});
},
child: GestureDetector(
//
onTap: () {
// Request focus when user taps
focusNodes["_countriesFocusNode"]?.requestFocus();
},
child: DropdownSearch<String>(
selectedItem: countryMap[selectedCountry],
popupProps: PopupProps.menu(
showSearchBox: true,
fit: FlexFit.loose,
constraints: BoxConstraints(maxHeight: 250),
menuProps: const MenuProps(
backgroundColor: Colors.white,
),
itemBuilder:
(context, item, isSelected) => Container(
color: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 6,
),
child: Text(
item,
style: GoogleFonts.poppins(fontSize: 11.5),
),
),
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
hintText: "Search ...",
contentPadding: EdgeInsets.symmetric(
horizontal: 10,
),
),
),
),
items: countryMap.values.toList(),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 1),
),
),
dropdownBuilder:
(context, selectedItem) => Align(
alignment: Alignment.centerLeft,
child: Text(
selectedItem ?? "Select ",
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
),
),
onChanged: (String? newValue) {
setState(() {
// Find the country_code based on selected country_name
selectedCountry =
countryMap.entries
.firstWhere(
(entry) => entry.value == newValue,
)
.key;
_onCountryChanged(selectedCountry);
});
},
),
),
),
),
),

View File

@ -4,6 +4,7 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:responsive_builder/responsive_builder.dart';
import '../../utils/auth_utils.dart';
import '../../widgets/custom_text_field.dart';
import '../../widgets/custom_text_itnerary_sub.dart';
@ -53,6 +54,8 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
late TextEditingController _nomineerelationController =
TextEditingController();
Color layoutColor = Colors.grey;
bool _isHotelNameFocused = false;
bool _startDateFocus = false;
bool _endDateFocus = false;
@ -63,6 +66,18 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
String? selectedInsuranceType;
Map<String, String> errorMessages = {};
Map<String, FocusNode> focusNodes = {};
Map<String, bool> focusStates = {};
List<String> dataHeader = [
"type_of_insurance",
"start_date",
"end_date",
"comments",
"nominee_name",
"nominee_dob",
"nominee_relationship",
];
Map<String, dynamic> get InsuranceData {
Map<String, dynamic> data = {
@ -94,33 +109,27 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
loadInitialData();
});
focusNodes.clear();
focusStates.clear();
_hotelNameFocusNode.addListener(() {
setState(() {
_isHotelNameFocused = _hotelNameFocusNode.hasFocus;
});
});
_endDateFocusNode.addListener(() {
setState(() {
_endDateFocus = _endDateFocusNode.hasFocus;
});
});
_startDateFocusNode.addListener(() {
setState(() {
_startDateFocus = _startDateFocusNode.hasFocus;
});
});
_commentsFocusNode.addListener(() {
setState(() {
_commentsFocus = _commentsFocusNode.hasFocus;
});
});
// Initialize fields dynamically
for (var field in dataHeader) {
focusNodes["${field}FocusNode"] = FocusNode();
focusStates["${field}Focused"] = false;
}
_nomineeFocusNode.addListener(() {
setState(() {
_nomineeFocus = _nomineeFocusNode.hasFocus;
for (var key in focusNodes.keys) {
_addFocusListener(focusNodes[key]!, (focus) {
setState(() {
focusStates[key.replaceFirst("FocusNode", "Focused")] = focus;
});
});
});
}
print("Focus Nodes Keys: ${focusNodes.keys.toList()}");
print("Focus States Keys: ${focusStates.keys.toList()}");
_insuranceCommentsController = TextEditingController(
text: widget.selectedItem?["comments"] ?? "",
@ -181,6 +190,16 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
});
}
void loadInitialData() async {
String? layoutString = await getLayoutColor();
setState(() {
layoutColor =
layoutString != null
? Color(int.parse(layoutString))
: Colors.redAccent;
});
}
Map<String, String?> getFlightTripDateRange(
List<Map<String, dynamic>> flightData,
) {
@ -285,6 +304,11 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
@override
void dispose() {
// Dispose all dynamically created FocusNodes
for (var node in focusNodes.values) {
node.dispose();
}
_tripTypeFocusNode.dispose();
_tripTypeController.dispose();
_startDateController.dispose();
@ -769,7 +793,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
// ),
// Dropdown Wrapper
CustomTextFieldWrapper(
isFocused: _isHotelNameFocused,
// isFocused: _isHotelNameFocused,
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: isDesktop,
width: isDesktop ? MediaQuery.of(context).size.width * 0.31 : null,
child: SizedBox(
@ -802,14 +828,45 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
);
},
),
dropdownDecoratorProps: const DropDownDecoratorProps(
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(
// border: InputBorder.none, // No underline
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(focusStates["type_of_insuranceFocusNode"] ?? false)
? layoutColor!
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(focusStates["type_of_insuranceFocusNode"] ?? false)
? layoutColor!
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: layoutColor!, width: 1),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
vertical: 5,
),
),
// dropdownSearchDecoration: InputDecoration(
// border: InputBorder.none,
// contentPadding: EdgeInsets.symmetric(
// horizontal: 10,
// vertical: 10,
// ),
// ),
),
dropdownBuilder: (context, selectedItem) {
if (selectedItem == null || selectedItem.isEmpty) {
@ -897,13 +954,15 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
),
SizedBox(height: 5),
CustomTextFieldWrapper(
isFocused: _startDateFocus,
// isFocused: _startDateFocus,
isFocused: focusStates["start_dateFocused"] ?? false,
isDesktop: isDesktop,
width: isDesktop ? MediaQuery.of(context).size.width * 0.16 : null,
child: SizedBox(
height: 40,
child: GestureDetector(
onTap: () async {
focusNodes["start_dateFocusNode"]?.requestFocus();
await _selectCheckOutDate(context);
if (_startDateController.text.isNotEmpty) {
setState(() {
@ -915,7 +974,8 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
},
child: AbsorbPointer(
child: TextField(
focusNode: _startDateFocusNode,
// focusNode: _startDateFocusNode,
focusNode: focusNodes["start_dateFocusNode"],
controller: _startDateController,
readOnly: true,
style: const TextStyle(fontSize: 12),
@ -956,13 +1016,14 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
),
SizedBox(height: 5),
CustomTextFieldWrapper(
isFocused: _endDateFocus,
isFocused: focusStates["end_dateFocused"] ?? false,
isDesktop: isDesktop,
width: isDesktop ? MediaQuery.of(context).size.width * 0.16 : null,
child: SizedBox(
height: 40,
child: GestureDetector(
onTap: () async {
focusNodes["end_dateFocusNode"]?.requestFocus();
await _selectEndCheckOutDate(context);
if (_endDateController.text.isNotEmpty) {
@ -985,7 +1046,8 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
},
child: AbsorbPointer(
child: TextField(
focusNode: _endDateFocusNode,
// focusNode: _endDateFocusNode,
focusNode: focusNodes["end_dateFocusNode"],
controller: _endDateController,
readOnly: true,
style: const TextStyle(fontSize: 12),
@ -1108,7 +1170,8 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
),
SizedBox(height: 5),
CustomTextFieldWrapper(
isFocused: _nomineeFocus,
// isFocused: _nomineeFocus,
isFocused: focusStates["nominee_nameFocused"] ?? false,
isDesktop: isDesktop,
// width: isDesktop ? MediaQuery.of(context).size.width * 0.15 : null,
width: isDesktop ? MediaQuery.of(context).size.width * 0.31 : null,
@ -1116,7 +1179,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
child: SizedBox(
height: 40,
child: TextField(
focusNode: _nomineeFocusNode,
focusNode: focusNodes["nominee_nameFocusNode"],
// focusNode: _nomineeFocusNode,
controller: _nomineeController,
style: TextStyle(fontSize: 12),
decoration: InputDecoration(
@ -1150,7 +1215,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
),
SizedBox(height: 5),
CustomTextFieldWrapper(
isFocused: _startDateFocus,
isFocused: focusStates["nominee_dobFocused"] ?? false,
isDesktop: isDesktop,
width: isDesktop ? MediaQuery.of(context).size.width * 0.16 : null,
// width: isDesktop ? MediaQuery.of(context).size.width * 0.11 : null,
@ -1158,6 +1223,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
height: 40,
child: GestureDetector(
onTap: () async {
focusNodes["nominee_dobFocusNode"]?.requestFocus();
await _selectCheckDOBOutDate(context);
// await _selectDateOfBirth(context);
if (_dateOfBirthController.text.isNotEmpty) {
@ -1170,7 +1236,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
},
child: AbsorbPointer(
child: TextField(
focusNode: _startDateFocusNode,
focusNode: focusNodes["nominee_dobFocusNode"],
controller: _dateOfBirthController,
readOnly: true,
style: const TextStyle(fontSize: 12),
@ -1213,7 +1279,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
//
CustomTextFieldWrapper(
isFocused: false,
isFocused: focusStates["nominee_relationshipFocused"] ?? false,
isDesktop: isDesktop,
width: isDesktop ? MediaQuery.of(context).size.width * 0.16 : null,
// width: isDesktop ? MediaQuery.of(context).size.width * 0.31 : null,
@ -1221,7 +1287,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
child: SizedBox(
height: 40,
child: TextField(
// focusNode: _nomineeFocusNode,
focusNode: focusNodes["nominee_relationshipFocusNode"],
controller: _nomineerelationController,
style: TextStyle(fontSize: 12),
decoration: InputDecoration(
@ -1260,7 +1326,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
),
SizedBox(height: 5),
CustomTextFieldWrapper(
isFocused: _commentsFocus, // Dropdown doesn't use focus
isFocused:
focusStates["commentsFocused"] ??
false, // Dropdown doesn't use focus
isDesktop: isDesktop,
width:
isDesktop
@ -1269,7 +1337,8 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
child: SizedBox(
height: 40,
child: TextField(
focusNode: _commentsFocusNode,
// focusNode: _commentsFocusNode,
focusNode: focusNodes["commentsFocusNode"],
controller: _insuranceCommentsController,
style: TextStyle(fontSize: 12),
decoration: InputDecoration(

View File

@ -389,6 +389,8 @@ class CreateNewPlansState extends State<CreateNewPlan> {
// bool _isdescriptionFocused = false;
// bool _isTripTitleFocused = false;
Color? layoutColor;
late String _selectedOption = "Option 1";
// late String? _selectedIsBillable = "Billable";
@ -537,6 +539,9 @@ class CreateNewPlansState extends State<CreateNewPlan> {
void initState() {
super.initState();
print("approverStatus - ${widget.approverStatus}");
WidgetsBinding.instance.addPostFrameCallback((_) {
loadInitialData();
});
if (widget.approverStatus == "Approval pending") {
print("Status approver - Approval Pending");
@ -580,6 +585,17 @@ class CreateNewPlansState extends State<CreateNewPlan> {
handleUpdateData();
}
void loadInitialData() async {
String? layoutString = await getLayoutColor();
setState(() {
layoutColor =
layoutString != null
? Color(int.parse(layoutString))
: Colors.redAccent;
});
}
@override
void dispose() {
for (var node in focusNodes.values) {
@ -1332,22 +1348,22 @@ class CreateNewPlansState extends State<CreateNewPlan> {
if (response.statusCode == 200) {
print("Plan submitted successfully!");
print("Response: ${response.body}");
final currentUri =
GoRouterState.of(
context,
).uri.toString(); // safer than `.location`
print("currentUri - $currentUri");
if (currentUri == "/allTrips/trips") {
context.go('/listAllPlan');
} else if (currentUri == "/createPlan") {
context.go('/listPlan');
} else {
widget.isApprover
? context.go('/approvallist')
: context.go('/listPlan');
}
//
// final currentUri =
// GoRouterState.of(
// context,
// ).uri.toString(); // safer than `.location`
// print("currentUri - $currentUri");
//
// if (currentUri == "/allTrips/trips") {
// context.go('/listAllPlan');
// } else if (currentUri == "/createPlan") {
// context.go('/listPlan');
// } else {
// widget.isApprover
// ? context.go('/approvallist')
// : context.go('/listPlan');
// }
} else {
print("Failed to submit plan. Status: ${response.statusCode}");
print("Error: ${response.body}");
@ -1804,10 +1820,13 @@ class CreateNewPlansState extends State<CreateNewPlan> {
SizedBox(height: 5),
CustomTextFieldWrapper(
isFocused: focusStates["trip_typeFocused"] ?? false,
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
// isFocused: focusStates["trip_typeFocused"] ?? false,
isDesktop: widget.isDesktop,
child: SizedBox(
height: 35,
// width: double.infinity,
width: double.infinity,
child: Focus(
focusNode: focusNodes["trip_typeFocusNode"],
@ -1825,7 +1844,9 @@ class CreateNewPlansState extends State<CreateNewPlan> {
popupProps: PopupProps.menu(
showSearchBox: false, // Optionally enable search
fit: FlexFit.loose,
menuProps: const MenuProps(backgroundColor: Colors.white),
itemBuilder: (context, item, isSelected) {
return Padding(
padding: const EdgeInsets.symmetric(
@ -1842,16 +1863,42 @@ class CreateNewPlansState extends State<CreateNewPlan> {
);
},
),
dropdownDecoratorProps: const DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none, // No underline
contentPadding: EdgeInsets.symmetric(
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
// border: InputBorder.none, // No underline
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(focusStates["trip_typeFocused"] ?? false)
? layoutColor!
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(focusStates["trip_typeFocused"] ?? false)
? layoutColor!
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: layoutColor!, width: 1),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
),
),
dropdownBuilder: (context, selectedItem) {
if (selectedItem == null || selectedItem.isEmpty) {
return Text(
@ -1951,7 +1998,9 @@ class CreateNewPlansState extends State<CreateNewPlan> {
SizedBox(height: 5),
CustomTextFieldWrapper(
isFocused: focusStates["is_billableFocused"] ?? false,
// isFocused: focusStates["is_billableFocused"] ?? false,
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
width:
widget.isDesktop
? MediaQuery.of(context).size.width * 0.2
@ -1994,10 +2043,33 @@ class CreateNewPlansState extends State<CreateNewPlan> {
);
},
),
dropdownDecoratorProps: const DropDownDecoratorProps(
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(focusStates["is_billableFocused"] ?? false)
? layoutColor!
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(focusStates["is_billableFocused"] ?? false)
? layoutColor!
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: layoutColor!, width: 1),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
@ -2225,9 +2297,10 @@ class CreateNewPlansState extends State<CreateNewPlan> {
),
SizedBox(height: 5),
CustomTextFieldWrapper(
isFocused:
focusStates["cost_center_idFocused"] ??
false, // Dropdown doesn't use focus
// isFocused: focusStates["cost_center_idFocused"] ??
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: widget.isDesktop,
child: SizedBox(
height: 35,
@ -2242,6 +2315,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
)
: Focus(
focusNode: focusNodes["cost_center_idFocusNode"],
onFocusChange: (hasFocus) {
setState(() {
focusStates["cost_center_idFocused"] = hasFocus;
@ -2295,7 +2369,35 @@ class CreateNewPlansState extends State<CreateNewPlan> {
items: costCenterMap.values.toList(), // just names
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(focusStates["cost_center_idFocused"] ??
false)
? layoutColor!
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(focusStates["cost_center_idFocused"] ??
false)
? layoutColor!
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: layoutColor!,
width: 1,
),
),
// contentPadding: EdgeInsets.symmetric(horizontal: 1),
contentPadding: EdgeInsets.symmetric(
horizontal: 10,
@ -2400,7 +2502,9 @@ class CreateNewPlansState extends State<CreateNewPlan> {
isDesktop
? MediaQuery.of(context).size.width * 0.2
: MediaQuery.of(context).size.width * 0.88,
isFocused: focusStates["purpose_of_travelFocused"] ?? false,
// isFocused: focusStates["purpose_of_travelFocused"] ?? false,
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: widget.isDesktop,
child: SizedBox(
@ -2472,11 +2576,39 @@ class CreateNewPlansState extends State<CreateNewPlan> {
),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(focusStates["purpose_of_travelFocused"] ??
false)
? layoutColor!
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(focusStates["purpose_of_travelFocused"] ??
false)
? layoutColor!
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: layoutColor!,
width: 1,
),
),
contentPadding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
border: InputBorder.none,
),
),
onChanged:
@ -2582,7 +2714,9 @@ class CreateNewPlansState extends State<CreateNewPlan> {
),
SizedBox(height: 5),
CustomTextFieldWrapper(
isFocused: focusStates["functional_departmentFocused"] ?? false,
// isFocused: focusStates["functional_departmentFocused"] ?? false,
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: widget.isDesktop,
width:
isDesktop
@ -2666,7 +2800,35 @@ class CreateNewPlansState extends State<CreateNewPlan> {
horizontal: 10,
vertical: 5,
),
border: InputBorder.none,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(focusStates["functional_departmentFocused"] ??
false)
? layoutColor!
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(focusStates["functional_departmentFocused"] ??
false)
? layoutColor!
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: layoutColor!,
width: 1,
),
),
),
),
onChanged:
@ -2737,8 +2899,9 @@ class CreateNewPlansState extends State<CreateNewPlan> {
return [
CustomTextFieldWrapper(
isFocused: focusStates["trip_plannedFocused"] ?? false,
// isFocused: focusStates["trip_plannedFocused"] ?? false,
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: isDesktop,
layoutColor: widget.layoutColor,
child: SizedBox(
@ -2766,6 +2929,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
popupProps: PopupProps.menu(
showSearchBox: false,
menuProps: const MenuProps(backgroundColor: Colors.white),
constraints: BoxConstraints(maxHeight: 100),
itemBuilder:
(context, item, isSelected) => Padding(
@ -2781,7 +2945,31 @@ class CreateNewPlansState extends State<CreateNewPlan> {
),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(focusStates["trip_typeFocused"] ?? false)
? layoutColor!
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(focusStates["trip_plannedFocused"] ?? false)
? layoutColor!
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: layoutColor!, width: 1),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,

View File

@ -2,7 +2,7 @@ import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
// import 'package:flutter/rendering.dart';
import 'dart:html' as html;
import 'package:frontend/config/apiUrl.dart'; // 1 newly added
import 'package:frontend/services/apiService.dart';
@ -31,7 +31,7 @@ class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
SemanticsBinding.instance.ensureSemantics(); // Safe here
// SemanticsBinding.instance.ensureSemantics(); // Safe here
if (kIsWeb) {
final uri = Uri.parse(html.window.location.href);
print("URI - $uri");

View File

@ -1,3 +1,3 @@
//api url
const String apiUrl = 'http://apitest.tripapprovaltool.com/tstat_be';
// const String apiUrl = 'https://uat.tripapprovaltool.com/tstat_be';
// const String apiUrl = 'http://apitest.tripapprovaltool.com/tstat_be';
const String apiUrl = 'https://uat.tripapprovaltool.com/tstat_be';

View File

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:frontend/Screens/authentication/login/login_page.dart';
import 'package:frontend/Screens/authentication/loginPage1.dart';
import 'package:frontend/Screens/dashboard/home_page.dart';
import 'package:frontend/Screens/forex/forex_list.dart';
import 'package:frontend/Screens/myTemplates/templatesList.dart';
import 'package:frontend/Screens/organization/orgSetup.dart';
import 'package:frontend/Screens/organization/org_List.dart';
@ -26,6 +25,7 @@ import '../Screens/group/groupList.dart';
import '../Screens/myTemplates/template.dart';
import '../Screens/myTemplates/templateForex.dart';
import '../Screens/myTemplates/templateTest.dart';
import '../Screens/perdiem_amount/forex_list.dart';
import '../Screens/userManagement/create_user/create_user.dart';
import '../Screens/department/department_list.dart';
import '../Screens/costCenter/costCenter_list.dart';
@ -150,10 +150,7 @@ final GoRouter router = GoRouter(
pageBuilder:
(context, state) => MaterialPage(child: Group.fromState(state)),
),
GoRoute(
path: '/report',
builder: (context, state) => ReportList(),
),
GoRoute(path: '/report', builder: (context, state) => ReportList()),
GoRoute(
path: '/advancePurchase',
builder: (context, state) => AdvancePurchase(),
@ -162,10 +159,7 @@ final GoRouter router = GoRouter(
path: '/misservicesAnalysis',
builder: (context, state) => ServicesAnalysis(),
),
GoRoute(
path: '/misAirReport',
builder: (context, state) => MISair(),
),
GoRoute(path: '/misAirReport', builder: (context, state) => MISair()),
GoRoute(
path: '/misHotelReport',
builder: (context, state) => MIShotel(),

View File

@ -85,19 +85,20 @@ class _CustomTextFieldWrapperState extends State<CustomTextFieldWrapper> {
// color: widget.isFocused ? Color(0xFF78B4FC) : Color(0xFFD6D5E6),
width: widget.isFocused ? 1.0 : 0.5,
),
// boxShadow: widget.isFocused
// ? [
// BoxShadow(
// // color: Color.fromRGBO(120, 180, 252, 0.3),
// // color: widget.isFocused
// // ? (widget.layoutColor ?? Colors.red).withAlpha(204)
// // : Color(0xFFF5F5F5),
// blurRadius: 10,
// spreadRadius: 1,
// offset: Offset(0, 4),
// ),
// ]
// : [],
// boxShadow:
// widget.isFocused
// ? [
// BoxShadow(
// color: widget.isFocused ? layoutColor! : Color(0xFFD6D5E6),
// // color: widget.isFocused
// // ? (widget.layoutColor ?? Colors.red).withAlpha(204)
// // : Color(0xFFF5F5F5),
// blurRadius: 10,
// spreadRadius: 1,
// offset: Offset(0, 4),
// ),
// ]
// : [],
),
child: widget.child,
);