user passport changes

This commit is contained in:
venbaittech 2025-06-06 18:05:58 +05:30
parent fe6ccab809
commit f48680c2a5
5 changed files with 132 additions and 43 deletions

View File

@ -349,7 +349,7 @@ class _UserSelectionDialogState extends State<UserSelectionDialog> {
mainAxisSize:
MainAxisSize.min, // Ensures content doesn't expand unnecessarily
children: [
widget.title == "Others"
widget.title == "Others (Non Employee)"
? Text(
"Please Select Other User",
style: GoogleFonts.poppins(fontSize: 14),
@ -367,7 +367,7 @@ class _UserSelectionDialogState extends State<UserSelectionDialog> {
setState(() {
_showTravellerForm = false;
});
widget.title == "Others"
widget.title == "Others (Non Employee)"
? _filterTravellers(query)
: _filterUsers(query);
},
@ -395,7 +395,7 @@ class _UserSelectionDialogState extends State<UserSelectionDialog> {
SizedBox(height: 10),
if (widget.title == "Others") ...[
if (widget.title == "Others (Non Employee)") ...[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [

View File

@ -686,7 +686,7 @@ class FlightScreenState extends State<FlightScreen> {
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(20.0),
padding: const EdgeInsets.only(top: 30.0),
child: Center(
child: Column(children: _buildAccomadtionForm(isDesktop)),
),
@ -1809,7 +1809,7 @@ class FlightScreenState extends State<FlightScreen> {
),
),
SizedBox(height: 5),
CustomTextFieldWrapper(
CustomTextFieldItnerarySubWrapper(
// use same wrapper as class
isFocused: focusStates["_visa1Focused"] ?? false,
isDesktop: isDesktop,

View File

@ -2583,7 +2583,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
List<Map<String, String>> options = [
{"title": "Self", "value": "Option 1"},
{"title": "Other Employee", "value": "Option 2"},
{"title": "Others", "value": "Option 3"},
{"title": "Others (Non Employee)", "value": "Option 3"},
];
print(" layoutColor: ${widget.layoutColor}");
@ -2899,8 +2899,8 @@ class CreateNewPlansState extends State<CreateNewPlan> {
// ),
// ),
CustomTextFieldWrapper(
isFocused: false,
// isFocused: _isdescriptionFocused,
// isFocused: false,
isFocused: _isdescriptionFocused,
// width: isDesktop
// ? MediaQuery.of(context).size.width * 0.38
// : MediaQuery.of(context).size.width * 0.85,

View File

@ -49,7 +49,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
// late List<Map<String, dynamic>?> travelDetailsData;
Map<String, dynamic>? travelDetailsData;
Map<String, dynamic>? travelDetailsDataFromAPI;
Map<String, String> errorMessagesTravel = {};
late TabController _tabController;
String? userId;
@ -580,6 +580,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
// travelDetailsData = [travellerDetailsKey.currentState?.travel_Detials];
travelDetailsData = travellerDetailsKey.currentState?.travel_Detials;
errorMessagesTravel = travellerDetailsKey.currentState!.errorMessages;
print("TRAVEL DETAILS FROM CHILD: $travelDetailsData");
@ -655,6 +656,9 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
// printFormData();
travelDetailsData = travellerDetailsKey.currentState?.travel_Detials;
print("travelDetailsData - $travelDetailsData");
errorMessagesTravel = travellerDetailsKey.currentState!.errorMessages;
print("TRAVEL DETAILS FROM CHILD");
// print("TRAVEL DETAILS FROM CHILD: $travelDetailsData");
@ -668,7 +672,9 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
// Map<String, dynamic> data = userDetials;
if (!isValidData(data) && isValidDataTwo(data)) {
if (!isValidData(data) &&
isValidDataTwo(data) &&
errorMessagesTravel.isNotEmpty) {
print("USERDETAILS : $userDetials");
print("Validation Failed: Required fields are missing.");
setState(() {});
@ -677,7 +683,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
print("USERDETAILS : $userDetials");
orgId = await getOrgId();
createUserData(userDetials);
// createUserData(userDetials);
}
}

View File

@ -62,6 +62,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
String? selectedFileNames;
Uint8List? passportDocumentBytes;
String? passportFileUrlFromApi;
String? _selectedTripType;
// String? selectedPurpose;
// String? selectedCountry;
@ -107,7 +108,6 @@ class TravellerDetailsState extends State<TravellerDetails> {
List<String> dataHeader = [
"Fname",
"Mname",
"Lname",
"nationality",
"d_meal_pref",
@ -310,9 +310,10 @@ class TravellerDetailsState extends State<TravellerDetails> {
Map<String, dynamic> get travel_Detials {
Map<String, dynamic> data = {
// "given_Name": controllers["Fname"]?.text,
// "last_Name": controllers["Lname"]?.text,
// "nationality": controllers["nationality"]?.text,
"passport_firstname": controllers["Fname"]?.text,
"passport_middlename": controllers["Mname"]?.text,
"passport_lastname": controllers["Lname"]?.text,
"nationality": _selectedTripType,
"passport_number": controllers["passportNumber"]?.text ?? '',
"place_of_issue": controllers["placeOfIssue"]?.text,
"date_of_issue": controllers["dateOfIssue"]?.text,
@ -502,6 +503,17 @@ class TravellerDetailsState extends State<TravellerDetails> {
print("Updatewidget.travelDetails");
print(widget.travelDetails);
controllers["Fname"]?.text =
widget.travelDetails?["passport_firstname"] ?? "";
controllers["Mname"]?.text =
widget.travelDetails?["passport_middlename"] ?? "";
controllers["Lname"]?.text =
widget.travelDetails?["passport_lastname"] ?? "";
_selectedTripType = widget.travelDetails?["nationality"] ?? "";
controllers["passportNumber"]?.text =
widget.travelDetails?["passport_number"] ?? "";
controllers["placeOfIssue"]?.text =
@ -1133,6 +1145,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
}
Widget buildNationality() {
List<String> nationalityOptions = ["Indian", "International"];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -1154,23 +1167,54 @@ class TravellerDetailsState extends State<TravellerDetails> {
isDesktop: widget.isDesktop,
child: SizedBox(
height: 40,
child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
controller: controllers["nationality"],
child: DropdownSearch<String>(
selectedItem: _selectedTripType,
enabled: !widget.isViewMode,
onChanged: (value) {
_clearError("last_name");
},
decoration: InputDecoration(
labelText: "Nationality",
labelStyle: GoogleFonts.poppins(
fontSize: 12,
color: Colors.grey,
),
floatingLabelBehavior: FloatingLabelBehavior.never,
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16),
popupProps: PopupProps.menu(
showSearchBox: false, // Set true if you want search
fit: FlexFit.loose,
constraints: BoxConstraints(maxHeight: 200),
itemBuilder:
(context, item, isSelected) => Container(
color: Colors.white,
padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 6,
),
child: Text(
item,
style: GoogleFonts.poppins(fontSize: 11.5),
),
),
),
items: nationalityOptions,
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:
widget.isViewMode
? null
: (String? newValue) {
setState(() {
_selectedTripType = newValue;
print("_selectedTripType - $_selectedTripType");
});
},
),
),
),
@ -1200,8 +1244,30 @@ class TravellerDetailsState extends State<TravellerDetails> {
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
controller: controllers["passportNumber"],
enabled: !widget.isViewMode,
inputFormatters: [
// limit to 8 characters
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9]'),
), // allow only letters and digits
if (_selectedTripType == "Indian")
LengthLimitingTextInputFormatter(8),
],
onChanged: (value) {
_clearError("passport_number");
final regex = RegExp(r'^[a-zA-Z0-9]{0,8}$');
if (!regex.hasMatch(value)) {
setState(() {
if (_selectedTripType == "Indian") {
errorMessages["passport_number"] =
"Only 8 characters allowed (letters & numbers)";
}
});
return;
} else {
setState(() {
errorMessages.remove("passport_number");
});
}
apiCheckDuplicate(
"Passport Number",
"passport_number",
@ -1372,29 +1438,46 @@ class TravellerDetailsState extends State<TravellerDetails> {
DateTime today = DateTime(now.year, now.month, now.day);
// DateTime today = DateTime(now.year now.day, now.month,);
// Parse dateOfIssue safely
DateTime firstDate;
try {
firstDate = DateFormat(
"yyyy-MM-dd",
).parse(controllers["dateOfIssue"]!.text);
} catch (e) {
firstDate = today; // fallback if parsing fails
}
DateTime? pickedDate = await showDatePicker(
context: context,
initialDate:
_selectedDateOfExpiry != null &&
_selectedDateOfExpiry!.isAfter(today)
_selectedDateOfExpiry!.isAfter(firstDate)
? _selectedDateOfExpiry!
: today,
// firstDate: today,
firstDate: DateTime(1900),
firstDate: firstDate,
// firstDate: DateTime(1900),
lastDate: DateTime(2100),
);
if (pickedDate != null && pickedDate != _selectedDateOfExpiry) {
setState(() {
_selectedDateOfExpiry = pickedDate;
controllers["dateOfExpiry"]?.text = DateFormat(
'dd-MM-yyyy',
).format(pickedDate);
// controllers["dateOfExpiry"]?.text =
// DateFormat('dd-MM-yyyy').format(pickedDate);
});
if (pickedDate != null) {
_selectedDateOfExpiry = pickedDate;
controllers["dateOfExpiry"]?.text = DateFormat(
"yyyy-MM-dd",
).format(pickedDate);
}
// if (pickedDate != null && pickedDate != _selectedDateOfExpiry) {
// setState(() {
// _selectedDateOfExpiry = pickedDate;
// controllers["dateOfExpiry"]?.text = DateFormat(
// 'dd-MM-yyyy',
// ).format(pickedDate);
//
// // controllers["dateOfExpiry"]?.text =
// // DateFormat('dd-MM-yyyy').format(pickedDate);
// });
// }
}
return Column(