trip highlighter
This commit is contained in:
parent
691ba181c6
commit
7f897a7296
@ -415,8 +415,9 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
// fit: BoxFit.contain,
|
||||
// ),
|
||||
Container(
|
||||
width: 200, // Optional: control size
|
||||
height: 100,
|
||||
// color: Colors.yellow,
|
||||
width: 120, // Optional: control size
|
||||
height: 200,
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
|
||||
@ -988,64 +988,80 @@ class FlightScreenState extends State<FlightScreen> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
child: DropdownSearch<String>(
|
||||
items:
|
||||
purposeList
|
||||
.map((item) => item['dropdown_value'] as String)
|
||||
.toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 1),
|
||||
),
|
||||
),
|
||||
onChanged: (newValue) {
|
||||
child: Focus(
|
||||
focusNode: focusNodes["_tripType1FocusNode"],
|
||||
onFocusChange: (hasFocus) {
|
||||
setState(() {
|
||||
selectedTripType = newValue;
|
||||
if (selectedTripType != "Multitrip") {
|
||||
multiTripRowCount = 1;
|
||||
}
|
||||
errorMessages.clear();
|
||||
|
||||
for (int i = 1; i <= rowCount; i++) {
|
||||
textControllers["_date${i}Controller"]?.clear();
|
||||
textControllers["_time${i}Controller"]?.clear();
|
||||
|
||||
// Also clear the actual selected data (not just the text in controllers)
|
||||
selectedFrom[i] = null; // Assuming null means no selection
|
||||
selectedTo[i] = null;
|
||||
}
|
||||
focusStates["_tripType1Focused"] = hasFocus;
|
||||
});
|
||||
print(
|
||||
"Updating form data: Flight -> trip_type -> $selectedTripType",
|
||||
);
|
||||
_initializeFields();
|
||||
},
|
||||
selectedItem: selectedTripType,
|
||||
dropdownBuilder:
|
||||
(context, selectedItem) => Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select",
|
||||
style: TextStyle(fontSize: 12),
|
||||
child: GestureDetector(
|
||||
//
|
||||
onTap: () {
|
||||
// Request focus when user taps
|
||||
focusNodes["_tripType1FocusNode"]?.requestFocus();
|
||||
},
|
||||
child: DropdownSearch<String>(
|
||||
items:
|
||||
purposeList
|
||||
.map((item) => item['dropdown_value'] as String)
|
||||
.toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 1),
|
||||
),
|
||||
),
|
||||
popupProps: PopupProps.menu(
|
||||
constraints: BoxConstraints(maxHeight: 100),
|
||||
menuProps: MenuProps(backgroundColor: Colors.white),
|
||||
itemBuilder:
|
||||
(context, item, isSelected) => Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
vertical: 6.0,
|
||||
onChanged: (newValue) {
|
||||
setState(() {
|
||||
selectedTripType = newValue;
|
||||
if (selectedTripType != "Multitrip") {
|
||||
multiTripRowCount = 1;
|
||||
}
|
||||
errorMessages.clear();
|
||||
|
||||
for (int i = 1; i <= rowCount; i++) {
|
||||
textControllers["_date${i}Controller"]?.clear();
|
||||
textControllers["_time${i}Controller"]?.clear();
|
||||
|
||||
// Also clear the actual selected data (not just the text in controllers)
|
||||
selectedFrom[i] =
|
||||
null; // Assuming null means no selection
|
||||
selectedTo[i] = null;
|
||||
}
|
||||
});
|
||||
print(
|
||||
"Updating form data: Flight -> trip_type -> $selectedTripType",
|
||||
);
|
||||
_initializeFields();
|
||||
},
|
||||
selectedItem: selectedTripType,
|
||||
dropdownBuilder:
|
||||
(context, selectedItem) => Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select",
|
||||
style: TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
item,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
), // Custom text size for dropdown items
|
||||
),
|
||||
),
|
||||
popupProps: PopupProps.menu(
|
||||
constraints: BoxConstraints(maxHeight: 100),
|
||||
menuProps: MenuProps(backgroundColor: Colors.white),
|
||||
itemBuilder:
|
||||
(context, item, isSelected) => Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
vertical: 6.0,
|
||||
),
|
||||
child: Text(
|
||||
item,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
), // Custom text size for dropdown items
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -1419,156 +1435,180 @@ class FlightScreenState extends State<FlightScreen> {
|
||||
child:
|
||||
isCountryLoading
|
||||
? Center(child: CircularProgressIndicator())
|
||||
: DropdownSearch<String>(
|
||||
enabled:
|
||||
!(selectedTripType == "Roundtrip" && index == 2),
|
||||
selectedItem:
|
||||
selectedFrom[index] != null
|
||||
? countryMap[selectedFrom[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["_from${index}FocusNode"],
|
||||
onFocusChange: (hasFocus) {
|
||||
setState(() {
|
||||
focusStates["_from${index}Focused"] = hasFocus;
|
||||
});
|
||||
},
|
||||
child: GestureDetector(
|
||||
//
|
||||
onTap: () {
|
||||
// Request focus when user taps
|
||||
focusNodes["_from${index}FocusNode"]
|
||||
?.requestFocus();
|
||||
},
|
||||
child: DropdownSearch<String>(
|
||||
enabled:
|
||||
!(selectedTripType == "Roundtrip" &&
|
||||
index == 2),
|
||||
selectedItem:
|
||||
selectedFrom[index] != null
|
||||
? countryMap[selectedFrom[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: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 1),
|
||||
// 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) {
|
||||
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),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
// dropdownBuilder:
|
||||
// (context, selectedItem) => Align(
|
||||
// alignment: Alignment.centerLeft,
|
||||
// child: Text(
|
||||
// selectedItem ?? "Select",
|
||||
// style: TextStyle(fontSize: 12),
|
||||
// ),
|
||||
// ),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
errorMessages.remove("from_place_$index");
|
||||
// selectedFrom[index] = countryMap.entries
|
||||
// .firstWhere((entry) => entry.value == newValue)
|
||||
// .key;
|
||||
|
||||
selectedFrom[index] =
|
||||
countryMap.entries
|
||||
.firstWhere(
|
||||
(entry) => entry.value == newValue,
|
||||
)
|
||||
.key;
|
||||
|
||||
if (selectedTripType == "Roundtrip") {
|
||||
print('rounfTo${selectedFrom[index]}');
|
||||
// textControllers["_to${index+1}Controller"]?.text = selectedFrom[index]!;
|
||||
selectedTo[2] = selectedFrom[index]!;
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
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),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
// dropdownBuilder:
|
||||
// (context, selectedItem) => Align(
|
||||
// alignment: Alignment.centerLeft,
|
||||
// child: Text(
|
||||
// selectedItem ?? "Select",
|
||||
// style: TextStyle(fontSize: 12),
|
||||
// ),
|
||||
// ),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
errorMessages.remove("from_place_$index");
|
||||
// selectedFrom[index] = countryMap.entries
|
||||
// .firstWhere((entry) => entry.value == newValue)
|
||||
// .key;
|
||||
|
||||
selectedFrom[index] =
|
||||
countryMap.entries
|
||||
.firstWhere(
|
||||
(entry) => entry.value == newValue,
|
||||
)
|
||||
.key;
|
||||
|
||||
if (selectedTripType == "Roundtrip") {
|
||||
print('rounfTo${selectedFrom[index]}');
|
||||
// textControllers["_to${index+1}Controller"]?.text = selectedFrom[index]!;
|
||||
selectedTo[2] = selectedFrom[index]!;
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
@ -1941,6 +1981,7 @@ class FlightScreenState extends State<FlightScreen> {
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: focusStates["_date${index}Focused"] ?? false,
|
||||
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.11 : null,
|
||||
child: SizedBox(
|
||||
@ -1994,7 +2035,7 @@ class FlightScreenState extends State<FlightScreen> {
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: focusStates["_timeFocused"] ?? false,
|
||||
isFocused: focusStates["_time${index}Focused"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.1 : null,
|
||||
child: SizedBox(
|
||||
@ -2013,6 +2054,7 @@ class FlightScreenState extends State<FlightScreen> {
|
||||
); // ✅ Force rebuild to show the error immediately
|
||||
});
|
||||
},
|
||||
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_time${index}FocusNode"],
|
||||
@ -2034,6 +2076,19 @@ class FlightScreenState extends State<FlightScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
// Focus(
|
||||
// focusNode: focusNodes["_time${index}FocusNode"],
|
||||
// onFocusChange: (hasFocus) {
|
||||
// setState(() {
|
||||
// focusStates["_time${index}Focused"] = hasFocus;
|
||||
// });
|
||||
// },
|
||||
// child: GestureDetector(
|
||||
// //
|
||||
// onTap: () {
|
||||
// // Request focus when user taps
|
||||
// focusNodes["_time${index}FocusNode"]?.requestFocus();
|
||||
// },
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -34,10 +34,10 @@ class _MailSettingState extends State<MailSetting> {
|
||||
List<String> dataHeader = [
|
||||
"host",
|
||||
"userName",
|
||||
"password",
|
||||
"mail_password",
|
||||
"port",
|
||||
"senderEmail",
|
||||
"toEmail"
|
||||
"toEmail",
|
||||
];
|
||||
|
||||
Map<String, dynamic> getMailData() => mailData;
|
||||
@ -46,7 +46,7 @@ class _MailSettingState extends State<MailSetting> {
|
||||
final data = {
|
||||
"mail_host": controllers["host"]?.text,
|
||||
"mail_user_name": controllers["userName"]?.text,
|
||||
"mail_password": controllers["password"]?.text,
|
||||
"mail_password": controllers["mail_password"]?.text,
|
||||
"mail_port": controllers["port"]?.text,
|
||||
"sender_email": controllers["senderEmail"]?.text,
|
||||
"to_mail": controllers["toEmail"]?.text,
|
||||
@ -97,7 +97,7 @@ class _MailSettingState extends State<MailSetting> {
|
||||
widget.initialMailData['sender_email'] ?? '';
|
||||
controllers["userName"]?.text =
|
||||
widget.initialMailData['mail_user_name'] ?? '';
|
||||
controllers["password"]?.text =
|
||||
controllers["mail_password"]?.text =
|
||||
widget.initialMailData['mail_password'] ?? '';
|
||||
controllers["host"]?.text = widget.initialMailData['mail_host'] ?? '';
|
||||
controllers["port"]?.text =
|
||||
@ -181,8 +181,9 @@ class _MailSettingState extends State<MailSetting> {
|
||||
|
||||
// Email validation
|
||||
if (data["to_mail"] != null && data["to_mail"].toString().isNotEmpty) {
|
||||
if (!RegExp(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
|
||||
.hasMatch(data["to_mail"].toString())) {
|
||||
if (!RegExp(
|
||||
r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$",
|
||||
).hasMatch(data["to_mail"].toString())) {
|
||||
errorMessages["to_mail"] =
|
||||
"Invalid email format"; // Invalid email format
|
||||
}
|
||||
@ -191,8 +192,9 @@ class _MailSettingState extends State<MailSetting> {
|
||||
// Email validation
|
||||
if (data["sender_email"] != null &&
|
||||
data["sender_email"].toString().isNotEmpty) {
|
||||
if (!RegExp(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
|
||||
.hasMatch(data["sender_email"].toString())) {
|
||||
if (!RegExp(
|
||||
r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$",
|
||||
).hasMatch(data["sender_email"].toString())) {
|
||||
errorMessages["sender_email"] =
|
||||
"Invalid email format"; // Invalid email format
|
||||
}
|
||||
@ -226,17 +228,19 @@ class _MailSettingState extends State<MailSetting> {
|
||||
Text(
|
||||
"Sender Email",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
width: widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
width:
|
||||
widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
@ -249,8 +253,8 @@ class _MailSettingState extends State<MailSetting> {
|
||||
if (value.trim().isEmpty) {
|
||||
errorMessages["sender_email"] = "Required";
|
||||
} else if (!RegExp(
|
||||
r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
|
||||
.hasMatch(value)) {
|
||||
r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$",
|
||||
).hasMatch(value)) {
|
||||
errorMessages["sender_email"] =
|
||||
"Invalid email format";
|
||||
}
|
||||
@ -259,7 +263,9 @@ class _MailSettingState extends State<MailSetting> {
|
||||
decoration: InputDecoration(
|
||||
labelText: "sender email",
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12, color: Colors.grey),
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
@ -278,36 +284,28 @@ class _MailSettingState extends State<MailSetting> {
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
|
||||
widget.isDesktop
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: _buildMailFirstRow(widget.isDesktop),
|
||||
)
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: _buildMailFirstRow(widget.isDesktop),
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: _buildMailFirstRow(widget.isDesktop),
|
||||
),
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: _buildMailFirstRow(widget.isDesktop),
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
|
||||
widget.isDesktop
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: _buildMailSecondRow(widget.isDesktop),
|
||||
)
|
||||
: Column(
|
||||
children: _buildMailSecondRow(widget.isDesktop),
|
||||
),
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: _buildMailSecondRow(widget.isDesktop),
|
||||
)
|
||||
: Column(children: _buildMailSecondRow(widget.isDesktop)),
|
||||
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
|
||||
Container(
|
||||
// color: Color(0xFFF7F7FB),
|
||||
@ -317,7 +315,9 @@ class _MailSettingState extends State<MailSetting> {
|
||||
Text(
|
||||
"Test Mail",
|
||||
style: GoogleFonts.poppins(
|
||||
color: Color(0xFF114D8B), fontWeight: FontWeight.w600),
|
||||
color: Color(0xFF114D8B),
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -327,7 +327,7 @@ class _MailSettingState extends State<MailSetting> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: _buildTestMail(widget.isDesktop),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -342,17 +342,19 @@ class _MailSettingState extends State<MailSetting> {
|
||||
Text(
|
||||
"User Name",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
width: widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
width:
|
||||
widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
@ -364,8 +366,10 @@ class _MailSettingState extends State<MailSetting> {
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "user name",
|
||||
labelStyle:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
@ -388,47 +392,56 @@ class _MailSettingState extends State<MailSetting> {
|
||||
Text(
|
||||
"Password",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
width: widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
width:
|
||||
widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
// focusNode: _destinationFocusNode,
|
||||
controller: controllers["password"],
|
||||
controller: controllers["mail_password"],
|
||||
onChanged: (value) {
|
||||
_clearError("mail_password");
|
||||
},
|
||||
obscureText: _obscurePassword,
|
||||
// obscureText: _obscurePassword,
|
||||
autofillHints: const [
|
||||
// AutofillHints.newPassword,
|
||||
], // <--- This is key
|
||||
enableSuggestions: false, // <--- Disable suggestions
|
||||
autocorrect: false,
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "password",
|
||||
labelStyle:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
labelText: "Access Key",
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(
|
||||
_obscurePassword
|
||||
? Icons.visibility_off
|
||||
: Icons.visibility,
|
||||
size: 16,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_obscurePassword = !_obscurePassword;
|
||||
});
|
||||
},
|
||||
),
|
||||
// suffixIcon: IconButton(
|
||||
// icon: Icon(
|
||||
// _obscurePassword
|
||||
// ? Icons.visibility_off
|
||||
// : Icons.visibility,
|
||||
// size: 16,
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// setState(() {
|
||||
// _obscurePassword = !_obscurePassword;
|
||||
// });
|
||||
// },
|
||||
// ),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -453,17 +466,19 @@ class _MailSettingState extends State<MailSetting> {
|
||||
Text(
|
||||
"Host",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
width: widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
width:
|
||||
widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
@ -475,8 +490,10 @@ class _MailSettingState extends State<MailSetting> {
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "host",
|
||||
labelStyle:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
@ -499,17 +516,19 @@ class _MailSettingState extends State<MailSetting> {
|
||||
Text(
|
||||
"Port",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
width: widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
width:
|
||||
widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
@ -521,8 +540,10 @@ class _MailSettingState extends State<MailSetting> {
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "port",
|
||||
labelStyle:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
@ -550,17 +571,19 @@ class _MailSettingState extends State<MailSetting> {
|
||||
Text(
|
||||
"Enter Your Mail Id",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
width: widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
width:
|
||||
widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
@ -573,16 +596,18 @@ class _MailSettingState extends State<MailSetting> {
|
||||
if (value.trim().isEmpty) {
|
||||
errorMessages["to_mail"] = "Required";
|
||||
} else if (!RegExp(
|
||||
r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
|
||||
.hasMatch(value)) {
|
||||
r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$",
|
||||
).hasMatch(value)) {
|
||||
errorMessages["to_mail"] = "Invalid email format";
|
||||
}
|
||||
},
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "To mail",
|
||||
labelStyle:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
@ -599,31 +624,28 @@ class _MailSettingState extends State<MailSetting> {
|
||||
],
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Column(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B), // Keep original color
|
||||
foregroundColor: Colors.white, // Keep original color
|
||||
disabledBackgroundColor:
|
||||
Color(0xFF114D8B), // Ensure color remains when disabled
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(horizontal: 18, vertical: 12),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B), // Keep original color
|
||||
foregroundColor: Colors.white, // Keep original color
|
||||
disabledBackgroundColor: Color(
|
||||
0xFF114D8B,
|
||||
), // Ensure color remains when disabled
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
onPressed: () {
|
||||
handleTestMailSubmit();
|
||||
},
|
||||
child: Text(
|
||||
"Test Email",
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
))
|
||||
padding: EdgeInsets.symmetric(horizontal: 18, vertical: 12),
|
||||
),
|
||||
onPressed: () {
|
||||
handleTestMailSubmit();
|
||||
},
|
||||
child: Text("Test Email", style: GoogleFonts.poppins(fontSize: 12)),
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frontend/utils/colorOpcity.dart';
|
||||
|
||||
import '../utils/auth_utils.dart';
|
||||
|
||||
class CustomTextFieldWrapper extends StatefulWidget {
|
||||
final Widget child;
|
||||
final bool isFocused;
|
||||
@ -30,6 +32,28 @@ class CustomTextFieldWrapper extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _CustomTextFieldWrapperState extends State<CustomTextFieldWrapper> {
|
||||
Color? layoutColor;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
loadInitialData();
|
||||
});
|
||||
}
|
||||
|
||||
void loadInitialData() async {
|
||||
String? layoutString = await getLayoutColor();
|
||||
|
||||
setState(() {
|
||||
layoutColor =
|
||||
layoutString != null
|
||||
? Color(int.parse(layoutString))
|
||||
: Colors.redAccent;
|
||||
});
|
||||
}
|
||||
|
||||
Color getColorWithOpacity(Color color, double opacity) {
|
||||
final int alpha = (opacity * 255).round().clamp(0, 255);
|
||||
return Color.fromARGB(
|
||||
@ -43,22 +67,23 @@ class _CustomTextFieldWrapperState extends State<CustomTextFieldWrapper> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: widget.width ?? // Use custom width if provided, else default
|
||||
width:
|
||||
widget.width ?? // Use custom width if provided, else default
|
||||
(widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.3
|
||||
: MediaQuery.of(context).size.width * 0.85),
|
||||
: MediaQuery.of(context).size.width * 0.88),
|
||||
padding: widget.padding,
|
||||
decoration: BoxDecoration(
|
||||
color: widget.isFocused
|
||||
? (widget.layoutColor ?? widget.color)
|
||||
: widget.color,
|
||||
// color: widget.isFocused
|
||||
// ? (widget.layoutColor ?? widget.color)
|
||||
// : widget.color,
|
||||
color: Colors.white,
|
||||
borderRadius: widget.borderRadius ?? BorderRadius.circular(8),
|
||||
|
||||
border: Border.all(
|
||||
color: widget.isFocused
|
||||
? (widget.layoutColor ?? Colors.blueAccent)
|
||||
: Color(0xFFF5F5F5),
|
||||
width: widget.isFocused ? 1.5 : 1.5,
|
||||
color: widget.isFocused ? layoutColor! : Color(0xFFD6D5E6),
|
||||
// color: widget.isFocused ? Color(0xFF78B4FC) : Color(0xFFD6D5E6),
|
||||
width: widget.isFocused ? 1.0 : 0.5,
|
||||
),
|
||||
// boxShadow: widget.isFocused
|
||||
// ? [
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../utils/auth_utils.dart';
|
||||
|
||||
class CustomTextFieldItnerarySubWrapper extends StatefulWidget {
|
||||
final Widget child;
|
||||
final bool isFocused;
|
||||
@ -21,36 +23,64 @@ class CustomTextFieldItnerarySubWrapper extends StatefulWidget {
|
||||
});
|
||||
|
||||
@override
|
||||
_CustomTextFieldItnerarySubWrapperState createState() => _CustomTextFieldItnerarySubWrapperState();
|
||||
_CustomTextFieldItnerarySubWrapperState createState() =>
|
||||
_CustomTextFieldItnerarySubWrapperState();
|
||||
}
|
||||
|
||||
class _CustomTextFieldItnerarySubWrapperState extends State<CustomTextFieldItnerarySubWrapper> {
|
||||
class _CustomTextFieldItnerarySubWrapperState
|
||||
extends State<CustomTextFieldItnerarySubWrapper> {
|
||||
Color? layoutColor;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
loadInitialData();
|
||||
});
|
||||
}
|
||||
|
||||
void loadInitialData() async {
|
||||
String? layoutString = await getLayoutColor();
|
||||
|
||||
setState(() {
|
||||
layoutColor =
|
||||
layoutString != null
|
||||
? Color(int.parse(layoutString))
|
||||
: Colors.redAccent;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: widget.width ?? // Use custom width if provided, else default
|
||||
width:
|
||||
widget.width ?? // Use custom width if provided, else default
|
||||
(widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.15
|
||||
: MediaQuery.of(context).size.width * 0.8),
|
||||
padding: widget.padding,
|
||||
decoration: BoxDecoration(
|
||||
color: widget.color,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(
|
||||
color: widget.isFocused ? Color(0xFF78B4FC) : Color(0xFFD6D5E6),
|
||||
width: widget.isFocused ? 2.0 : 0.5,
|
||||
),
|
||||
boxShadow: widget.isFocused
|
||||
? [
|
||||
BoxShadow(
|
||||
color: Color.fromRGBO(120, 180, 252, 0.3),
|
||||
blurRadius: 10,
|
||||
spreadRadius: 2,
|
||||
offset: Offset(0, 4),
|
||||
color: Colors.white,
|
||||
|
||||
),
|
||||
]
|
||||
: [],
|
||||
border: Border.all(
|
||||
color: widget.isFocused ? layoutColor! : Color(0xFFD6D5E6),
|
||||
// color: widget.isFocused ? Color(0xFF78B4FC) : Color(0xFFD6D5E6),
|
||||
width: widget.isFocused ? 1.0 : 0.5,
|
||||
),
|
||||
boxShadow:
|
||||
widget.isFocused
|
||||
? [
|
||||
BoxShadow(
|
||||
color: Colors.white,
|
||||
// color: Color.fromRGBO(120, 180, 252, 0.3),
|
||||
blurRadius: 10,
|
||||
spreadRadius: 2,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
]
|
||||
: [],
|
||||
),
|
||||
child: widget.child,
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user