merge with old code

This commit is contained in:
venba-Inspriron-3558 2025-06-21 19:18:24 +05:30
parent 428dff9ca8
commit f95b5d9c37
9 changed files with 337 additions and 531 deletions

View File

@ -51,12 +51,12 @@ class DepartmentDataState extends State<DepartmentData> {
int? departmentDataId;
late String isActive = "1";
List<String> dataHeader = ["name", "description"];
List<String> dataHeader = ["dropdown_value", "description"];
Map<String, dynamic> departmentDetails() {
final data = {
// "department_id": int.parse(departmentId),
"name": controllers["name"]?.text,
"dropdown_value": controllers["dropdown_value"]?.text,
"description": controllers["description"]?.text,
"created_by": userId,
"is_active": isActive,
@ -119,10 +119,10 @@ class DepartmentDataState extends State<DepartmentData> {
if (data == null) return;
setState(() {
controllers['name']?.text = data['name'] ?? '';
controllers['description']?.text = data['description'].toString();
controllers['dropdown_value']?.text = data['dropdown_value'] ?? '';
// controllers['description']?.text = data['description'].toString();
isActive = data["is_active"];
final departmentId = int.tryParse(data['department_id'].toString());
final departmentId = int.tryParse(data['id'].toString());
departmentDataId = departmentId;
});
}
@ -137,11 +137,11 @@ class DepartmentDataState extends State<DepartmentData> {
errorMessages.clear();
final data = {
"name": controllers["name"]?.text,
"description": controllers["description"]?.text,
"dropdown_value": controllers["dropdown_value"]?.text,
// "description": controllers["description"]?.text,
};
final requiredFields = ["name", "description"];
final requiredFields = ["dropdown_value"];
bool hasFocused = false;
// Check validation for each field
@ -185,7 +185,7 @@ class DepartmentDataState extends State<DepartmentData> {
if (departmentDataId != null) {
print("for edit department id - $departmentDataId");
apiUrldata = '$apiUrl/api/updateDepartment/$departmentDataId';
departmentData["department_id"] = departmentDataId.toString();
departmentData["id"] = departmentDataId.toString();
departmentData["updated_by"] = userId;
(departmentData.containsKey("created_by"))
? departmentData.remove("created_by")
@ -281,14 +281,14 @@ class DepartmentDataState extends State<DepartmentData> {
),
SizedBox(height: 5),
CustomTextFieldForexWrapper(
isFocused: focusStates["nameFocused"] ?? false,
isFocused: focusStates["dropdown_valueFocused"] ?? false,
isDesktop: widget.isDesktop,
color: Colors.transparent,
child: SizedBox(
height: 40,
child: TextField(
controller: controllers["name"],
focusNode: focusNodes["nameFocusNode"],
controller: controllers["dropdown_value"],
focusNode: focusNodes["dropdown_valueFocusNode"],
style: const TextStyle(fontSize: 12),
decoration: const InputDecoration(
labelText: "Name",
@ -300,60 +300,60 @@ class DepartmentDataState extends State<DepartmentData> {
),
),
),
if (errorMessages["name"] != null) ...[
if (errorMessages["dropdown_value"] != null) ...[
SizedBox(height: 5), // Space before error message
Text(
errorMessages["name"]!,
style: TextStyle(color: Colors.red, fontSize: 12),
),
],
],
),
SizedBox(height: 15),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Description *",
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Color(0xFF575A74),
),
),
SizedBox(height: 5),
CustomTextFieldForexWrapper(
isFocused: focusStates["descriptionFocused"] ?? false,
isDesktop: widget.isDesktop,
color: Colors.transparent,
child: SizedBox(
height: 100,
child: TextField(
controller: controllers["description"],
focusNode: focusNodes["descriptionFocusNode"],
style: const TextStyle(fontSize: 12),
maxLines: null,
expands: true,
decoration: const InputDecoration(
labelText: "Description",
labelStyle: TextStyle(fontSize: 11, color: Colors.grey),
floatingLabelBehavior: FloatingLabelBehavior.never,
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16),
),
),
),
),
if (errorMessages["description"] != null) ...[
SizedBox(height: 5), // Space before error message
Text(
errorMessages["description"]!,
errorMessages["dropdown_value"]!,
style: TextStyle(color: Colors.red, fontSize: 12),
),
],
],
),
SizedBox(height: 15),
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// "Description *",
// style: GoogleFonts.poppins(
// fontSize: 12,
// fontWeight: FontWeight.w600,
// color: Color(0xFF575A74),
// ),
// ),
// SizedBox(height: 5),
// CustomTextFieldForexWrapper(
// isFocused: focusStates["descriptionFocused"] ?? false,
// isDesktop: widget.isDesktop,
// color: Colors.transparent,
// child: SizedBox(
// height: 100,
// child: TextField(
// controller: controllers["description"],
// focusNode: focusNodes["descriptionFocusNode"],
// style: const TextStyle(fontSize: 12),
// maxLines: null,
// expands: true,
// decoration: const InputDecoration(
// labelText: "Description",
// labelStyle: TextStyle(fontSize: 11, color: Colors.grey),
// floatingLabelBehavior: FloatingLabelBehavior.never,
// border: InputBorder.none,
// contentPadding: EdgeInsets.symmetric(vertical: 16),
// ),
// ),
// ),
// ),
// if (errorMessages["description"] != null) ...[
// SizedBox(height: 5), // Space before error message
// Text(
// errorMessages["description"]!,
// style: TextStyle(color: Colors.red, fontSize: 12),
// ),
// ],
// ],
// ),
// SizedBox(height: 15),
if (departmentDataId != null)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,

View File

@ -180,13 +180,13 @@ class DepartmentListState extends State<DepartmentList> {
allDepartment.where((object) {
final isActiveStatus =
object['is_active'] == "1" ? "active" : "inactive";
return (object['department_id']?.toLowerCase().contains(
return (object['id']?.toLowerCase().contains(
lowerQuery,
) ??
false) ||
(object['name']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['description']?.toLowerCase().contains(lowerQuery) ??
false) ||
(object['dropdown_value']?.toLowerCase().contains(lowerQuery) ?? false) ||
// (object['description']?.toLowerCase().contains(lowerQuery) ??
// false) ||
(isActiveStatus.contains(lowerQuery));
}).toList();
currentPage = 0;
@ -550,15 +550,15 @@ class DepartmentListState extends State<DepartmentList> {
),
),
),
DataColumn(
label: Text(
'Description',
style: GoogleFonts.poppins(
fontSize: 13,
fontWeight: FontWeight.w600,
),
),
),
// DataColumn(
// label: Text(
// 'Description',
// style: GoogleFonts.poppins(
// fontSize: 13,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
DataColumn(
label: Text(
'Status',
@ -581,7 +581,7 @@ class DepartmentListState extends State<DepartmentList> {
rows:
paginatedDepartment.map((tableObject) {
String departmentId =
tableObject['department_id']
tableObject['id']
.toString(); // Get user ID
bool isSelected =
selectedDepartmentId == departmentId;
@ -590,24 +590,24 @@ class DepartmentListState extends State<DepartmentList> {
cells: [
DataCell(
Text(
tableObject['name'] ?? '',
tableObject['dropdown_value'] ?? '',
style: TextStyle(
fontSize: 13,
fontFamily: "Inter",
),
),
),
DataCell(
Text(
tableObject['description'] ?? 'N/A',
style: TextStyle(
fontSize: 13,
fontFamily: "Inter",
),
softWrap: true,
overflow: TextOverflow.ellipsis,
),
),
// DataCell(
// Text(
// tableObject['description'] ?? 'N/A',
// style: TextStyle(
// fontSize: 13,
// fontFamily: "Inter",
// ),
// softWrap: true,
// overflow: TextOverflow.ellipsis,
// ),
// ),
DataCell(
Text(
tableObject['is_active'] == "1"
@ -645,7 +645,7 @@ class DepartmentListState extends State<DepartmentList> {
// final usersData = await getUserDetails(userId);
//
final departmentId = int.tryParse(
tableObject['department_id']
tableObject['id']
.toString(),
);
@ -716,7 +716,7 @@ class DepartmentListState extends State<DepartmentList> {
MainAxisAlignment.spaceBetween,
children: [
Text(
cardObject['name'] ?? 'N/A',
cardObject['dropdown_value'] ?? 'N/A',
style: GoogleFonts.poppins(
fontSize: 10,
color: Colors.black87,
@ -738,7 +738,7 @@ class DepartmentListState extends State<DepartmentList> {
// final usersData = await getUserDetails(userId);
//
final departmentId = int.tryParse(
cardObject['department_id']
cardObject['id']
.toString(),
);
@ -852,37 +852,37 @@ class DepartmentListState extends State<DepartmentList> {
SizedBox(height: 2),
// Trip Id and Trip Name
// Name
Row(
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
cardObject['description'] ?? '',
style: GoogleFonts.poppins(
fontSize: 10,
color: Colors.black87,
),
),
],
),
SizedBox(width: 10),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
cardObject['description'] ?? '',
style: GoogleFonts.poppins(
fontSize: 10,
color: Colors.black87,
),
),
],
),
],
),
// Row(
// children: [
// Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// Text(
// cardObject['description'] ?? '',
// style: GoogleFonts.poppins(
// fontSize: 10,
// color: Colors.black87,
// ),
// ),
// ],
// ),
// SizedBox(width: 10),
// Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// Text(
// cardObject['description'] ?? '',
// style: GoogleFonts.poppins(
// fontSize: 10,
// color: Colors.black87,
// ),
// ),
// ],
// ),
// ],
// ),
// Actions
// Actions
],

View File

@ -70,7 +70,7 @@ class _PolicyState extends State<Policy> {
String? userId;
bool showClass = true;
bool showCost = true;
bool showCost = false; // bool showCost = true; // on 21st june
List<dynamic>? selectedAllServices;
List<Map<String, String>> selectedOrgServiceIds = [];
@ -1115,7 +1115,7 @@ class _PolicyState extends State<Policy> {
if (selectedService == "Flight" ||
selectedService == "Train" || selectedService == "Accomodation") {
showClass = true;
showCost = true;
showCost = false;
int serviceCode = selectedService == "Flight" ? 1 : 2;
print("policyselectedService1 - $selectedService");
policyCriteriaKey.currentState
@ -1340,7 +1340,7 @@ class _PolicyState extends State<Policy> {
Text(
"Domestic",
style: GoogleFonts.poppins(
color: _selectedTripType == "1" ? Colors.white : Colors.black,
color: _selectedTripType == "1" ? Colors.black : Colors.black,
fontWeight: _selectedTripType == "1" ? FontWeight.w600 : null,
fontSize: 13,
),
@ -1366,13 +1366,13 @@ class _PolicyState extends State<Policy> {
borderRadius: BorderRadius.circular(4), // Rounded rectangle
border: Border.all(
color:
_selectedTripType == "1" ? Colors.white : Colors.black,
_selectedTripType == "1" ? Colors.green : Colors.black,
width: _selectedTripType == "1" ? 2 : 1,
),
),
child:
_selectedTripType == "1"
? Icon(Icons.rectangle, size: 8, color: Colors.white)
? Icon(Icons.rectangle, size: 8, color: Colors.green)
: null, // Add checkmark if selected
),
),
@ -1397,7 +1397,7 @@ class _PolicyState extends State<Policy> {
"International",
style: GoogleFonts.poppins(
fontSize: 13,
color: _selectedTripType == "2" ? Colors.white : Colors.black,
color: _selectedTripType == "2" ? Colors.black : Colors.black,
fontWeight: _selectedTripType == "2" ? FontWeight.w600 : null,
),
),
@ -1422,13 +1422,13 @@ class _PolicyState extends State<Policy> {
borderRadius: BorderRadius.circular(4), // Rounded rectangle
border: Border.all(
color:
_selectedTripType == "2" ? Colors.white : Colors.black,
_selectedTripType == "2" ? Colors.green : Colors.black,
width: _selectedTripType == "2" ? 2 : 1,
),
),
child:
_selectedTripType == "2"
? Icon(Icons.rectangle, size: 8, color: Colors.white)
? Icon(Icons.rectangle, size: 8, color: Colors.green)
: null, // Add checkmark if selected
),
),

View File

@ -364,9 +364,11 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
(object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['flight_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['sector']?.toLowerCase().contains(lowerQuery));
(object['Service']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['created_on']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['FirstTravelDt']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['AdvPurch']?.toLowerCase().contains(lowerQuery));
}).toList();
currentPage1 = 0;
});
@ -382,9 +384,11 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
(object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['flight_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['sector']?.toLowerCase().contains(lowerQuery));
(object['Service']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['created_on']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['FirstTravelDt']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['AdvPurch']?.toLowerCase().contains(lowerQuery));
}).toList();
currentPage2 = 0;
});
@ -700,9 +704,9 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
// DataColumn(label: Text('Employee Code', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('SO Number', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('Department', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('Flight Trip Type', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('Service', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('Plan Trip Type', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('Sector', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('AdvPurch', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// ],
// rows: domesticData.map((entry) {
// return DataRow(cells: [
@ -710,9 +714,9 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
// DataCell(Text('${entry['employee_code']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['so_number']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['functional_department']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['flight_trip_type']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['Service']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['plan_trip_type']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['sector']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['AdvPurch']}', style: GoogleFonts.poppins(fontSize: 12))),
// ]);
// }).toList(),
// ),
@ -846,7 +850,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
),
DataColumn(
label: Text(
'Flight Trip Type',
'Service',
style:
GoogleFonts.poppins(
fontSize: 12,
@ -870,7 +874,31 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
),
DataColumn(
label: Text(
'Sector',
'Created on',
style:
GoogleFonts.poppins(
fontSize: 12,
fontWeight:
FontWeight
.w600,
),
),
),
DataColumn(
label: Text(
'First Travel Date',
style:
GoogleFonts.poppins(
fontSize: 12,
fontWeight:
FontWeight
.w600,
),
),
),
DataColumn(
label: Text(
git 'Advance Purchase',
style:
GoogleFonts.poppins(
fontSize: 12,
@ -929,7 +957,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
),
DataCell(
Text(
'${entry['flight_trip_type']}',
'${entry['Service']}',
style:
GoogleFonts.poppins(
fontSize:
@ -949,7 +977,27 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
),
DataCell(
Text(
'${entry['sector']}',
'${entry['created_on']}',
style:
GoogleFonts.poppins(
fontSize:
12,
),
),
),
DataCell(
Text(
'${entry['FirstTravelDt']}',
style:
GoogleFonts.poppins(
fontSize:
12,
),
),
),
DataCell(
Text(
'${entry['AdvPurch']}',
style:
GoogleFonts.poppins(
fontSize:
@ -1126,9 +1174,9 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
// DataColumn(label: Text('Employee Code', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('SO Number', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('Department', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('Flight Trip Type', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('Service', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('Plan Trip Type', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('Sector', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// DataColumn(label: Text('AdvPurch', style: GoogleFonts.poppins(fontSize: 12, fontWeight: FontWeight.w600))),
// ],
// rows: internationalData.map((entry) {
// return DataRow(cells: [
@ -1136,9 +1184,9 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
// DataCell(Text('${entry['employee_code']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['so_number']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['functional_department']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['flight_trip_type']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['Service']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['plan_trip_type']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['sector']}', style: GoogleFonts.poppins(fontSize: 12))),
// DataCell(Text('${entry['AdvPurch']}', style: GoogleFonts.poppins(fontSize: 12))),
// ]);
// }).toList(),
// ),
@ -1336,7 +1384,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
),
DataColumn(
label: Text(
'Flight Trip Type',
'Service',
style:
GoogleFonts.poppins(
fontSize: 12,
@ -1360,7 +1408,31 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
),
DataColumn(
label: Text(
'Sector',
'Created on',
style:
GoogleFonts.poppins(
fontSize: 12,
fontWeight:
FontWeight
.w600,
),
),
),
DataColumn(
label: Text(
'First Travel Date',
style:
GoogleFonts.poppins(
fontSize: 12,
fontWeight:
FontWeight
.w600,
),
),
),
DataColumn(
label: Text(
'Advance Purchase',
style:
GoogleFonts.poppins(
fontSize: 12,
@ -1419,7 +1491,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
),
DataCell(
Text(
'${entry['flight_trip_type']}',
'${entry['Service']}',
style:
GoogleFonts.poppins(
fontSize:
@ -1436,10 +1508,29 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
12,
),
),
),DataCell(
Text(
'${entry['created_on']}',
style:
GoogleFonts.poppins(
fontSize:
12,
),
),
),
DataCell(
Text(
'${entry['sector']}',
'${entry['FirstTravelDt']}',
style:
GoogleFonts.poppins(
fontSize:
12,
),
),
),
DataCell(
Text(
'${entry['AdvPurch']}',
style:
GoogleFonts.poppins(
fontSize:

View File

@ -10,8 +10,8 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:frontend/Screens/userManagement/create_user/personal_details.dart';
import 'package:frontend/Screens/userManagement/create_user/traveller_details.dart';
import 'package:frontend/utils/auth_utils.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
@ -31,6 +31,7 @@ import '../../../widgets/custom_text_field.dart';
import '../../../widgets/custom_text_forex.dart';
import '../../../widgets/custom_user_form.dart';
import '../../../widgets/saving_loader.dart';
import '../../userManagement/create_traveller_agent/personalDetailsTravelAgent.dart';
import 'package:universal_html/html.dart' as html;
class CreateTravelAgentFormDetials extends StatefulWidget {
@ -43,8 +44,6 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
final GlobalKey<PersonalDetailsState> personalDetailsKey =
GlobalKey<PersonalDetailsState>();
final GlobalKey<TravellerDetailsState> travellerDetailsKey =
GlobalKey<TravellerDetailsState>();
// late List<Map<String, dynamic>?> travelDetailsData;
Map<String, dynamic>? travelDetailsData;
@ -743,22 +742,11 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
print("USR Detail Next");
printFormData();
// travelDetailsData = [travellerDetailsKey.currentState?.travel_Detials];
travelDetailsData = travellerDetailsKey.currentState?.travel_Detials;
// errorMessagesTravel = travellerDetailsKey.currentState!.errorMessages;
print("TRAVEL DETAILS FROM CHILD: $travelDetailsData");
Map<String, dynamic> data = userDetials;
print("USERDETAILS : $data");
final tabs = {
"personal": "Personal Details",
"office": "Office Details",
"travel": "Travel Details",
};
final tabs = { "personal": "Personal Details" };
final tabKeys = tabs.keys.toList(); // ["personal", "office", "travel"]
@ -821,7 +809,7 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
print("travel gnt Detail Submit");
// printFormData();
print("travel validation");
bool isValid = travellerDetailsKey.currentState?.boolValidation() ?? false;
bool isValid = false;
print("Start loader at: ${DateTime.now()}");
showDialog(
@ -853,19 +841,18 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
return; // STOP execution here if not valid
}
travelDetailsData = travellerDetailsKey.currentState?.travel_Detials;
// travelDetailsData = travellerDetailsKey.currentState?.travel_Detials;
// print("travelDetailsData - $travelDetailsData");
print("travelDetailsData - $travelDetailsData");
print("travelDetailsData - $travelDetailsData");
// print("travelDetailsData - $travelDetailsData");
// errorMessagesTravel = travellerDetailsKey.currentState!.errorMessages;
print("TRAVEL DETAILS FROM CHILD");
// print("TRAVEL DETAILS FROM CHILD");
// print("TRAVEL DETAILS FROM CHILD: $travelDetailsData");
passportFile = travellerDetailsKey.currentState?.passportFile;
// passportFile = travellerDetailsKey.currentState?.passportFile;
print("passportFile : $passportFile");
// print("passportFile : $passportFile");
Map<String, dynamic> data = userDetials;
@ -1274,7 +1261,7 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
Widget buildData(bool isDesktop, context) {
return Container(
margin: isDesktop ? const EdgeInsets.only(top: 10.0, bottom: 10.0) : null,
padding: const EdgeInsets.only(left: 10, right: 10, top: 8),
padding: const EdgeInsets.only(left: 10, right: 10, top: 5),
decoration: BoxDecoration(
color: isDesktop ? Colors.white : Color(0xFFFCFCFC),
),
@ -1284,7 +1271,7 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
child: Container(
height:
isDesktop
? MediaQuery.of(context).size.height * 0.98
? MediaQuery.of(context).size.height * 0.88
: MediaQuery.of(context).size.height,
child: Padding(
padding: EdgeInsets.all(0.0),
@ -1295,7 +1282,7 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(8.0),
padding: const EdgeInsets.all(5.0),
child:
isDesktop
? Row(

View File

@ -71,6 +71,8 @@ class PersonalDetailsState extends State<PersonalDetails> {
List<dynamic>? apiAllServices;
Map<String, dynamic>? selectedOrg;
List<Map<String, dynamic>> selectedServiceIds = [];
Map<String, FocusNode> focusNodes = {};
Map<String, bool> focusStates = {};
String? get selectedGenderValue => selectedGender;
String? get selectedCountryValue => selectedCountry;
@ -150,6 +152,19 @@ class PersonalDetailsState extends State<PersonalDetails> {
print("selectedServiceIdsAPI - $selectedServiceIds");
for (var field in dataHeader) {
focusNodes["${field}FocusNode"] = FocusNode();
focusStates["${field}Focused"] = false;
}
for (var key in focusNodes.keys) {
_addFocusListener(focusNodes[key]!, (focus) {
setState(() {
focusStates[key.replaceFirst("FocusNode", "Focused")] = focus;
});
});
}
WidgetsBinding.instance.addPostFrameCallback((_) {
loadAllServices();
getOrganizationData();
@ -157,6 +172,23 @@ class PersonalDetailsState extends State<PersonalDetails> {
});
}
@override
void dispose() {
for (var node in focusNodes.values) {
node.dispose();
}
super.dispose();
}
void _addFocusListener(FocusNode node, Function(bool) updateState) {
node.addListener(() {
setState(() {
updateState(node.hasFocus);
});
});
}
Future<void> apiCheckDuplicate(
String label,
String field,
@ -314,9 +346,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20),
// _buildPassportDataRow1(widget.isDesktop),
// SizedBox(height: 10),
SizedBox(height: 10),
_buildFirstRow(widget.isDesktop),
SizedBox(height: 10),
_buildSecondRow(widget.isDesktop),
@ -325,32 +355,13 @@ class PersonalDetailsState extends State<PersonalDetails> {
SizedBox(height: 10),
_buildForthRow(widget.isDesktop),
SizedBox(height: 10),
if (selectedRole == "5") _buildServices(widget.isDesktop),
_buildServices(widget.isDesktop),
],
),
),
);
}
Widget _buildPassportDataRow1(bool isDesktop) {
return Container(
color: Colors.white,
child: Row(
children: [
Text(
"* Please fill name details as per in passport *",
style: GoogleFonts.poppins(
fontSize: 10,
color: Colors.black87,
fontStyle: FontStyle.italic,
letterSpacing: 0.5,
),
),
],
),
);
}
Future<void> loadAllServices() async {
try {
final result = await apiService.fetchAllServices();
@ -374,7 +385,6 @@ class PersonalDetailsState extends State<PersonalDetails> {
children: [
Text(
"Services",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w400,
@ -497,13 +507,6 @@ class PersonalDetailsState extends State<PersonalDetails> {
fontWeight:
isSelected == name ? FontWeight.bold : FontWeight.w500,
),
// style: TextStyle(
// fontSize: 13,
// color: isSelected == name ? Color(0xFF114D8B) : Color(0xFF475569),
// fontFamily: "Archivo",
// fontWeight:
// isSelected == name ? FontWeight.bold : FontWeight.w500),
// fontWeight: selectedListOption == title ? FontWeight.bold : FontWeight.normal,)),
),
SizedBox(width: 5),
@ -648,22 +651,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
width: MediaQuery.of(context).size.width * 0.015,
),
buildRole(),
] else ...[
// TextButton(
// onPressed: () => _openPopup(),
// style: TextButton.styleFrom(
// foregroundColor: Colors.black,
// textStyle: GoogleFonts.poppins(
// fontSize: 12,
// fontWeight: FontWeight.w400,
// ),
// ),
// child: Text("Change Password"),
// ),
//
// SizedBox(height: 8, width: 15),
// buildRole(),
],
]
],
)
: Column(
@ -778,12 +766,13 @@ class PersonalDetailsState extends State<PersonalDetails> {
),
SizedBox(height: 5),
CustomTextFieldUserWrapper(
isFocused: false,
isFocused: focusStates["FnameFocused"] ?? false,
isDesktop: widget.isDesktop,
child: SizedBox(
height: 40,
child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
focusNode: focusNodes["FnameFocusNode"],
controller: widget.controllers["Fname"],
enabled: !widget.isViewMode,
onChanged: (value) {
@ -828,12 +817,13 @@ class PersonalDetailsState extends State<PersonalDetails> {
),
SizedBox(height: 5),
CustomTextFieldUserWrapper(
isFocused: false,
isFocused: focusStates["LnameFocused"] ?? false,
isDesktop: widget.isDesktop,
child: SizedBox(
height: 40,
child: TextField(
style: TextStyle(fontSize: 12, color: Colors.black),
focusNode: focusNodes["LnameFocusNode"],
controller: widget.controllers["Lname"],
enabled: !widget.isViewMode,
onChanged: (value) {
@ -860,104 +850,6 @@ class PersonalDetailsState extends State<PersonalDetails> {
);
}
// Widget buildGenderFieldOld() {
// return Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// "Gender",
// style: GoogleFonts.poppins(
// fontSize: 12,
// fontWeight: FontWeight.w600,
// color: Color(0xFF575A74),
// ),
// ),
// SizedBox(height: 5),
// CustomTextFieldUserWrapper(
// width:
// widget.isDesktop
// ? MediaQuery.of(context).size.width * 0.12
// : null,
// isFocused: false,
// isDesktop: widget.isDesktop,
// child: SizedBox(
// height: 40,
// child: DropdownButtonFormField<String>(
// // value: selectedGender,
// value: widget.isViewMode ? null : selectedGender,
// onChanged:
// widget.isViewMode
// ? null
// : (String? newValue) {
// setState(() {
// selectedGender = newValue;
// print("selectedGender - $selectedGender");
// });
//
// widget.onGenderChanged?.call(newValue);
// },
// decoration: InputDecoration(
// border: InputBorder.none,
// enabled: !widget.isViewMode, // Disables input when in view mode
// ),
// style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
// items: [
// DropdownMenuItem(value: "Male", child: Text("Male")),
// DropdownMenuItem(value: "Female", child: Text("Female")),
// ],
// hint: Text(
// selectedGender ?? "Select Gender",
// style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
// ),
// disabledHint: Text(
// selectedGender ?? "Select Gender",
// style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
// ),
// ),
//
// // child: DropdownSearch<String>(
// // selectedItem: selectedGender,
// // // key: ValueKey(selectedGender),
// // popupProps: PopupProps.menu(
// // fit: FlexFit.loose, // Allows flexible height
// // constraints: BoxConstraints(maxHeight: 250),
// //
// // ),
// // items: ["Male", "Female", "Others"],
// // dropdownDecoratorProps: DropDownDecoratorProps(
// // dropdownSearchDecoration: InputDecoration(
// // border: InputBorder.none,
// // contentPadding: EdgeInsets.symmetric(horizontal: 1,),
// // ),
// // ),
// // dropdownBuilder: (context, selectedItem) => Align( // Center-align selected item
// // alignment: Alignment.centerLeft,
// // child: Text(
// // selectedItem ?? "Select",
// // style: TextStyle(fontSize: 12),
// // ),
// // ),
// // onChanged: isViewMode
// // ? null
// // : (String? newValue) {
// // setState(() {
// // // Find the country_code based on selected country_name
// // selectedGender = newValue;
// // print("selectedGender - $selectedGender");
// // // if (selectedCountry!.isNotEmpty) {
// // // errorMessages.remove("country_code");
// // // }
// // });
// // },
// //
// //
// // ),
// ),
// ),
// ],
// );
// }
Widget buildGenderField() {
List<String> genderOptions = ["Male", "Female"];
@ -1304,6 +1196,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
countryMap = {
for (var item in countryList)
item['country_code'] as String: item['country_name'] as String,
// item['currency'] as String
};
// Extract only country codes for processing
@ -1461,67 +1354,8 @@ class PersonalDetailsState extends State<PersonalDetails> {
);
}
// Widget buildRoleOld() {
// return Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// "Role ",
// style: GoogleFonts.poppins(
// fontSize: 12,
// fontWeight: FontWeight.w600,
// color: Color(0xFF575A74),
// ),
// ),
// SizedBox(height: 5),
// CustomTextFieldUserWrapper(
// isFocused: false, // Dropdown doesn't use focus
// isDesktop: widget.isDesktop,
// child: SizedBox(
// height: 45, // Set appropriate height
// child: DropdownButtonFormField<String>(
// // value: widget.isViewMode ? null : selectedRole,
// value: selectedRole,
// style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
// decoration: InputDecoration(
// border: InputBorder.none,
// contentPadding: EdgeInsets.symmetric(
// horizontal: 10,
// ), // Proper padding
// ),
// onChanged:
// widget.isViewMode
// ? null
// : (newValue) {
// setState(() {
// selectedRole = newValue;
// isTravelAgent = selectedRole == "5";
// // Pass the result back to parent
// widget.onUserTypeChanged?.call(isTravelAgent);
// });
// widget.onRoleChanged?.call(newValue);
// },
// items:
// apiRoleData?.map<DropdownMenuItem<String>>((item) {
// return DropdownMenuItem(
// value: item['dropdown_key'], // ID as value
// child: Text(item['dropdown_value'] ?? "Select Role"),
// );
// }).toList(),
// hint: Text("Select Role"),
// disabledHint: Text(
// selectedRole ?? "Select Role",
// style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
// ),
// ),
// ),
// ),
// ],
// );
// }
Widget buildRole() {
// Map dropdown_key (ID) -> dropdown_value (Name)
Map<String, String> roleMap = {
for (var item in apiRoleData ?? [])
item['dropdown_key'] as String: item['dropdown_value'] as String,
@ -1529,14 +1363,12 @@ class PersonalDetailsState extends State<PersonalDetails> {
// List<String> roleNames = roleMap.values.toList();
List<String> roleNames = roleMap.values.take(5).toList();
print("***---**");
print(roleNames);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Role*",
"Role",
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w600,
@ -1550,9 +1382,8 @@ class PersonalDetailsState extends State<PersonalDetails> {
child: SizedBox(
height: 40,
child: DropdownSearch<String>(
selectedItem: selectedRole != null ? roleMap[selectedRole] : null,
// enabled: !widget.isViewMode,
enabled: false,
selectedItem: roleMap[selectedRole] ,
enabled: false, //enabled: !widget.isViewMode,
popupProps: PopupProps.menu(
showSearchBox: true,
fit: FlexFit.loose,
@ -1610,7 +1441,6 @@ class PersonalDetailsState extends State<PersonalDetails> {
selectedRole = selectedKey;
isTravelAgent = selectedKey == "5";
});
widget.onUserTypeChanged?.call(isTravelAgent);
widget.onRoleChanged?.call(selectedKey);
},
@ -1628,115 +1458,6 @@ class PersonalDetailsState extends State<PersonalDetails> {
);
}
Widget buildRoleold() {
// Map dropdown_key (ID) -> dropdown_value (Name)
Map<String, String> roleMap = {
for (var item in apiRoleData ?? [])
item['dropdown_key'] as String: item['dropdown_value'] as String,
};
// List<String> roleNames = roleMap.values.toList();
List<String> roleNames = roleMap.values.take(5).toList();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Role",
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Color(0xFF575A74),
),
),
SizedBox(height: 5),
CustomTextFieldUserWrapper(
isFocused: false,
isDesktop: widget.isDesktop,
child: SizedBox(
height: 40,
child: DropdownSearch<String>(
selectedItem: selectedRole != null ? roleMap[selectedRole] : null,
// enabled: !widget.isViewMode,
enabled: false,
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 Role...",
contentPadding: EdgeInsets.symmetric(horizontal: 10),
),
),
),
items: roleNames,
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 1),
),
),
dropdownBuilder:
(context, selectedItem) => Align(
alignment: Alignment.centerLeft,
child: Text(
selectedItem ?? "Select Role",
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
),
),
onChanged:
widget.isViewMode
? null
: (String? newValue) {
widget.errorMessages.remove("role_id");
if (newValue == null) return;
final selectedKey =
roleMap.entries
.firstWhere((entry) => entry.value == newValue)
.key;
setState(() {
selectedRole = selectedKey;
isTravelAgent = selectedKey == "5";
});
widget.onUserTypeChanged?.call(isTravelAgent);
widget.onRoleChanged?.call(selectedKey);
},
),
),
),
if (widget.errorMessages["role_id"] != null) ...[
SizedBox(height: 5), // Space before error message
Text(
widget.errorMessages["role_id"]!,
style: GoogleFonts.poppins(color: Colors.red, fontSize: 12),
),
],
],
);
}
Widget buildAddress() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,

View File

@ -219,21 +219,44 @@ class _UserListScreenState extends State<UserListScreen> {
print("handDel - $userId");
}
void _showConfirmationDialog(message,reason) {
// if (!mounted) return;
void _showConfirmationDialog(String subtitle, List<String> successList, List<Map<String, String>> failedList) {
_dialogShown = true;
showDialog(
context: context,
builder:
(context) => AlertDialog(
title: Text(message),
content: Text(reason),
builder: (context) => AlertDialog(
// title: Text("User Details"),
title: Text("User Details - $subtitle", style: TextStyle(fontWeight: FontWeight.bold)),
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Text(subtitle, style: TextStyle(fontWeight: FontWeight.bold)),
//
// SizedBox(height: 12),
Text("Users Created Successfully :", style: TextStyle(fontWeight: FontWeight.bold)),
if (successList.isNotEmpty)
...successList.asMap().entries.map((entry) => Text("${entry.key + 1}) ${entry.value} created."))
else
Text("-- There is no data to create. --"),
SizedBox(height: 12),
Text("Failed to Create Users :", style: TextStyle(fontWeight: FontWeight.bold)),
if (failedList.isNotEmpty)
...failedList.asMap().entries.map((entry) {
final data = entry.value["data"] ?? "-";
final reason = entry.value["reason"] ?? "Unknown error";
return Text("${entry.key + 1}) $data - unable to create due to \"$reason\".");
})
else
Text("-- There is no failed data. --"),
],
),
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context); // Close dialog
Navigator.pop(context);
_dialogShown = false;
},
child: Text("Close"),
@ -243,6 +266,7 @@ class _UserListScreenState extends State<UserListScreen> {
);
}
Future<void> handleUpload() async {
final String apiUrldata = '$apiUrl/api/user/userUpload'; // api
final String? token = await getToken(); // 2kn
@ -333,33 +357,16 @@ class _UserListScreenState extends State<UserListScreen> {
final status = responseData['status'] ?? '';
final data = responseData['data'] ?? {};
final successfulUsers = List.from(data['successfulUsers'] ?? []);
final failedUsers = List.from(data['failedUsers'] ?? []);
final List<String> successList = List<String>.from(data['successfulUsers'] ?? []);
final List<Map<String, String>> failedList = List<Map<String, String>>.from(
(data['failedUsers'] ?? []).map((item) => Map<String, String>.from(item)),
);
print(successfulUsers);
print(failedUsers);
_showConfirmationDialog(message, successList, failedList);
// final successfulUsers = List.from(data['successfulUsers'] ?? []);
// final failedUsers = List.from(data['failedUsers'] ?? []);
// Helper function to format user lists
String buildUserList(String title, List users) {
if (users.isEmpty) return '';
final formattedUsers = users.map((user) {
if (user == null || user.toString().trim().isEmpty) {
return '• Email not provided';
}
return '$user';
}).join('\n');
return '\n$title:\n$formattedUsers';
}
final successList = buildUserList("✅ Successfully Processed", successfulUsers);
final failedList = buildUserList("❌ Failed to Process", failedUsers);
final combinedMessage = [message, successList, failedList]
.where((part) => part.isNotEmpty)
.join('\n\n');
_showConfirmationDialog(message,combinedMessage);
// Unified SnackBar logic
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(

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

@ -1057,7 +1057,7 @@ class ApiService {
// ---
Future<Map<String, dynamic>> getDepartmentDetailsFind(int id) async {
final String apiUrldata = '$apiUrl/api/findDepartment?department_id=$id';
final String apiUrldata = '$apiUrl/api/findDepartment?id=$id';
final token = await getToken();