Merge with old in branch 'main'

This commit is contained in:
venba-Inspriron-3558 2025-06-25 12:40:29 +05:30
commit c0ecff7697
5 changed files with 189 additions and 147 deletions

View File

@ -657,27 +657,28 @@ class FlightScreenState extends State<FlightScreen> {
Set<String?> seenFrom = {};
Set<String?> seenTo = {};
for (int i = 1; i <= rowCount; i++) {
final fromValue = selectedFrom[i];
final toValue = selectedTo[i];
if (fromValue != null) {
if (seenFrom.contains(fromValue)) {
errorMessages["from_place_$i"] = "Duplicate Departure ";
print("Error: from_place_$i duplicates a previous departure");
} else {
seenFrom.add(fromValue);
if (selectedTripType == "Roundtrip") {
for (int i = 1; i <= rowCount; i++) {
final fromValue = selectedFrom[i];
final toValue = selectedTo[i];
if (fromValue != null) {
if (seenFrom.contains(fromValue)) {
errorMessages["from_place_$i"] = "Duplicate Departure ";
print("Error: from_place_$i duplicates a previous departure");
} else {
seenFrom.add(fromValue);
// errorMessages.remove("from_place_$i");
// errorMessages.remove("from_place_$i");
}
}
}
if (toValue != null) {
if (seenTo.contains(toValue)) {
errorMessages["to_place_$i"] = "Duplicate Destination ";
print("Error: to_place_$i duplicates a previous departure");
} else {
// errorMessages.remove("to_place_$i");
seenTo.add(toValue);
if (toValue != null) {
if (seenTo.contains(toValue)) {
errorMessages["to_place_$i"] = "Duplicate Destination ";
print("Error: to_place_$i duplicates a previous departure");
} else {
// errorMessages.remove("to_place_$i");
seenTo.add(toValue);
}
}
}
}
@ -972,7 +973,6 @@ class FlightScreenState extends State<FlightScreen> {
}
List<String> filterAndSortCountryList(List<String> items, String filter) {
final lowerFilter = filter.toLowerCase();
int getMatchScore(String item) {
@ -994,25 +994,22 @@ class FlightScreenState extends State<FlightScreen> {
return 999;
}
return items
.where((item) {
final parts = item.split('\n');
final cityAndCode = parts[0];
final airport = parts.length > 1 ? parts[1].toLowerCase() : '';
return items.where((item) {
final parts = item.split('\n');
final cityAndCode = parts[0];
final airport = parts.length > 1 ? parts[1].toLowerCase() : '';
final match = RegExp(r'^(.*)\s+\(([^)]+)\)$').firstMatch(cityAndCode);
final city = match?.group(1)?.toLowerCase() ?? '';
final code = match?.group(2)?.toLowerCase() ?? '';
final match = RegExp(r'^(.*)\s+\(([^)]+)\)$').firstMatch(cityAndCode);
final city = match?.group(1)?.toLowerCase() ?? '';
final code = match?.group(2)?.toLowerCase() ?? '';
return code.contains(lowerFilter) ||
city.contains(lowerFilter) ||
airport.contains(lowerFilter);
})
.toList()
return code.contains(lowerFilter) ||
city.contains(lowerFilter) ||
airport.contains(lowerFilter);
}).toList()
..sort((a, b) => getMatchScore(a).compareTo(getMatchScore(b)));
}
List<Widget> _buildFirstRow(isDesktop) {
return [
Column(
@ -1523,8 +1520,6 @@ class FlightScreenState extends State<FlightScreen> {
// }
}
return [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -1572,13 +1567,14 @@ class FlightScreenState extends State<FlightScreen> {
selectedFrom[index] != null
? countryMap[selectedFrom[index]]
: null,
asyncItems: (String filter) async {
final allItems = countryMap.values.toSet().toList();
print("Original items: ${allItems.length}");
final filtered = filterAndSortCountryList(allItems, filter);
// print("Filtered items: ${filtered.length} -> $filtered");
return filtered;
},
items: countryMap.values.toList(),
// asyncItems: (String filter) async {
// final allItems = countryMap.values.toSet().toList();
// print("Original items: ${allItems.length}");
// final filtered = filterAndSortCountryList(allItems, filter);
// // print("Filtered items: ${filtered.length} -> $filtered");
// return filtered;
// },
popupProps: PopupProps.menu(
fit: FlexFit.loose,
constraints: BoxConstraints(maxHeight: 220),
@ -2875,6 +2871,4 @@ class FlightScreenState extends State<FlightScreen> {
),
];
}
}

View File

@ -273,11 +273,13 @@ class _ForexScreenState extends State<ForexScreen> {
// Check if card_number has at least 16 digits
}
final cardNumber = data["card_number"]?.toString() ?? '';
if (cardNumber.length < 16) {
// Show error or return false
print("Card number must be 16 digits");
errorMessages["card_number"] = "Card number must be 16 digits";
if (!isCardChecked) {
final cardNumber = data["card_number"]?.toString() ?? '';
if (cardNumber.length < 15) {
// Show error or return false
print("Card number must be 15 digits");
errorMessages["card_number"] = "Card number must be atleat 15 digits";
}
}
// Check validation for each field
@ -2328,6 +2330,8 @@ class _ForexScreenState extends State<ForexScreen> {
),
onChanged: (bool? value) {
setState(() {
errorMessages.remove("card_number");
isChecked = value!;
// if (isChecked) {
// textControllers["_cardNumber"]

View File

@ -5,6 +5,7 @@ import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_quill/flutter_quill_internal.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
@ -421,14 +422,12 @@ class PersonalDetailsState extends State<PersonalDetails> {
child:
isDesktop
? SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: _buildOptions(),
),
),
)
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(children: _buildOptions()),
),
)
: Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
@ -587,9 +586,12 @@ class PersonalDetailsState extends State<PersonalDetails> {
Spacer(),
buildLastNameField(),
Spacer(), // Space after Last Name
buildGenderField(),
SizedBox(width: 15),
buildDobField(),
// buildGenderField(),
// SizedBox(width: 15),
// buildDobField(),
buildMobileField(),
Spacer(),
buildAlternateMobileField(),
],
)
: Column(
@ -599,9 +601,12 @@ class PersonalDetailsState extends State<PersonalDetails> {
SizedBox(height: 8), // Vertical space
buildLastNameField(),
SizedBox(height: 8),
buildGenderField(),
SizedBox(height: 8),
buildDobField(),
// buildGenderField(),
// SizedBox(height: 8),
// buildDobField(),
buildMobileField(),
SizedBox(height: 8), // Space after Last Name
buildAlternateMobileField(),
],
),
);
@ -615,21 +620,21 @@ class PersonalDetailsState extends State<PersonalDetails> {
? Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildEmailField(),
Spacer(),
buildMobileField(),
Spacer(), // Space after Last Name
buildAlternateMobileField(),
// buildEmailField(),
// Spacer(),
// buildMobileField(),
// Spacer(), // Space after Last Name
// buildAlternateMobileField(),
],
)
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildMobileField(),
SizedBox(height: 8), // Vertical space
buildAlternateMobileField(),
SizedBox(height: 8),
buildEmailField(),
// buildMobileField(),
// SizedBox(height: 8), // Vertical space
// buildAlternateMobileField(),
// SizedBox(height: 8),
// buildEmailField(),
],
),
);
@ -662,6 +667,8 @@ class PersonalDetailsState extends State<PersonalDetails> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (!widget.apiselectedUser) ...[
buildEmailField(),
Spacer(),
buildPassword(),
SizedBox(
width: MediaQuery.of(context).size.width * 0.015,
@ -670,33 +677,37 @@ class PersonalDetailsState extends State<PersonalDetails> {
],
],
)
: Column(
: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width:
isDesktop
? MediaQuery.of(context).size.width * 0.25
: MediaQuery.of(context).size.width * 0.8,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () => _openPopup(),
style: TextButton.styleFrom(
foregroundColor: Color(0xFF114D8B),
textStyle: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w400,
),
),
child: Text("Change Password"),
),
],
),
),
SizedBox(height: 1),
buildEmailField(),
SizedBox(width: 10),
// Spacer(),
// Container(
// width:
// isDesktop
// ? MediaQuery.of(context).size.width * 0.25
// : MediaQuery.of(context).size.width * 0.8,
// child: Row(
// mainAxisAlignment: MainAxisAlignment.end,
// children: [
// TextButton(
// onPressed: () => _openPopup(),
// style: TextButton.styleFrom(
// foregroundColor: Color(0xFF114D8B),
// textStyle: GoogleFonts.poppins(
// fontSize: 12,
// fontWeight: FontWeight.w400,
// ),
// ),
// child: Text("Change Password"),
// ),
// ],
// ),
// ),
buildchangPswd(),
// SizedBox(height: 1),
Spacer(),
buildRole(),
],
)
@ -704,6 +715,8 @@ class PersonalDetailsState extends State<PersonalDetails> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (!widget.apiselectedUser) ...[
buildEmailField(),
SizedBox(height: 8),
buildPassword(),
SizedBox(height: 8),
buildRole(),
@ -1038,6 +1051,50 @@ class PersonalDetailsState extends State<PersonalDetails> {
);
}
Widget buildchangPswd() {
void _openPopup() {
final emailValue = widget.controllers["email"]?.text ?? "";
final updaterUserId = widget.userIdApi ?? "";
showDialog(
context: context,
builder: (context) {
return ChangePasswordDialogData(
updaterEmail: emailValue,
updaterUserId: updaterUserId,
layoutColor: layoutColor,
isDesktop: widget.isDesktop,
);
},
);
}
return Container(
width:
isDesktop
? MediaQuery.of(context).size.width * 0.25
: MediaQuery.of(context).size.width * 0.8,
child: Column(
// mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 30),
TextButton(
onPressed: () => _openPopup(),
style: TextButton.styleFrom(
foregroundColor: Color(0xFF114D8B),
textStyle: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w400,
),
),
child: Text("Change Password"),
),
],
),
);
}
Widget buildEmailField() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -1104,6 +1161,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
CustomTextFieldUserWrapper(
isFocused: false,
isDesktop: widget.isDesktop,
width: MediaQuery.of(context).size.width * 0.12,
child: SizedBox(
height: 40,
child: TextField(
@ -1165,6 +1223,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
CustomTextFieldUserWrapper(
isFocused: false,
isDesktop: widget.isDesktop,
width: MediaQuery.of(context).size.width * 0.12,
child: SizedBox(
height: 40,
child: TextField(
@ -1272,7 +1331,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
),
child: Padding(
// padding: const EdgeInsets.all(3.0),
padding: EdgeInsets.symmetric(horizontal: 2,vertical: 3),
padding: EdgeInsets.symmetric(horizontal: 2, vertical: 3),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -1296,7 +1355,10 @@ class PersonalDetailsState extends State<PersonalDetails> {
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
hintText: "Search Country...",
contentPadding: EdgeInsets.symmetric(horizontal: 3,vertical: 3),
contentPadding: EdgeInsets.symmetric(
horizontal: 3,
vertical: 3,
),
),
),
),

View File

@ -795,28 +795,6 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
print("All tabs completed!");
// Submit the full form here
}
// if (!isValidData(data))
// {
// print("USERDETAILS : $userDetials");
// print("Validation Failed: Required fields are missing.");
// setState(() {});
// return; // Stop execution if validation fails
// } else
// {
// print("USERDETAILS : $userDetials");
//
// if (currentIndex < tabKeys.length - 1) {
// // Move to next tab
// setState(() {
// selectedTab = tabKeys[currentIndex + 1];
// });
// } else {
// // Already at last tab (travel), maybe submit form or show done message
// print("All tabs completed!");
// // You can trigger full form submit here
// }
// }
}
void handleSubmit() async {
@ -1351,30 +1329,29 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
Row(
children: [
apiselectedUser != null
? Text( "Profile",
style: GoogleFonts.poppins(
fontSize: isDesktop ? 15 : 12,
fontWeight: FontWeight.w600,
color: Colors.black,
),
)
: Container(
child: BreadcrumbNavigation(
isDesktop: isDesktop,
breadcrumbItems: [
BreadcrumbItem(
title: 'Users',
tooltip: 'Go To Users',
onTap: (context) {
context.go("/listUser");
}
),
BreadcrumbItem(
title: 'Create New User',
),
],
),
? Text(
"Profile",
style: GoogleFonts.poppins(
fontSize: isDesktop ? 15 : 12,
fontWeight: FontWeight.w600,
color: Colors.black,
),
)
: Container(
child: BreadcrumbNavigation(
isDesktop: isDesktop,
breadcrumbItems: [
BreadcrumbItem(
title: 'Users',
tooltip: 'Go To Users',
onTap: (context) {
context.go("/listUser");
},
),
BreadcrumbItem(title: 'Create New User'),
],
),
),
// Text(
// apiselectedUser != null ? "Profile" : "Create New User",
// style: GoogleFonts.poppins(

View File

@ -282,6 +282,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
value,
userId,
);
if (response.isNotEmpty) {
_clearError(field);
errorMessages[field] = response['message'] ?? "$label Already Exists";
@ -1261,7 +1262,11 @@ class TravellerDetailsState extends State<TravellerDetails> {
}
Widget buildNationality() {
List<String> nationalityOptions = ["Indian", "International","other nationality"];
List<String> nationalityOptions = [
"Indian",
"International",
"other nationality",
];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [