merged
This commit is contained in:
commit
1c77a03067
@ -36,11 +36,12 @@ class CostCenterDataState extends State<CostCenterData> {
|
|||||||
final ApiService apiService = ApiService();
|
final ApiService apiService = ApiService();
|
||||||
Map<String, dynamic>? apiData;
|
Map<String, dynamic>? apiData;
|
||||||
|
|
||||||
final Map<String, FocusNode> focusNodes = {
|
// final Map<String, FocusNode> focusNodes = {
|
||||||
"name": FocusNode(),
|
// "name": FocusNode(),
|
||||||
"description": FocusNode(),
|
// "description": FocusNode(),
|
||||||
};
|
// };
|
||||||
|
Map<String, FocusNode> focusNodes = {};
|
||||||
|
Map<String, bool> focusStates = {};
|
||||||
final Map<String, TextEditingController> controllers = {};
|
final Map<String, TextEditingController> controllers = {};
|
||||||
Map<String, String> errorMessages = {};
|
Map<String, String> errorMessages = {};
|
||||||
|
|
||||||
@ -70,6 +71,15 @@ class CostCenterDataState extends State<CostCenterData> {
|
|||||||
apiData = null;
|
apiData = null;
|
||||||
for (var field in dataHeader) {
|
for (var field in dataHeader) {
|
||||||
controllers[field] = TextEditingController();
|
controllers[field] = TextEditingController();
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (widget.costcenterId != null) {
|
if (widget.costcenterId != null) {
|
||||||
@ -89,8 +99,18 @@ class CostCenterDataState extends State<CostCenterData> {
|
|||||||
for (var controller in controllers.values) {
|
for (var controller in controllers.values) {
|
||||||
controller.dispose();
|
controller.dispose();
|
||||||
}
|
}
|
||||||
|
for (var node in focusNodes.values) {
|
||||||
|
node.dispose();
|
||||||
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
void _addFocusListener(FocusNode node, Function(bool) updateState) {
|
||||||
|
node.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
updateState(node.hasFocus);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void updateCostCenterDetails() {
|
void updateCostCenterDetails() {
|
||||||
print("Inside Update Function - ${widget.costcenterData}");
|
print("Inside Update Function - ${widget.costcenterData}");
|
||||||
@ -129,10 +149,10 @@ class CostCenterDataState extends State<CostCenterData> {
|
|||||||
if (data[field] == null || data[field]!.trim().isEmpty) {
|
if (data[field] == null || data[field]!.trim().isEmpty) {
|
||||||
errorMessages[field] = "Required";
|
errorMessages[field] = "Required";
|
||||||
|
|
||||||
if (!hasFocused) {
|
// if (!hasFocused) {
|
||||||
focusNodes[field]?.requestFocus();
|
// focusNodes[field]?.requestFocus();
|
||||||
hasFocused = true;
|
// hasFocused = true;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,14 +278,14 @@ class CostCenterDataState extends State<CostCenterData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["nameFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: controllers["name"],
|
controller: controllers["name"],
|
||||||
focusNode: focusNodes["name"],
|
focusNode: focusNodes["nameFocusNode"],
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Name",
|
labelText: "Name",
|
||||||
@ -300,14 +320,14 @@ class CostCenterDataState extends State<CostCenterData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["descriptionFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 100,
|
height: 100,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: controllers["description"],
|
controller: controllers["description"],
|
||||||
focusNode: focusNodes["description"],
|
focusNode: focusNodes["descriptionFocusNode"],
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
maxLines: null,
|
maxLines: null,
|
||||||
expands: true,
|
expands: true,
|
||||||
|
|||||||
@ -36,26 +36,27 @@ class DepartmentDataState extends State<DepartmentData> {
|
|||||||
final ApiService apiService = ApiService();
|
final ApiService apiService = ApiService();
|
||||||
Map<String, dynamic>? apiData;
|
Map<String, dynamic>? apiData;
|
||||||
|
|
||||||
final Map<String, FocusNode> focusNodes = {
|
// final Map<String, FocusNode> focusNodes = {
|
||||||
"name": FocusNode(),
|
// "name": FocusNode(),
|
||||||
"description": FocusNode(),
|
// "description": FocusNode(),
|
||||||
};
|
// };
|
||||||
|
|
||||||
final Map<String, TextEditingController> controllers = {};
|
final Map<String, TextEditingController> controllers = {};
|
||||||
Map<String, String> errorMessages = {};
|
Map<String, String> errorMessages = {};
|
||||||
|
Map<String, FocusNode> focusNodes = {};
|
||||||
|
Map<String, bool> focusStates = {};
|
||||||
String? selectedName;
|
String? selectedName;
|
||||||
String? selectedDescription;
|
String? selectedDescription;
|
||||||
String? userId;
|
String? userId;
|
||||||
int? departmentDataId;
|
int? departmentDataId;
|
||||||
late String isActive = "1";
|
late String isActive = "1";
|
||||||
|
|
||||||
List<String> dataHeader = ["name", "description"];
|
List<String> dataHeader = ["dropdown_value", "description"];
|
||||||
|
|
||||||
Map<String, dynamic> departmentDetails() {
|
Map<String, dynamic> departmentDetails() {
|
||||||
final data = {
|
final data = {
|
||||||
// "department_id": int.parse(departmentId),
|
// "department_id": int.parse(departmentId),
|
||||||
"name": controllers["name"]?.text,
|
"dropdown_value": controllers["dropdown_value"]?.text,
|
||||||
"description": controllers["description"]?.text,
|
"description": controllers["description"]?.text,
|
||||||
"created_by": userId,
|
"created_by": userId,
|
||||||
"is_active": isActive,
|
"is_active": isActive,
|
||||||
@ -70,6 +71,15 @@ class DepartmentDataState extends State<DepartmentData> {
|
|||||||
apiData = null;
|
apiData = null;
|
||||||
for (var field in dataHeader) {
|
for (var field in dataHeader) {
|
||||||
controllers[field] = TextEditingController();
|
controllers[field] = TextEditingController();
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (widget.departmentId != null) {
|
if (widget.departmentId != null) {
|
||||||
@ -89,8 +99,18 @@ class DepartmentDataState extends State<DepartmentData> {
|
|||||||
for (var controller in controllers.values) {
|
for (var controller in controllers.values) {
|
||||||
controller.dispose();
|
controller.dispose();
|
||||||
}
|
}
|
||||||
|
for (var node in focusNodes.values) {
|
||||||
|
node.dispose();
|
||||||
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
void _addFocusListener(FocusNode node, Function(bool) updateState) {
|
||||||
|
node.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
updateState(node.hasFocus);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void updateDepartmentDetails() {
|
void updateDepartmentDetails() {
|
||||||
print("Inside Update Function - ${widget.departmentData}");
|
print("Inside Update Function - ${widget.departmentData}");
|
||||||
@ -99,10 +119,10 @@ class DepartmentDataState extends State<DepartmentData> {
|
|||||||
|
|
||||||
if (data == null) return;
|
if (data == null) return;
|
||||||
setState(() {
|
setState(() {
|
||||||
controllers['name']?.text = data['name'] ?? '';
|
controllers['dropdown_value']?.text = data['dropdown_value'] ?? '';
|
||||||
controllers['description']?.text = data['description'].toString();
|
// controllers['description']?.text = data['description'].toString();
|
||||||
isActive = data["is_active"];
|
isActive = data["is_active"];
|
||||||
final departmentId = int.tryParse(data['department_id'].toString());
|
final departmentId = int.tryParse(data['id'].toString());
|
||||||
departmentDataId = departmentId;
|
departmentDataId = departmentId;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -117,11 +137,11 @@ class DepartmentDataState extends State<DepartmentData> {
|
|||||||
errorMessages.clear();
|
errorMessages.clear();
|
||||||
|
|
||||||
final data = {
|
final data = {
|
||||||
"name": controllers["name"]?.text,
|
"dropdown_value": controllers["dropdown_value"]?.text,
|
||||||
"description": controllers["description"]?.text,
|
// "description": controllers["description"]?.text,
|
||||||
};
|
};
|
||||||
|
|
||||||
final requiredFields = ["name", "description"];
|
final requiredFields = ["dropdown_value"];
|
||||||
bool hasFocused = false;
|
bool hasFocused = false;
|
||||||
|
|
||||||
// Check validation for each field
|
// Check validation for each field
|
||||||
@ -129,10 +149,10 @@ class DepartmentDataState extends State<DepartmentData> {
|
|||||||
if (data[field] == null || data[field]!.trim().isEmpty) {
|
if (data[field] == null || data[field]!.trim().isEmpty) {
|
||||||
errorMessages[field] = "Required";
|
errorMessages[field] = "Required";
|
||||||
|
|
||||||
if (!hasFocused) {
|
// if (!hasFocused) {
|
||||||
focusNodes[field]?.requestFocus();
|
// focusNodes[field]?.requestFocus();
|
||||||
hasFocused = true;
|
// hasFocused = true;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +185,7 @@ class DepartmentDataState extends State<DepartmentData> {
|
|||||||
if (departmentDataId != null) {
|
if (departmentDataId != null) {
|
||||||
print("for edit department id - $departmentDataId");
|
print("for edit department id - $departmentDataId");
|
||||||
apiUrldata = '$apiUrl/api/updateDepartment/$departmentDataId';
|
apiUrldata = '$apiUrl/api/updateDepartment/$departmentDataId';
|
||||||
departmentData["department_id"] = departmentDataId.toString();
|
departmentData["id"] = departmentDataId.toString();
|
||||||
departmentData["updated_by"] = userId;
|
departmentData["updated_by"] = userId;
|
||||||
(departmentData.containsKey("created_by"))
|
(departmentData.containsKey("created_by"))
|
||||||
? departmentData.remove("created_by")
|
? departmentData.remove("created_by")
|
||||||
@ -261,14 +281,14 @@ class DepartmentDataState extends State<DepartmentData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["dropdown_valueFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: controllers["name"],
|
controller: controllers["dropdown_value"],
|
||||||
focusNode: focusNodes["name"],
|
focusNode: focusNodes["dropdown_valueFocusNode"],
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Name",
|
labelText: "Name",
|
||||||
@ -280,60 +300,60 @@ class DepartmentDataState extends State<DepartmentData> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (errorMessages["name"] != null) ...[
|
if (errorMessages["dropdown_value"] != null) ...[
|
||||||
SizedBox(height: 5), // Space before error message
|
SizedBox(height: 5), // Space before error message
|
||||||
Text(
|
Text(
|
||||||
errorMessages["name"]!,
|
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: false,
|
|
||||||
isDesktop: widget.isDesktop,
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: SizedBox(
|
|
||||||
height: 100,
|
|
||||||
child: TextField(
|
|
||||||
controller: controllers["description"],
|
|
||||||
focusNode: focusNodes["description"],
|
|
||||||
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),
|
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(height: 15),
|
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)
|
if (departmentDataId != null)
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
|||||||
@ -180,13 +180,13 @@ class DepartmentListState extends State<DepartmentList> {
|
|||||||
allDepartment.where((object) {
|
allDepartment.where((object) {
|
||||||
final isActiveStatus =
|
final isActiveStatus =
|
||||||
object['is_active'] == "1" ? "active" : "inactive";
|
object['is_active'] == "1" ? "active" : "inactive";
|
||||||
return (object['department_id']?.toLowerCase().contains(
|
return (object['id']?.toLowerCase().contains(
|
||||||
lowerQuery,
|
lowerQuery,
|
||||||
) ??
|
) ??
|
||||||
false) ||
|
false) ||
|
||||||
(object['name']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
(object['dropdown_value']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
||||||
(object['description']?.toLowerCase().contains(lowerQuery) ??
|
// (object['description']?.toLowerCase().contains(lowerQuery) ??
|
||||||
false) ||
|
// false) ||
|
||||||
(isActiveStatus.contains(lowerQuery));
|
(isActiveStatus.contains(lowerQuery));
|
||||||
}).toList();
|
}).toList();
|
||||||
currentPage = 0;
|
currentPage = 0;
|
||||||
@ -550,15 +550,15 @@ class DepartmentListState extends State<DepartmentList> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DataColumn(
|
// DataColumn(
|
||||||
label: Text(
|
// label: Text(
|
||||||
'Description',
|
// 'Description',
|
||||||
style: GoogleFonts.poppins(
|
// style: GoogleFonts.poppins(
|
||||||
fontSize: 13,
|
// fontSize: 13,
|
||||||
fontWeight: FontWeight.w600,
|
// fontWeight: FontWeight.w600,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
DataColumn(
|
DataColumn(
|
||||||
label: Text(
|
label: Text(
|
||||||
'Status',
|
'Status',
|
||||||
@ -581,7 +581,7 @@ class DepartmentListState extends State<DepartmentList> {
|
|||||||
rows:
|
rows:
|
||||||
paginatedDepartment.map((tableObject) {
|
paginatedDepartment.map((tableObject) {
|
||||||
String departmentId =
|
String departmentId =
|
||||||
tableObject['department_id']
|
tableObject['id']
|
||||||
.toString(); // Get user ID
|
.toString(); // Get user ID
|
||||||
bool isSelected =
|
bool isSelected =
|
||||||
selectedDepartmentId == departmentId;
|
selectedDepartmentId == departmentId;
|
||||||
@ -590,24 +590,24 @@ class DepartmentListState extends State<DepartmentList> {
|
|||||||
cells: [
|
cells: [
|
||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
tableObject['name'] ?? '',
|
tableObject['dropdown_value'] ?? '',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontFamily: "Inter",
|
fontFamily: "Inter",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DataCell(
|
// DataCell(
|
||||||
Text(
|
// Text(
|
||||||
tableObject['description'] ?? 'N/A',
|
// tableObject['description'] ?? 'N/A',
|
||||||
style: TextStyle(
|
// style: TextStyle(
|
||||||
fontSize: 13,
|
// fontSize: 13,
|
||||||
fontFamily: "Inter",
|
// fontFamily: "Inter",
|
||||||
),
|
// ),
|
||||||
softWrap: true,
|
// softWrap: true,
|
||||||
overflow: TextOverflow.ellipsis,
|
// overflow: TextOverflow.ellipsis,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
tableObject['is_active'] == "1"
|
tableObject['is_active'] == "1"
|
||||||
@ -645,7 +645,7 @@ class DepartmentListState extends State<DepartmentList> {
|
|||||||
// final usersData = await getUserDetails(userId);
|
// final usersData = await getUserDetails(userId);
|
||||||
//
|
//
|
||||||
final departmentId = int.tryParse(
|
final departmentId = int.tryParse(
|
||||||
tableObject['department_id']
|
tableObject['id']
|
||||||
.toString(),
|
.toString(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -716,7 +716,7 @@ class DepartmentListState extends State<DepartmentList> {
|
|||||||
MainAxisAlignment.spaceBetween,
|
MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
cardObject['name'] ?? 'N/A',
|
cardObject['dropdown_value'] ?? 'N/A',
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
@ -738,7 +738,7 @@ class DepartmentListState extends State<DepartmentList> {
|
|||||||
// final usersData = await getUserDetails(userId);
|
// final usersData = await getUserDetails(userId);
|
||||||
//
|
//
|
||||||
final departmentId = int.tryParse(
|
final departmentId = int.tryParse(
|
||||||
cardObject['department_id']
|
cardObject['id']
|
||||||
.toString(),
|
.toString(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -852,37 +852,37 @@ class DepartmentListState extends State<DepartmentList> {
|
|||||||
SizedBox(height: 2),
|
SizedBox(height: 2),
|
||||||
// Trip Id and Trip Name
|
// Trip Id and Trip Name
|
||||||
// Name
|
// Name
|
||||||
Row(
|
// Row(
|
||||||
children: [
|
// children: [
|
||||||
Column(
|
// Column(
|
||||||
crossAxisAlignment:
|
// crossAxisAlignment:
|
||||||
CrossAxisAlignment.start,
|
// CrossAxisAlignment.start,
|
||||||
children: [
|
// children: [
|
||||||
Text(
|
// Text(
|
||||||
cardObject['description'] ?? '',
|
// cardObject['description'] ?? '',
|
||||||
style: GoogleFonts.poppins(
|
// style: GoogleFonts.poppins(
|
||||||
fontSize: 10,
|
// fontSize: 10,
|
||||||
color: Colors.black87,
|
// color: Colors.black87,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
SizedBox(width: 10),
|
// SizedBox(width: 10),
|
||||||
Column(
|
// Column(
|
||||||
crossAxisAlignment:
|
// crossAxisAlignment:
|
||||||
CrossAxisAlignment.start,
|
// CrossAxisAlignment.start,
|
||||||
children: [
|
// children: [
|
||||||
Text(
|
// Text(
|
||||||
cardObject['description'] ?? '',
|
// cardObject['description'] ?? '',
|
||||||
style: GoogleFonts.poppins(
|
// style: GoogleFonts.poppins(
|
||||||
fontSize: 10,
|
// fontSize: 10,
|
||||||
color: Colors.black87,
|
// color: Colors.black87,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
// Actions
|
// Actions
|
||||||
// Actions
|
// Actions
|
||||||
],
|
],
|
||||||
|
|||||||
@ -42,6 +42,8 @@ class HotelsDataState extends State<HotelsData> {
|
|||||||
Map<String, dynamic>? apiData;
|
Map<String, dynamic>? apiData;
|
||||||
final Map<String, TextEditingController> controllers = {};
|
final Map<String, TextEditingController> controllers = {};
|
||||||
Map<String, String> errorMessages = {};
|
Map<String, String> errorMessages = {};
|
||||||
|
Map<String, FocusNode> focusNodes = {};
|
||||||
|
Map<String, bool> focusStates = {};
|
||||||
|
|
||||||
List<dynamic> countryList = [];
|
List<dynamic> countryList = [];
|
||||||
String? selectedCountry;
|
String? selectedCountry;
|
||||||
@ -83,6 +85,15 @@ class HotelsDataState extends State<HotelsData> {
|
|||||||
apiData = null;
|
apiData = null;
|
||||||
for (var field in dataHeader) {
|
for (var field in dataHeader) {
|
||||||
controllers[field] = TextEditingController();
|
controllers[field] = TextEditingController();
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
fetchCountries();
|
fetchCountries();
|
||||||
if (widget.hotelsId != null) {
|
if (widget.hotelsId != null) {
|
||||||
@ -103,8 +114,18 @@ class HotelsDataState extends State<HotelsData> {
|
|||||||
for (var controller in controllers.values) {
|
for (var controller in controllers.values) {
|
||||||
controller.dispose();
|
controller.dispose();
|
||||||
}
|
}
|
||||||
|
for (var node in focusNodes.values) {
|
||||||
|
node.dispose();
|
||||||
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
void _addFocusListener(FocusNode node, Function(bool) updateState) {
|
||||||
|
node.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
updateState(node.hasFocus);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void updateHotelsDetails() {
|
void updateHotelsDetails() {
|
||||||
print("Update - ${widget.hotelsData}");
|
print("Update - ${widget.hotelsData}");
|
||||||
@ -312,12 +333,14 @@ class HotelsDataState extends State<HotelsData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
// isFocused: false,
|
||||||
|
isFocused: focusStates["hotel_nameFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
focusNode: focusNodes["hotel_nameFocusNode"],
|
||||||
controller: controllers["hotel_name"],
|
controller: controllers["hotel_name"],
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
@ -353,12 +376,13 @@ class HotelsDataState extends State<HotelsData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["hotel_chainFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
focusNode: focusNodes["hotel_chainFocusNode"],
|
||||||
controller: controllers["hotel_chain"],
|
controller: controllers["hotel_chain"],
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
@ -394,12 +418,14 @@ class HotelsDataState extends State<HotelsData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
// isFocused: false,
|
||||||
|
isFocused: focusStates["categoryFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
focusNode: focusNodes["categoryFocusNode"],
|
||||||
controller: controllers["category"],
|
controller: controllers["category"],
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 ]')),
|
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 ]')),
|
||||||
@ -432,20 +458,34 @@ class HotelsDataState extends State<HotelsData> {
|
|||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: false,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 0),
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
|
width: double.infinity,
|
||||||
|
child: Focus(
|
||||||
|
focusNode: focusNodes["country_codeFocusNode"],
|
||||||
|
onFocusChange: (hasFocus) {
|
||||||
|
setState(() {
|
||||||
|
focusStates["country_codeFocused"] = hasFocus;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
// Request focus when user taps
|
||||||
|
focusNodes["country_codeFocusNode"]?.requestFocus();
|
||||||
|
},
|
||||||
child: DropdownSearch<String>(
|
child: DropdownSearch<String>(
|
||||||
selectedItem: countryMap[selectedCountry],
|
selectedItem: countryMap[selectedCountry],
|
||||||
popupProps: PopupProps.menu(
|
popupProps: PopupProps.menu(
|
||||||
showSearchBox: true, // Enables search functionality
|
showSearchBox: true, // Enables search functionality
|
||||||
menuProps: const MenuProps(backgroundColor: Colors.white),
|
menuProps: const MenuProps(backgroundColor: Colors.white),
|
||||||
constraints: BoxConstraints(maxHeight: 250),
|
constraints: BoxConstraints(maxHeight: 200),
|
||||||
itemBuilder:
|
itemBuilder:
|
||||||
(context, item, isSelected) => Padding(
|
(context, item, isSelected) => Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 8.0,
|
horizontal: 10.0,
|
||||||
vertical: 6.0,
|
vertical: 8.0,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
item,
|
item,
|
||||||
@ -463,8 +503,33 @@ class HotelsDataState extends State<HotelsData> {
|
|||||||
items: countryMap.values.toList(),
|
items: countryMap.values.toList(),
|
||||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||||
dropdownSearchDecoration: InputDecoration(
|
dropdownSearchDecoration: InputDecoration(
|
||||||
border: InputBorder.none,
|
// border: InputBorder.none,
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 1),
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color:
|
||||||
|
(focusStates["country_codeFocused"] ?? false)
|
||||||
|
? widget.layoutColor!
|
||||||
|
: Colors.white,
|
||||||
|
// width: 0.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color:
|
||||||
|
(focusStates["country_codeFocused"] ?? false)
|
||||||
|
? widget.layoutColor!
|
||||||
|
: Colors.white,
|
||||||
|
// : const Color(0xFFD6D5E6),
|
||||||
|
// width: 0.5,
|
||||||
|
// const Color(0xFFD6D5E6),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: widget.layoutColor!, width: 1),
|
||||||
|
),
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 10.0,
|
||||||
|
vertical: 8.0,),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
dropdownBuilder:
|
dropdownBuilder:
|
||||||
@ -487,6 +552,8 @@ class HotelsDataState extends State<HotelsData> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (errorMessages["country_code"] != null) ...[
|
if (errorMessages["country_code"] != null) ...[
|
||||||
@ -512,12 +579,13 @@ class HotelsDataState extends State<HotelsData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["cityFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
focusNode: focusNodes["cityFocusNode"],
|
||||||
controller: controllers["city"],
|
controller: controllers["city"],
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
|
|||||||
@ -33,6 +33,7 @@ import '../../routes/custom_appBar.dart';
|
|||||||
import '../../routes/custom_drawer.dart';
|
import '../../routes/custom_drawer.dart';
|
||||||
import '../../services/apiService.dart';
|
import '../../services/apiService.dart';
|
||||||
import '../../utils/auth_utils.dart';
|
import '../../utils/auth_utils.dart';
|
||||||
|
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||||
import '../../widgets/custom_user_travel.dart';
|
import '../../widgets/custom_user_travel.dart';
|
||||||
import 'dialog_placeholders.dart';
|
import 'dialog_placeholders.dart';
|
||||||
|
|
||||||
@ -60,6 +61,8 @@ class TemplateState extends State<Template> {
|
|||||||
final Map<String, TextEditingController> controllers = {};
|
final Map<String, TextEditingController> controllers = {};
|
||||||
List<String> dataHeader = ["subject"];
|
List<String> dataHeader = ["subject"];
|
||||||
List<String> placeholders = [];
|
List<String> placeholders = [];
|
||||||
|
Map<String, FocusNode> focusNodes = {};
|
||||||
|
Map<String, bool> focusStates = {};
|
||||||
|
|
||||||
late QuillController _controller = QuillController.basic();
|
late QuillController _controller = QuillController.basic();
|
||||||
final FocusNode _focusNode = FocusNode();
|
final FocusNode _focusNode = FocusNode();
|
||||||
@ -103,6 +106,15 @@ class TemplateState extends State<Template> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_checkAuthAndLoadData();
|
_checkAuthAndLoadData();
|
||||||
|
focusNodes["subjectFocusNode"] = FocusNode();
|
||||||
|
focusStates["subjectFocused"] = false;
|
||||||
|
for (var key in focusNodes.keys) {
|
||||||
|
_addFocusListener(focusNodes[key]!, (focus) {
|
||||||
|
setState(() {
|
||||||
|
focusStates[key.replaceFirst("FocusNode", "Focused")] = focus;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// for (var field in dataHeader) {
|
// for (var field in dataHeader) {
|
||||||
// controllers[field] = TextEditingController();
|
// controllers[field] = TextEditingController();
|
||||||
@ -144,6 +156,13 @@ class TemplateState extends State<Template> {
|
|||||||
// _editorFocusNode.dispose();
|
// _editorFocusNode.dispose();
|
||||||
// super.dispose();
|
// super.dispose();
|
||||||
// }
|
// }
|
||||||
|
void _addFocusListener(FocusNode node, Function(bool) updateState) {
|
||||||
|
node.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
updateState(node.hasFocus);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
void loadinitializeData() async {
|
void loadinitializeData() async {
|
||||||
orgId = await getOrgId();
|
orgId = await getOrgId();
|
||||||
userId = await getUserId();
|
userId = await getUserId();
|
||||||
@ -529,15 +548,40 @@ class TemplateState extends State<Template> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
// Text(
|
||||||
formatTemplateName(templateName),
|
// formatTemplateName(templateName),
|
||||||
style: GoogleFonts.poppins(
|
// style: GoogleFonts.poppins(
|
||||||
fontSize: 18,
|
// fontSize: 18,
|
||||||
fontWeight: FontWeight.w400,
|
// fontWeight: FontWeight.w400,
|
||||||
color: Colors.black,
|
// color: Colors.black,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
BreadcrumbNavigation(
|
||||||
|
isDesktop: isDesktop,
|
||||||
|
breadcrumbItems: [
|
||||||
|
BreadcrumbItem(
|
||||||
|
title: 'Organization Settings',
|
||||||
|
tooltip: 'Go To Organization Settings',
|
||||||
|
onTap: (context) {
|
||||||
|
context.go("/OrganizationSettings");
|
||||||
|
}
|
||||||
),
|
),
|
||||||
|
BreadcrumbItem(
|
||||||
|
title: 'Templates',
|
||||||
|
tooltip: 'Go To Templates',
|
||||||
|
onTap: (context) {
|
||||||
|
context.go("/templateList");
|
||||||
|
}
|
||||||
|
),
|
||||||
|
BreadcrumbItem(
|
||||||
|
title: formatTemplateName(templateName),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
buildTempalteSubject(isDesktop),
|
buildTempalteSubject(isDesktop),
|
||||||
|
|
||||||
@ -565,7 +609,8 @@ class TemplateState extends State<Template> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldUserTravellerWrapper(
|
CustomTextFieldUserTravellerWrapper(
|
||||||
isFocused: false,
|
// isFocused: false,
|
||||||
|
isFocused: focusStates["subjectFocused"] ?? false,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.8 : null,
|
width: isDesktop ? MediaQuery.of(context).size.width * 0.8 : null,
|
||||||
isDesktop: isDesktop,
|
isDesktop: isDesktop,
|
||||||
@ -573,6 +618,7 @@ class TemplateState extends State<Template> {
|
|||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||||
|
focusNode: focusNodes["subjectNode"],
|
||||||
controller: controllers["subject"],
|
controller: controllers["subject"],
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
// _clearError("local_id_num");
|
// _clearError("local_id_num");
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import '../../routes/custom_drawer.dart';
|
|||||||
import '../../services/apiService.dart';
|
import '../../services/apiService.dart';
|
||||||
import '../../utils/auth_utils.dart';
|
import '../../utils/auth_utils.dart';
|
||||||
import '../../utils/pagination.dart';
|
import '../../utils/pagination.dart';
|
||||||
|
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||||
import '../../widgets/popup_userList_action.dart';
|
import '../../widgets/popup_userList_action.dart';
|
||||||
|
|
||||||
class TemplatesList extends StatefulWidget {
|
class TemplatesList extends StatefulWidget {
|
||||||
@ -432,12 +433,29 @@ class TemplatesListState extends State<TemplatesList> {
|
|||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
// Text(
|
||||||
'Templates',
|
// 'Templates',
|
||||||
style: GoogleFonts.poppins(
|
// style: GoogleFonts.poppins(
|
||||||
fontSize: isDesktop ? 16 : 14,
|
// fontSize: isDesktop ? 16 : 14,
|
||||||
fontWeight: FontWeight.w600,
|
// fontWeight: FontWeight.w600,
|
||||||
color: Colors.black,
|
// color: Colors.black,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
Container(
|
||||||
|
child: BreadcrumbNavigation(
|
||||||
|
isDesktop: isDesktop,
|
||||||
|
breadcrumbItems: [
|
||||||
|
BreadcrumbItem(
|
||||||
|
title: 'Organization Settings',
|
||||||
|
tooltip: 'Go To Organization Settings',
|
||||||
|
onTap: (context) {
|
||||||
|
context.go("/OrganizationSettings");
|
||||||
|
}
|
||||||
|
),
|
||||||
|
BreadcrumbItem(
|
||||||
|
title: 'Templates',
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -42,6 +42,8 @@ class ForexDataState extends State<ForexData> {
|
|||||||
Map<String, dynamic>? apiData;
|
Map<String, dynamic>? apiData;
|
||||||
final Map<String, TextEditingController> controllers = {};
|
final Map<String, TextEditingController> controllers = {};
|
||||||
Map<String, String> errorMessages = {};
|
Map<String, String> errorMessages = {};
|
||||||
|
Map<String, FocusNode> focusNodes = {};
|
||||||
|
Map<String, bool> focusStates = {};
|
||||||
|
|
||||||
List<dynamic> countryList = [];
|
List<dynamic> countryList = [];
|
||||||
String? selectedCountry;
|
String? selectedCountry;
|
||||||
@ -89,6 +91,15 @@ class ForexDataState extends State<ForexData> {
|
|||||||
apiData = null;
|
apiData = null;
|
||||||
for (var field in dataHeader) {
|
for (var field in dataHeader) {
|
||||||
controllers[field] = TextEditingController();
|
controllers[field] = TextEditingController();
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
fetchCountries();
|
fetchCountries();
|
||||||
|
|
||||||
@ -113,8 +124,18 @@ class ForexDataState extends State<ForexData> {
|
|||||||
for (var controller in controllers.values) {
|
for (var controller in controllers.values) {
|
||||||
controller.dispose();
|
controller.dispose();
|
||||||
}
|
}
|
||||||
|
for (var node in focusNodes.values) {
|
||||||
|
node.dispose();
|
||||||
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
void _addFocusListener(FocusNode node, Function(bool) updateState) {
|
||||||
|
node.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
updateState(node.hasFocus);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void updateForexDetails() {
|
void updateForexDetails() {
|
||||||
print("Updateeee - ${widget.forexData}");
|
print("Updateeee - ${widget.forexData}");
|
||||||
@ -383,9 +404,23 @@ class ForexDataState extends State<ForexData> {
|
|||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: false,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 0),
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
|
width: double.infinity,
|
||||||
|
child: Focus(
|
||||||
|
focusNode: focusNodes["country_codeFocusNode"],
|
||||||
|
onFocusChange: (hasFocus) {
|
||||||
|
setState(() {
|
||||||
|
focusStates["country_codeFocused"] = hasFocus;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
// Request focus when user taps
|
||||||
|
focusNodes["country_codeFocusNode"]?.requestFocus();
|
||||||
|
},
|
||||||
child: DropdownSearch<String>(
|
child: DropdownSearch<String>(
|
||||||
selectedItem: countryMap[selectedCountry],
|
selectedItem: countryMap[selectedCountry],
|
||||||
popupProps: PopupProps.menu(
|
popupProps: PopupProps.menu(
|
||||||
@ -395,8 +430,8 @@ class ForexDataState extends State<ForexData> {
|
|||||||
itemBuilder:
|
itemBuilder:
|
||||||
(context, item, isSelected) => Padding(
|
(context, item, isSelected) => Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 8.0,
|
horizontal: 10.0,
|
||||||
vertical: 6.0,
|
vertical: 8.0,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
item,
|
item,
|
||||||
@ -414,8 +449,33 @@ class ForexDataState extends State<ForexData> {
|
|||||||
items: countryMap.values.toList(),
|
items: countryMap.values.toList(),
|
||||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||||
dropdownSearchDecoration: InputDecoration(
|
dropdownSearchDecoration: InputDecoration(
|
||||||
border: InputBorder.none,
|
// border: InputBorder.none,
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 1),
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color:
|
||||||
|
(focusStates["country_codeFocused"] ?? false)
|
||||||
|
? widget.layoutColor!
|
||||||
|
: Colors.white,
|
||||||
|
// width: 0.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color:
|
||||||
|
(focusStates["country_codeFocused"] ?? false)
|
||||||
|
? widget.layoutColor!
|
||||||
|
: Colors.white,
|
||||||
|
// : const Color(0xFFD6D5E6),
|
||||||
|
// width: 0.5,
|
||||||
|
// const Color(0xFFD6D5E6),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: widget.layoutColor!, width: 1),
|
||||||
|
),
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 10.0,
|
||||||
|
vertical: 8.0,),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
dropdownBuilder:
|
dropdownBuilder:
|
||||||
@ -439,6 +499,8 @@ class ForexDataState extends State<ForexData> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (errorMessages["country_code"] != null) ...[
|
if (errorMessages["country_code"] != null) ...[
|
||||||
@ -464,7 +526,7 @@ class ForexDataState extends State<ForexData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["currencyFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
|
|
||||||
@ -474,6 +536,7 @@ class ForexDataState extends State<ForexData> {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
focusNode: focusNodes["currencyFocusNode"],
|
||||||
controller: controllers["currency"],
|
controller: controllers["currency"],
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
@ -518,7 +581,7 @@ class ForexDataState extends State<ForexData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["cashFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
width:
|
width:
|
||||||
@ -528,6 +591,7 @@ class ForexDataState extends State<ForexData> {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
focusNode: focusNodes["cashFocusNode"],
|
||||||
controller: controllers["cash"],
|
controller: controllers["cash"],
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
@ -570,7 +634,7 @@ class ForexDataState extends State<ForexData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["cardFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
width:
|
width:
|
||||||
@ -580,6 +644,7 @@ class ForexDataState extends State<ForexData> {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
focusNode: focusNodes["cardFocusNode"],
|
||||||
controller: controllers["card"],
|
controller: controllers["card"],
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
@ -624,12 +689,13 @@ class ForexDataState extends State<ForexData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["perdiemAmountFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
focusNode: focusNodes["perdiemAmountFocusNode"],
|
||||||
controller: controllers["perdiemAmount"],
|
controller: controllers["perdiemAmount"],
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
|
|||||||
@ -57,6 +57,8 @@ class _PolicyState extends State<Policy> {
|
|||||||
// ValueNotifier<String> selectedService = ValueNotifier("Train");
|
// ValueNotifier<String> selectedService = ValueNotifier("Train");
|
||||||
bool isViewMode = false;
|
bool isViewMode = false;
|
||||||
|
|
||||||
|
Map<String, FocusNode> focusNodes = {};
|
||||||
|
Map<String, bool> focusStates = {};
|
||||||
Map<String, String> errorMessages = {};
|
Map<String, String> errorMessages = {};
|
||||||
|
|
||||||
String? selectedPolicyId;
|
String? selectedPolicyId;
|
||||||
@ -68,7 +70,7 @@ class _PolicyState extends State<Policy> {
|
|||||||
String? userId;
|
String? userId;
|
||||||
|
|
||||||
bool showClass = true;
|
bool showClass = true;
|
||||||
bool showCost = true;
|
bool showCost = false; // bool showCost = true; // on 21st june
|
||||||
|
|
||||||
List<dynamic>? selectedAllServices;
|
List<dynamic>? selectedAllServices;
|
||||||
List<Map<String, String>> selectedOrgServiceIds = [];
|
List<Map<String, String>> selectedOrgServiceIds = [];
|
||||||
@ -97,6 +99,7 @@ class _PolicyState extends State<Policy> {
|
|||||||
});
|
});
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
|
|
||||||
Map<String, dynamic> data = {
|
Map<String, dynamic> data = {
|
||||||
"name": _policyController.text,
|
"name": _policyController.text,
|
||||||
"domestic": SelectedDomestic,
|
"domestic": SelectedDomestic,
|
||||||
@ -115,6 +118,10 @@ class _PolicyState extends State<Policy> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_checkAuthAndLoadData();
|
_checkAuthAndLoadData();
|
||||||
|
// for (var field in dataHeader) {
|
||||||
|
// focusNodes["${field}FocusNode"] = FocusNode();
|
||||||
|
// focusStates["${field}Focused"] = false;
|
||||||
|
// }
|
||||||
// WidgetsFlutterBinding.ensureInitialized();
|
// WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
@ -1104,18 +1111,21 @@ class _PolicyState extends State<Policy> {
|
|||||||
// policyCriteriaKey.currentState?.fieldForPolicy();
|
// policyCriteriaKey.currentState?.fieldForPolicy();
|
||||||
// policyCriteriaKey.currentState
|
// policyCriteriaKey.currentState
|
||||||
// ?.addOrUpdatePolicy(selectedServiceIndex.value);
|
// ?.addOrUpdatePolicy(selectedServiceIndex.value);
|
||||||
|
print("policyselectedService - $selectedService");
|
||||||
if (selectedService == "Flight" ||
|
if (selectedService == "Flight" ||
|
||||||
selectedService == "Train") {
|
selectedService == "Train" || selectedService == "Accomodation") {
|
||||||
showClass = true;
|
|
||||||
showCost = true;
|
|
||||||
int serviceCode = selectedService == "Flight" ? 1 : 2;
|
|
||||||
|
|
||||||
policyCriteriaKey.currentState
|
|
||||||
?.fetchTrainFlightClass();
|
|
||||||
} else if (selectedService == "Accommodation") {
|
|
||||||
showClass = true;
|
showClass = true;
|
||||||
showCost = false;
|
showCost = false;
|
||||||
} else {
|
int serviceCode = selectedService == "Flight" ? 1 : 2;
|
||||||
|
print("policyselectedService1 - $selectedService");
|
||||||
|
policyCriteriaKey.currentState
|
||||||
|
?.fetchTrainFlightClass();
|
||||||
|
}
|
||||||
|
// else if (selectedService == "Accommodation") {
|
||||||
|
// showClass = true;
|
||||||
|
// showCost = false;
|
||||||
|
// }
|
||||||
|
else {
|
||||||
showClass = false;
|
showClass = false;
|
||||||
showCost = false;
|
showCost = false;
|
||||||
}
|
}
|
||||||
@ -1330,7 +1340,7 @@ class _PolicyState extends State<Policy> {
|
|||||||
Text(
|
Text(
|
||||||
"Domestic",
|
"Domestic",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
color: _selectedTripType == "1" ? Colors.white : Colors.black,
|
color: _selectedTripType == "1" ? Colors.black : Colors.black,
|
||||||
fontWeight: _selectedTripType == "1" ? FontWeight.w600 : null,
|
fontWeight: _selectedTripType == "1" ? FontWeight.w600 : null,
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
),
|
),
|
||||||
@ -1356,13 +1366,13 @@ class _PolicyState extends State<Policy> {
|
|||||||
borderRadius: BorderRadius.circular(4), // Rounded rectangle
|
borderRadius: BorderRadius.circular(4), // Rounded rectangle
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color:
|
color:
|
||||||
_selectedTripType == "1" ? Colors.white : Colors.black,
|
_selectedTripType == "1" ? Colors.green : Colors.black,
|
||||||
width: _selectedTripType == "1" ? 2 : 1,
|
width: _selectedTripType == "1" ? 2 : 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child:
|
child:
|
||||||
_selectedTripType == "1"
|
_selectedTripType == "1"
|
||||||
? Icon(Icons.rectangle, size: 8, color: Colors.white)
|
? Icon(Icons.rectangle, size: 8, color: Colors.green)
|
||||||
: null, // Add checkmark if selected
|
: null, // Add checkmark if selected
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1387,7 +1397,7 @@ class _PolicyState extends State<Policy> {
|
|||||||
"International",
|
"International",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: _selectedTripType == "2" ? Colors.white : Colors.black,
|
color: _selectedTripType == "2" ? Colors.black : Colors.black,
|
||||||
fontWeight: _selectedTripType == "2" ? FontWeight.w600 : null,
|
fontWeight: _selectedTripType == "2" ? FontWeight.w600 : null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1412,13 +1422,13 @@ class _PolicyState extends State<Policy> {
|
|||||||
borderRadius: BorderRadius.circular(4), // Rounded rectangle
|
borderRadius: BorderRadius.circular(4), // Rounded rectangle
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color:
|
color:
|
||||||
_selectedTripType == "2" ? Colors.white : Colors.black,
|
_selectedTripType == "2" ? Colors.green : Colors.black,
|
||||||
width: _selectedTripType == "2" ? 2 : 1,
|
width: _selectedTripType == "2" ? 2 : 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child:
|
child:
|
||||||
_selectedTripType == "2"
|
_selectedTripType == "2"
|
||||||
? Icon(Icons.rectangle, size: 8, color: Colors.white)
|
? Icon(Icons.rectangle, size: 8, color: Colors.green)
|
||||||
: null, // Add checkmark if selected
|
: null, // Add checkmark if selected
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -112,9 +112,12 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
|
|
||||||
String getTabName(int index) {
|
String getTabName(int index) {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0: return "domestic";
|
case 0:
|
||||||
case 1: return "international";
|
return "domestic";
|
||||||
default: return "domestic"; // return "Unknown";
|
case 1:
|
||||||
|
return "international";
|
||||||
|
default:
|
||||||
|
return "domestic"; // return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,35 +335,62 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
excelName,
|
excelName,
|
||||||
);
|
);
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
// ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
// SnackBar(
|
||||||
backgroundColor: Colors.green,
|
// backgroundColor: result['status'] ? Colors.green : Colors.red,
|
||||||
content: Text(result as String),
|
// content: Text(result['message']),
|
||||||
behavior: SnackBarBehavior.floating,
|
// behavior: SnackBarBehavior.floating,
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDomesticFilter(String query) {
|
void handleDomesticFilter(String query) {
|
||||||
|
|
||||||
final lowerQuery = query.toLowerCase();
|
final lowerQuery = query.toLowerCase();
|
||||||
setState(() {
|
setState(() {
|
||||||
filteredDomestic =
|
filteredDomestic =
|
||||||
domesticData.where((object) {
|
domesticData.where((object) {
|
||||||
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
final travelDateRaw = object['flight_travel_date'];
|
||||||
(object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
String formattedDate = '';
|
||||||
(object['customer_name']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
|
||||||
(object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
if (travelDateRaw != null && travelDateRaw is String) {
|
||||||
(object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
try {
|
||||||
(object['flight_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
final parsedDate = DateTime.parse(travelDateRaw);
|
||||||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
formattedDate =
|
||||||
(object['flight_class']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
'${parsedDate.day.toString().padLeft(2, '0')}-${parsedDate.month.toString().padLeft(2, '0')}-${parsedDate.year}';
|
||||||
(object['flight_travel_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
} catch (e) {
|
||||||
|
// fallback if date is not parsable
|
||||||
|
formattedDate = travelDateRaw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(object['employee_code']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(object['customer_name']?.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['flight_class']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(formattedDate.toLowerCase().contains(lowerQuery)) ||
|
||||||
(object['sector']?.toLowerCase().contains(lowerQuery));
|
(object['sector']?.toLowerCase().contains(lowerQuery));
|
||||||
}).toList();
|
}).toList();
|
||||||
currentPage1 = 0;
|
currentPage1 = 0;
|
||||||
});
|
});
|
||||||
print("handleDomesticFilter > Total entries: ${filteredDomestic?.length ?? 0}");
|
print(
|
||||||
|
"handleDomesticFilter > Total entries: ${filteredDomestic?.length ?? 0}",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleInternationalFilter(String query) {
|
void handleInternationalFilter(String query) {
|
||||||
@ -368,23 +398,49 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
setState(() {
|
setState(() {
|
||||||
filteredInternational =
|
filteredInternational =
|
||||||
internationalData.where((object) {
|
internationalData.where((object) {
|
||||||
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
final travelDateRaw = object['flight_travel_date'];
|
||||||
(object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
String formattedDate = '';
|
||||||
(object['customer_name']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
|
||||||
(object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
if (travelDateRaw != null && travelDateRaw is String) {
|
||||||
(object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
try {
|
||||||
(object['flight_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
final parsedDate = DateTime.parse(travelDateRaw);
|
||||||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
formattedDate =
|
||||||
(object['flight_class']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
'${parsedDate.day.toString().padLeft(2, '0')}-${parsedDate.month.toString().padLeft(2, '0')}-${parsedDate.year}';
|
||||||
(object['flight_travel_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
} catch (e) {
|
||||||
|
// fallback if date is not parsable
|
||||||
|
formattedDate = travelDateRaw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(object['employee_code']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(object['customer_name']?.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['flight_class']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(formattedDate.toLowerCase().contains(lowerQuery)) ||
|
||||||
(object['sector']?.toLowerCase().contains(lowerQuery));
|
(object['sector']?.toLowerCase().contains(lowerQuery));
|
||||||
}).toList();
|
}).toList();
|
||||||
currentPage2 = 0;
|
currentPage2 = 0;
|
||||||
});
|
});
|
||||||
print("handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}");
|
print(
|
||||||
|
"handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// Widget build(BuildContext context) {
|
// Widget build(BuildContext context) {
|
||||||
// // TODO: implement build
|
// // TODO: implement build
|
||||||
@ -456,7 +512,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
children: [
|
children: [
|
||||||
buildTitle(isDesktop),
|
buildTitle(isDesktop),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
buildExports(isDesktop)
|
buildExports(isDesktop),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: Column(
|
: Column(
|
||||||
@ -464,9 +520,9 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
children: [
|
children: [
|
||||||
buildTitle(isDesktop),
|
buildTitle(isDesktop),
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
buildExports(isDesktop)
|
buildExports(isDesktop),
|
||||||
],
|
],
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
|
|
||||||
@ -523,13 +579,34 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
: domesticData.isEmpty
|
: domesticData.isEmpty
|
||||||
? Center(
|
? Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Text(
|
child: Column(
|
||||||
"No data found",
|
mainAxisSize: MainAxisSize.min,
|
||||||
style: GoogleFonts.poppins(
|
children: [
|
||||||
fontSize: 14,
|
SizedBox(
|
||||||
fontWeight: FontWeight.w500,
|
height:
|
||||||
|
MediaQuery.of(context).size.height / 4,
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
"No Records Found",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Please ensure the selected dates contain report data.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -561,7 +638,9 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.2,
|
width:
|
||||||
|
MediaQuery.of(context).size.width *
|
||||||
|
0.2,
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: searchDomesticController,
|
controller: searchDomesticController,
|
||||||
@ -578,24 +657,32 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
size: 18,
|
size: 18,
|
||||||
),
|
),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade200,
|
color: Colors.grey.shade200,
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade300,
|
color: Colors.grey.shade300,
|
||||||
width: 1,
|
width: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
style: GoogleFonts.poppins(fontSize: 12),
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// SizedBox(width: 16),
|
// SizedBox(width: 16),
|
||||||
@ -703,8 +790,10 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
final double minWidth =
|
final double minWidth =
|
||||||
isDesktop ? constraints.maxWidth : 1300;
|
isDesktop ? constraints.maxWidth : 1300;
|
||||||
|
|
||||||
List<Map<String, dynamic>> newDomesticData =filteredDomestic.isNotEmpty ? filteredDomestic : domesticData;
|
List<Map<String, dynamic>> newDomesticData =
|
||||||
|
filteredDomestic.isNotEmpty
|
||||||
|
? filteredDomestic
|
||||||
|
: domesticData;
|
||||||
|
|
||||||
// Pagination logic
|
// Pagination logic
|
||||||
List<Map<String, dynamic>>
|
List<Map<String, dynamic>>
|
||||||
@ -714,14 +803,43 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
.take(itemsPerPage1)
|
.take(itemsPerPage1)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return (
|
return ((searchDomesticController
|
||||||
(searchDomesticController.text.isNotEmpty && filteredDomestic.isEmpty)
|
.text
|
||||||
|
.isNotEmpty &&
|
||||||
|
filteredDomestic.isEmpty)
|
||||||
? Center(
|
? Center(
|
||||||
child: Text(
|
child: Padding(
|
||||||
"No data found",
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height:
|
||||||
|
MediaQuery.of(
|
||||||
|
context,
|
||||||
|
).size.height /
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"No Records Found",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 14,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Please ensure the selected dates contain report data.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -729,17 +847,21 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection:
|
||||||
|
Axis.horizontal,
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
minWidth: minWidth,
|
minWidth: minWidth,
|
||||||
),
|
),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection:
|
||||||
|
Axis.vertical,
|
||||||
child: DataTable(
|
child: DataTable(
|
||||||
dividerThickness: 0.5,
|
dividerThickness: 0.5,
|
||||||
columnSpacing:
|
columnSpacing:
|
||||||
isDesktop ? 30.0 : 24.0,
|
isDesktop
|
||||||
|
? 30.0
|
||||||
|
: 24.0,
|
||||||
border: TableBorder(
|
border: TableBorder(
|
||||||
horizontalInside:
|
horizontalInside:
|
||||||
BorderSide(
|
BorderSide(
|
||||||
@ -877,8 +999,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['plan_id']}',
|
'${entry['plan_id']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -887,8 +1008,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['employee_code']}',
|
'${entry['employee_code']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -897,8 +1017,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['so_number']}',
|
'${entry['so_number']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -907,8 +1026,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['functional_department']}',
|
'${entry['functional_department']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -917,8 +1035,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['flight_trip_type']}',
|
'${entry['flight_trip_type']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -927,8 +1044,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['plan_trip_type']}',
|
'${entry['plan_trip_type']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -937,8 +1053,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['sector']}',
|
'${entry['sector']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -947,8 +1062,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['flight_class']}',
|
'${entry['flight_class']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -957,8 +1071,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
flightTravelDate,
|
flightTravelDate,
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -977,7 +1090,8 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
PaginationControls(
|
PaginationControls(
|
||||||
currentPage: currentPage1,
|
currentPage: currentPage1,
|
||||||
itemsPerPage: itemsPerPage1,
|
itemsPerPage: itemsPerPage1,
|
||||||
totalItems: newDomesticData.length,
|
totalItems:
|
||||||
|
newDomesticData.length,
|
||||||
activeColor: layoutColor,
|
activeColor: layoutColor,
|
||||||
onPageChanged: (page) {
|
onPageChanged: (page) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -1003,13 +1117,34 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
internationalData.isEmpty
|
internationalData.isEmpty
|
||||||
? Center(
|
? Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Text(
|
child: Column(
|
||||||
"No data found",
|
mainAxisSize: MainAxisSize.min,
|
||||||
style: GoogleFonts.poppins(
|
children: [
|
||||||
fontSize: 14,
|
SizedBox(
|
||||||
fontWeight: FontWeight.w500,
|
height:
|
||||||
|
MediaQuery.of(context).size.height / 4,
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
"No Records Found",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Please ensure the selected dates contain report data.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -1140,7 +1275,8 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
vertical: 8,
|
vertical: 8,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
/// Title on the left
|
/// Title on the left
|
||||||
@ -1152,17 +1288,21 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Colors.grey[700],
|
color: Colors.grey[700],
|
||||||
),
|
),
|
||||||
overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow
|
overflow:
|
||||||
|
TextOverflow
|
||||||
|
.ellipsis, // Ensures title doesn't overflow
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
SizedBox(width: 16),
|
SizedBox(width: 16),
|
||||||
Container(
|
Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.2,
|
width:
|
||||||
|
MediaQuery.of(context).size.width *
|
||||||
|
0.2,
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: searchInternationalController,
|
controller:
|
||||||
|
searchInternationalController,
|
||||||
onChanged: handleInternationalFilter,
|
onChanged: handleInternationalFilter,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Search ...",
|
hintText: "Search ...",
|
||||||
@ -1176,27 +1316,36 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
size: 18,
|
size: 18,
|
||||||
),
|
),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade200,
|
color: Colors.grey.shade200,
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade300,
|
color: Colors.grey.shade300,
|
||||||
width: 1,
|
width: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
style: GoogleFonts.poppins(fontSize: 12),
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
])
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
height:
|
height:
|
||||||
@ -1209,7 +1358,11 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
final double minWidth =
|
final double minWidth =
|
||||||
isDesktop ? constraints.maxWidth : 1300;
|
isDesktop ? constraints.maxWidth : 1300;
|
||||||
List<Map<String, dynamic>> newInternationalData =filteredInternational.isNotEmpty ? filteredInternational : internationalData;
|
List<Map<String, dynamic>>
|
||||||
|
newInternationalData =
|
||||||
|
filteredInternational.isNotEmpty
|
||||||
|
? filteredInternational
|
||||||
|
: internationalData;
|
||||||
// Pagination logic
|
// Pagination logic
|
||||||
List<Map<String, dynamic>>
|
List<Map<String, dynamic>>
|
||||||
paginatedInternational =
|
paginatedInternational =
|
||||||
@ -1218,31 +1371,65 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
.take(itemsPerPage2)
|
.take(itemsPerPage2)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return ((searchInternationalController.text.isNotEmpty && filteredInternational.isEmpty)
|
return ((searchInternationalController
|
||||||
|
.text
|
||||||
|
.isNotEmpty &&
|
||||||
|
filteredInternational.isEmpty)
|
||||||
? Center(
|
? Center(
|
||||||
child: Text(
|
child: Padding(
|
||||||
"No data found",
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height:
|
||||||
|
MediaQuery.of(
|
||||||
|
context,
|
||||||
|
).size.height /
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"No Records Found",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 14,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Please ensure the selected dates contain report data.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
:Column(
|
: Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection:
|
||||||
|
Axis.horizontal,
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
minWidth: minWidth,
|
minWidth: minWidth,
|
||||||
),
|
),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection:
|
||||||
|
Axis.vertical,
|
||||||
child: DataTable(
|
child: DataTable(
|
||||||
dividerThickness: 0.5,
|
dividerThickness: 0.5,
|
||||||
columnSpacing:
|
columnSpacing:
|
||||||
isDesktop ? 30.0 : 24.0,
|
isDesktop
|
||||||
|
? 30.0
|
||||||
|
: 24.0,
|
||||||
border: TableBorder(
|
border: TableBorder(
|
||||||
horizontalInside:
|
horizontalInside:
|
||||||
BorderSide(
|
BorderSide(
|
||||||
@ -1390,8 +1577,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['plan_id']}',
|
'${entry['plan_id']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1400,8 +1586,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['employee_code']}',
|
'${entry['employee_code']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1410,8 +1595,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['so_number']}',
|
'${entry['so_number']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1420,8 +1604,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['functional_department']}',
|
'${entry['functional_department']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1430,8 +1613,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['flight_trip_type']}',
|
'${entry['flight_trip_type']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1440,8 +1622,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['plan_trip_type']}',
|
'${entry['plan_trip_type']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1450,8 +1631,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['sector']}',
|
'${entry['sector']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1460,8 +1640,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['flight_class']}',
|
'${entry['flight_class']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1470,8 +1649,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
flightTravelDate,
|
flightTravelDate,
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1490,7 +1668,8 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
PaginationControls(
|
PaginationControls(
|
||||||
currentPage: currentPage2,
|
currentPage: currentPage2,
|
||||||
itemsPerPage: itemsPerPage2,
|
itemsPerPage: itemsPerPage2,
|
||||||
totalItems: newInternationalData.length,
|
totalItems:
|
||||||
|
newInternationalData.length,
|
||||||
activeColor: layoutColor,
|
activeColor: layoutColor,
|
||||||
onPageChanged: (page) {
|
onPageChanged: (page) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -1523,7 +1702,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildTitle(bool isDesktop){
|
Widget buildTitle(bool isDesktop) {
|
||||||
return // Left side: Breadcrumb inside a Container (optional)
|
return // Left side: Breadcrumb inside a Container (optional)
|
||||||
Container(
|
Container(
|
||||||
child: BreadcrumbNavigation(
|
child: BreadcrumbNavigation(
|
||||||
@ -1535,17 +1714,15 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
onTap: (context) {
|
onTap: (context) {
|
||||||
// Navigator.pushNamed(context, '/report');
|
// Navigator.pushNamed(context, '/report');
|
||||||
context.go("/report");
|
context.go("/report");
|
||||||
}
|
},
|
||||||
),
|
|
||||||
BreadcrumbItem(
|
|
||||||
title: 'Guest House',
|
|
||||||
),
|
),
|
||||||
|
BreadcrumbItem(title: 'Guest House'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildExports(bool isDesktop){
|
Widget buildExports(bool isDesktop) {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
@ -1555,10 +1732,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||||
horizontal: 20,
|
|
||||||
vertical: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
onPressed: handleDownload,
|
onPressed: handleDownload,
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -1571,11 +1745,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
Icon(
|
Icon(Icons.file_present_outlined, size: 15, color: Colors.white),
|
||||||
Icons.file_present_outlined,
|
|
||||||
size: 15,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1608,14 +1778,14 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
// ),
|
// ),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildFromDateField(bool isDesktop) {
|
Widget buildFromDateField(bool isDesktop) {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text( "From Date *",
|
Text(
|
||||||
|
"From Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -1657,12 +1827,9 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
floatingLabelBehavior:
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
FloatingLabelBehavior.never,
|
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
vertical: 16,
|
|
||||||
),
|
|
||||||
suffixIcon: const Icon(
|
suffixIcon: const Icon(
|
||||||
Icons.calendar_today,
|
Icons.calendar_today,
|
||||||
size: 16,
|
size: 16,
|
||||||
@ -1689,7 +1856,8 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text( "To Date *",
|
Text(
|
||||||
|
"To Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -1705,13 +1873,10 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
height: 40,
|
height: 40,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final fromDateText =
|
final fromDateText = textControllers["from_date"]?.text;
|
||||||
textControllers["from_date"]?.text;
|
|
||||||
DateTime? mintoDate;
|
DateTime? mintoDate;
|
||||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||||
mintoDate = DateFormat(
|
mintoDate = DateFormat('dd-MM-yyyy').parse(fromDateText);
|
||||||
'dd-MM-yyyy',
|
|
||||||
).parse(fromDateText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final pickedDate = await showDatePicker(
|
final pickedDate = await showDatePicker(
|
||||||
@ -1735,16 +1900,10 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Select Date",
|
labelText: "Select Date",
|
||||||
labelStyle: TextStyle(
|
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||||
fontSize: 12,
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
floatingLabelBehavior:
|
|
||||||
FloatingLabelBehavior.never,
|
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding: EdgeInsets.symmetric(
|
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||||
vertical: 16,
|
|
||||||
),
|
|
||||||
suffixIcon: Icon(
|
suffixIcon: Icon(
|
||||||
Icons.calendar_today,
|
Icons.calendar_today,
|
||||||
size: 16,
|
size: 16,
|
||||||
@ -1763,8 +1922,7 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||||
maxLines: 2, // Allow it to wrap onto two lines
|
maxLines: 2, // Allow it to wrap onto two lines
|
||||||
overflow:
|
overflow:
|
||||||
TextOverflow
|
TextOverflow.ellipsis, // Add ellipsis if it still overflows
|
||||||
.ellipsis, // Add ellipsis if it still overflows
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -1772,11 +1930,8 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget buildSearchButton(bool isDesktop) {
|
Widget buildSearchButton(bool isDesktop) {
|
||||||
return
|
return Padding(
|
||||||
Padding(
|
padding: isDesktop ? const EdgeInsets.only(top: 22) : EdgeInsets.zero,
|
||||||
padding: isDesktop
|
|
||||||
? const EdgeInsets.only(top: 22)
|
|
||||||
: EdgeInsets.zero,
|
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: isDesktop ? null : double.infinity,
|
width: isDesktop ? null : double.infinity,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
@ -1789,23 +1944,17 @@ class _GuestHouseState extends State<GuestHouse>
|
|||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||||
horizontal: 20,
|
|
||||||
vertical: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
handleSubmit();
|
handleSubmit();
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize:
|
mainAxisSize: MainAxisSize.min, // Ensures content fits nicely
|
||||||
MainAxisSize.min, // Ensures content fits nicely
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Search",
|
"Search",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(fontSize: isDesktop ? 13 : 11),
|
||||||
fontSize: isDesktop ? 13 : 11,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(width: 8), // spacing between icon and text
|
SizedBox(width: 8), // spacing between icon and text
|
||||||
Icon(Icons.search, size: 15, color: Colors.white),
|
Icon(Icons.search, size: 15, color: Colors.white),
|
||||||
|
|||||||
@ -111,9 +111,12 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
|
|
||||||
String getTabName(int index) {
|
String getTabName(int index) {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0: return "domestic";
|
case 0:
|
||||||
case 1: return "international";
|
return "domestic";
|
||||||
default: return "domestic"; // return "Unknown";
|
case 1:
|
||||||
|
return "international";
|
||||||
|
default:
|
||||||
|
return "domestic"; // return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,13 +334,13 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
excelName,
|
excelName,
|
||||||
);
|
);
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
// ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
// SnackBar(
|
||||||
backgroundColor: Colors.green,
|
// backgroundColor: result['status'] ? Colors.green : Colors.red,
|
||||||
content: Text(result as String),
|
// content: Text(result['message']),
|
||||||
behavior: SnackBarBehavior.floating,
|
// behavior: SnackBarBehavior.floating,
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDomesticFilter(String query) {
|
void handleDomesticFilter(String query) {
|
||||||
@ -345,20 +348,48 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
setState(() {
|
setState(() {
|
||||||
filteredDomestic =
|
filteredDomestic =
|
||||||
domesticData.where((object) {
|
domesticData.where((object) {
|
||||||
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
final travelDateRaw = object['flight_travel_date'];
|
||||||
(object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
String formattedDate = '';
|
||||||
(object['customer_name']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
|
||||||
(object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
if (travelDateRaw != null && travelDateRaw is String) {
|
||||||
(object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
try {
|
||||||
(object['flight_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
final parsedDate = DateTime.parse(travelDateRaw);
|
||||||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
formattedDate =
|
||||||
(object['flight_class']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
'${parsedDate.day.toString().padLeft(2, '0')}-${parsedDate.month.toString().padLeft(2, '0')}-${parsedDate.year}';
|
||||||
(object['flight_travel_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
} catch (e) {
|
||||||
|
// fallback if date is not parsable
|
||||||
|
formattedDate = travelDateRaw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(object['employee_code']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(object['customer_name']?.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['flight_class']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(formattedDate.toLowerCase().contains(lowerQuery)) ||
|
||||||
(object['sector']?.toLowerCase().contains(lowerQuery));
|
(object['sector']?.toLowerCase().contains(lowerQuery));
|
||||||
}).toList();
|
}).toList();
|
||||||
currentPage1 = 0;
|
currentPage1 = 0;
|
||||||
});
|
});
|
||||||
print("handleDomesticFilter > Total entries: ${filteredDomestic?.length ?? 0}");
|
print(
|
||||||
|
"handleDomesticFilter > Total entries: ${filteredDomestic?.length ?? 0}",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleInternationalFilter(String query) {
|
void handleInternationalFilter(String query) {
|
||||||
@ -366,23 +397,50 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
setState(() {
|
setState(() {
|
||||||
filteredInternational =
|
filteredInternational =
|
||||||
internationalData.where((object) {
|
internationalData.where((object) {
|
||||||
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
final travelDateRaw = object['flight_travel_date'];
|
||||||
(object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
String formattedDate = '';
|
||||||
(object['customer_name']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
|
||||||
(object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
if (travelDateRaw != null && travelDateRaw is String) {
|
||||||
(object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
try {
|
||||||
(object['flight_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
final parsedDate = DateTime.parse(travelDateRaw);
|
||||||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
formattedDate =
|
||||||
(object['flight_class']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
'${parsedDate.day.toString().padLeft(2, '0')}-${parsedDate.month.toString().padLeft(2, '0')}-${parsedDate.year}';
|
||||||
(object['flight_travel_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
} catch (e) {
|
||||||
|
// fallback if date is not parsable
|
||||||
|
formattedDate = travelDateRaw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(object['employee_code']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(object['customer_name']?.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['flight_class']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(formattedDate.toLowerCase().contains(lowerQuery)) ||
|
||||||
(object['sector']?.toLowerCase().contains(lowerQuery));
|
(object['sector']?.toLowerCase().contains(lowerQuery));
|
||||||
}).toList();
|
}).toList();
|
||||||
currentPage2 = 0;
|
currentPage2 = 0;
|
||||||
});
|
});
|
||||||
print("handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}");
|
print(
|
||||||
|
"handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// Widget build(BuildContext context) {
|
// Widget build(BuildContext context) {
|
||||||
// // TODO: implement build
|
// // TODO: implement build
|
||||||
@ -454,7 +512,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
children: [
|
children: [
|
||||||
buildTitle(isDesktop),
|
buildTitle(isDesktop),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
buildExports(isDesktop)
|
buildExports(isDesktop),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: Column(
|
: Column(
|
||||||
@ -462,9 +520,9 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
children: [
|
children: [
|
||||||
buildTitle(isDesktop),
|
buildTitle(isDesktop),
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
buildExports(isDesktop)
|
buildExports(isDesktop),
|
||||||
],
|
],
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
|
|
||||||
@ -521,13 +579,34 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
: domesticData.isEmpty
|
: domesticData.isEmpty
|
||||||
? Center(
|
? Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Text(
|
child: Column(
|
||||||
"No data found",
|
mainAxisSize: MainAxisSize.min,
|
||||||
style: GoogleFonts.poppins(
|
children: [
|
||||||
fontSize: 14,
|
SizedBox(
|
||||||
fontWeight: FontWeight.w500,
|
height:
|
||||||
|
MediaQuery.of(context).size.height / 4,
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
"No Records Found",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Please ensure the selected dates contain report data.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -559,7 +638,9 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.2,
|
width:
|
||||||
|
MediaQuery.of(context).size.width *
|
||||||
|
0.2,
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: searchDomesticController,
|
controller: searchDomesticController,
|
||||||
@ -576,24 +657,32 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
size: 18,
|
size: 18,
|
||||||
),
|
),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade200,
|
color: Colors.grey.shade200,
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade300,
|
color: Colors.grey.shade300,
|
||||||
width: 1,
|
width: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
style: GoogleFonts.poppins(fontSize: 12),
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// SizedBox(width: 16),
|
// SizedBox(width: 16),
|
||||||
@ -701,8 +790,10 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
final double minWidth =
|
final double minWidth =
|
||||||
isDesktop ? constraints.maxWidth : 1300;
|
isDesktop ? constraints.maxWidth : 1300;
|
||||||
|
|
||||||
List<Map<String, dynamic>> newDomesticData =filteredDomestic.isNotEmpty ? filteredDomestic : domesticData;
|
List<Map<String, dynamic>> newDomesticData =
|
||||||
|
filteredDomestic.isNotEmpty
|
||||||
|
? filteredDomestic
|
||||||
|
: domesticData;
|
||||||
|
|
||||||
// Pagination logic
|
// Pagination logic
|
||||||
List<Map<String, dynamic>>
|
List<Map<String, dynamic>>
|
||||||
@ -712,14 +803,43 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
.take(itemsPerPage1)
|
.take(itemsPerPage1)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return (
|
return ((searchDomesticController
|
||||||
(searchDomesticController.text.isNotEmpty && filteredDomestic.isEmpty)
|
.text
|
||||||
|
.isNotEmpty &&
|
||||||
|
filteredDomestic.isEmpty)
|
||||||
? Center(
|
? Center(
|
||||||
child: Text(
|
child: Padding(
|
||||||
"No data found",
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height:
|
||||||
|
MediaQuery.of(
|
||||||
|
context,
|
||||||
|
).size.height /
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"No Records Found",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 14,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Please ensure the selected dates contain report data.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -727,17 +847,21 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection:
|
||||||
|
Axis.horizontal,
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
minWidth: minWidth,
|
minWidth: minWidth,
|
||||||
),
|
),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection:
|
||||||
|
Axis.vertical,
|
||||||
child: DataTable(
|
child: DataTable(
|
||||||
dividerThickness: 0.5,
|
dividerThickness: 0.5,
|
||||||
columnSpacing:
|
columnSpacing:
|
||||||
isDesktop ? 30.0 : 24.0,
|
isDesktop
|
||||||
|
? 30.0
|
||||||
|
: 24.0,
|
||||||
border: TableBorder(
|
border: TableBorder(
|
||||||
horizontalInside:
|
horizontalInside:
|
||||||
BorderSide(
|
BorderSide(
|
||||||
@ -875,8 +999,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['plan_id']}',
|
'${entry['plan_id']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -885,8 +1008,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['employee_code']}',
|
'${entry['employee_code']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -895,8 +1017,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['so_number']}',
|
'${entry['so_number']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -905,8 +1026,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['functional_department']}',
|
'${entry['functional_department']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -915,8 +1035,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['flight_trip_type']}',
|
'${entry['flight_trip_type']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -925,8 +1044,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['plan_trip_type']}',
|
'${entry['plan_trip_type']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -935,8 +1053,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['sector']}',
|
'${entry['sector']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -945,8 +1062,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['flight_class']}',
|
'${entry['flight_class']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -955,8 +1071,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
TravelDate,
|
TravelDate,
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -975,7 +1090,8 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
PaginationControls(
|
PaginationControls(
|
||||||
currentPage: currentPage1,
|
currentPage: currentPage1,
|
||||||
itemsPerPage: itemsPerPage1,
|
itemsPerPage: itemsPerPage1,
|
||||||
totalItems: newDomesticData.length,
|
totalItems:
|
||||||
|
newDomesticData.length,
|
||||||
activeColor: layoutColor,
|
activeColor: layoutColor,
|
||||||
onPageChanged: (page) {
|
onPageChanged: (page) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -1138,7 +1254,8 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
vertical: 8,
|
vertical: 8,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
/// Title on the left
|
/// Title on the left
|
||||||
@ -1150,17 +1267,21 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Colors.grey[700],
|
color: Colors.grey[700],
|
||||||
),
|
),
|
||||||
overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow
|
overflow:
|
||||||
|
TextOverflow
|
||||||
|
.ellipsis, // Ensures title doesn't overflow
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
SizedBox(width: 16),
|
SizedBox(width: 16),
|
||||||
Container(
|
Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.2,
|
width:
|
||||||
|
MediaQuery.of(context).size.width *
|
||||||
|
0.2,
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: searchInternationalController,
|
controller:
|
||||||
|
searchInternationalController,
|
||||||
onChanged: handleInternationalFilter,
|
onChanged: handleInternationalFilter,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Search ...",
|
hintText: "Search ...",
|
||||||
@ -1174,27 +1295,36 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
size: 18,
|
size: 18,
|
||||||
),
|
),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade200,
|
color: Colors.grey.shade200,
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade300,
|
color: Colors.grey.shade300,
|
||||||
width: 1,
|
width: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
style: GoogleFonts.poppins(fontSize: 12),
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
])
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
height:
|
height:
|
||||||
@ -1207,7 +1337,11 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
final double minWidth =
|
final double minWidth =
|
||||||
isDesktop ? constraints.maxWidth : 1300;
|
isDesktop ? constraints.maxWidth : 1300;
|
||||||
List<Map<String, dynamic>> newInternationalData =filteredInternational.isNotEmpty ? filteredInternational : internationalData;
|
List<Map<String, dynamic>>
|
||||||
|
newInternationalData =
|
||||||
|
filteredInternational.isNotEmpty
|
||||||
|
? filteredInternational
|
||||||
|
: internationalData;
|
||||||
// Pagination logic
|
// Pagination logic
|
||||||
List<Map<String, dynamic>>
|
List<Map<String, dynamic>>
|
||||||
paginatedInternational =
|
paginatedInternational =
|
||||||
@ -1216,7 +1350,10 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
.take(itemsPerPage2)
|
.take(itemsPerPage2)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return ((searchInternationalController.text.isNotEmpty && filteredInternational.isEmpty)
|
return ((searchInternationalController
|
||||||
|
.text
|
||||||
|
.isNotEmpty &&
|
||||||
|
filteredInternational.isEmpty)
|
||||||
? Center(
|
? Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
"No data found",
|
"No data found",
|
||||||
@ -1230,17 +1367,21 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection:
|
||||||
|
Axis.horizontal,
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
minWidth: minWidth,
|
minWidth: minWidth,
|
||||||
),
|
),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection:
|
||||||
|
Axis.vertical,
|
||||||
child: DataTable(
|
child: DataTable(
|
||||||
dividerThickness: 0.5,
|
dividerThickness: 0.5,
|
||||||
columnSpacing:
|
columnSpacing:
|
||||||
isDesktop ? 30.0 : 24.0,
|
isDesktop
|
||||||
|
? 30.0
|
||||||
|
: 24.0,
|
||||||
border: TableBorder(
|
border: TableBorder(
|
||||||
horizontalInside:
|
horizontalInside:
|
||||||
BorderSide(
|
BorderSide(
|
||||||
@ -1378,8 +1519,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['plan_id']}',
|
'${entry['plan_id']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1388,8 +1528,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['employee_code']}',
|
'${entry['employee_code']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1398,8 +1537,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['so_number']}',
|
'${entry['so_number']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1408,8 +1546,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['functional_department']}',
|
'${entry['functional_department']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1418,8 +1555,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['flight_trip_type']}',
|
'${entry['flight_trip_type']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1428,8 +1564,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['plan_trip_type']}',
|
'${entry['plan_trip_type']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1438,8 +1573,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['sector']}',
|
'${entry['sector']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1448,8 +1582,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['flight_class']}',
|
'${entry['flight_class']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1458,8 +1591,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
TravelDate,
|
TravelDate,
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1478,7 +1610,8 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
PaginationControls(
|
PaginationControls(
|
||||||
currentPage: currentPage2,
|
currentPage: currentPage2,
|
||||||
itemsPerPage: itemsPerPage2,
|
itemsPerPage: itemsPerPage2,
|
||||||
totalItems: internationalData.length,
|
totalItems:
|
||||||
|
internationalData.length,
|
||||||
activeColor: layoutColor,
|
activeColor: layoutColor,
|
||||||
onPageChanged: (page) {
|
onPageChanged: (page) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -1510,7 +1643,8 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Widget buildTitle(bool isDesktop){
|
|
||||||
|
Widget buildTitle(bool isDesktop) {
|
||||||
return // Left side: Breadcrumb inside a Container (optional)
|
return // Left side: Breadcrumb inside a Container (optional)
|
||||||
Container(
|
Container(
|
||||||
child: BreadcrumbNavigation(
|
child: BreadcrumbNavigation(
|
||||||
@ -1522,16 +1656,15 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
onTap: (context) {
|
onTap: (context) {
|
||||||
// Navigator.pushNamed(context, '/report');
|
// Navigator.pushNamed(context, '/report');
|
||||||
context.go("/report");
|
context.go("/report");
|
||||||
}
|
},
|
||||||
),
|
|
||||||
BreadcrumbItem(
|
|
||||||
title: 'MIS Air Report ',
|
|
||||||
),
|
),
|
||||||
|
BreadcrumbItem(title: 'MIS Air Report '),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Widget buildExports(bool isDesktop){
|
|
||||||
|
Widget buildExports(bool isDesktop) {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
@ -1541,10 +1674,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||||
horizontal: 20,
|
|
||||||
vertical: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
onPressed: handleDownload,
|
onPressed: handleDownload,
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -1557,11 +1687,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
Icon(
|
Icon(Icons.file_present_outlined, size: 15, color: Colors.white),
|
||||||
Icons.file_present_outlined,
|
|
||||||
size: 15,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1594,14 +1720,14 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
// ),
|
// ),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildFromDateField(bool isDesktop) {
|
Widget buildFromDateField(bool isDesktop) {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text( "From Date *",
|
Text(
|
||||||
|
"From Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -1643,12 +1769,9 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
floatingLabelBehavior:
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
FloatingLabelBehavior.never,
|
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
vertical: 16,
|
|
||||||
),
|
|
||||||
suffixIcon: const Icon(
|
suffixIcon: const Icon(
|
||||||
Icons.calendar_today,
|
Icons.calendar_today,
|
||||||
size: 16,
|
size: 16,
|
||||||
@ -1675,7 +1798,8 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text( "To Date *",
|
Text(
|
||||||
|
"To Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -1691,13 +1815,10 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
height: 40,
|
height: 40,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final fromDateText =
|
final fromDateText = textControllers["from_date"]?.text;
|
||||||
textControllers["from_date"]?.text;
|
|
||||||
DateTime? mintoDate;
|
DateTime? mintoDate;
|
||||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||||
mintoDate = DateFormat(
|
mintoDate = DateFormat('dd-MM-yyyy').parse(fromDateText);
|
||||||
'dd-MM-yyyy',
|
|
||||||
).parse(fromDateText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final pickedDate = await showDatePicker(
|
final pickedDate = await showDatePicker(
|
||||||
@ -1722,16 +1843,10 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Select Date",
|
labelText: "Select Date",
|
||||||
labelStyle: TextStyle(
|
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||||
fontSize: 12,
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
floatingLabelBehavior:
|
|
||||||
FloatingLabelBehavior.never,
|
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding: EdgeInsets.symmetric(
|
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||||
vertical: 16,
|
|
||||||
),
|
|
||||||
suffixIcon: Icon(
|
suffixIcon: Icon(
|
||||||
Icons.calendar_today,
|
Icons.calendar_today,
|
||||||
size: 16,
|
size: 16,
|
||||||
@ -1750,8 +1865,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||||
maxLines: 2, // Allow it to wrap onto two lines
|
maxLines: 2, // Allow it to wrap onto two lines
|
||||||
overflow:
|
overflow:
|
||||||
TextOverflow
|
TextOverflow.ellipsis, // Add ellipsis if it still overflows
|
||||||
.ellipsis, // Add ellipsis if it still overflows
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -1759,11 +1873,8 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget buildSearchButton(bool isDesktop) {
|
Widget buildSearchButton(bool isDesktop) {
|
||||||
return
|
return Padding(
|
||||||
Padding(
|
padding: isDesktop ? const EdgeInsets.only(top: 22) : EdgeInsets.zero,
|
||||||
padding: isDesktop
|
|
||||||
? const EdgeInsets.only(top: 22)
|
|
||||||
: EdgeInsets.zero,
|
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: isDesktop ? null : double.infinity,
|
width: isDesktop ? null : double.infinity,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
@ -1776,23 +1887,17 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
|||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||||
horizontal: 20,
|
|
||||||
vertical: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
handleSubmit();
|
handleSubmit();
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize:
|
mainAxisSize: MainAxisSize.min, // Ensures content fits nicely
|
||||||
MainAxisSize.min, // Ensures content fits nicely
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Search",
|
"Search",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(fontSize: isDesktop ? 13 : 11),
|
||||||
fontSize: isDesktop ? 13 : 11,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(width: 8), // spacing between icon and text
|
SizedBox(width: 8), // spacing between icon and text
|
||||||
Icon(Icons.search, size: 15, color: Colors.white),
|
Icon(Icons.search, size: 15, color: Colors.white),
|
||||||
|
|||||||
@ -78,7 +78,6 @@ class _MISforexState extends State<MISforex>
|
|||||||
focusStates["from_date"] = false;
|
focusStates["from_date"] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Add focus listeners
|
// Add focus listeners
|
||||||
focusNodes.forEach((key, focusNode) {
|
focusNodes.forEach((key, focusNode) {
|
||||||
_addFocusListener(focusNode, (focus) {
|
_addFocusListener(focusNode, (focus) {
|
||||||
@ -92,7 +91,6 @@ class _MISforexState extends State<MISforex>
|
|||||||
// fetchMISforexReport();
|
// fetchMISforexReport();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _addFocusListener(FocusNode node, Function(bool) updateState) {
|
void _addFocusListener(FocusNode node, Function(bool) updateState) {
|
||||||
node.addListener(() {
|
node.addListener(() {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -243,9 +241,7 @@ class _MISforexState extends State<MISforex>
|
|||||||
setState(() {
|
setState(() {
|
||||||
// domesticData = List<Map<String, dynamic>>.from(result['data']['domestic'] ?? []);
|
// domesticData = List<Map<String, dynamic>>.from(result['data']['domestic'] ?? []);
|
||||||
internationalData = List<Map<String, dynamic>>.from(
|
internationalData = List<Map<String, dynamic>>.from(
|
||||||
result['status'] == 'success'
|
result['status'] == 'success' ? result['data'] ?? [] : [],
|
||||||
? result['data'] ?? []
|
|
||||||
: [],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
filteredInternational = internationalData;
|
filteredInternational = internationalData;
|
||||||
@ -299,13 +295,13 @@ class _MISforexState extends State<MISforex>
|
|||||||
excelName,
|
excelName,
|
||||||
);
|
);
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
// ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
// SnackBar(
|
||||||
backgroundColor: Colors.green,
|
// backgroundColor: result['status'] ? Colors.green : Colors.red,
|
||||||
content: Text(result as String),
|
// content: Text(result['message']),
|
||||||
behavior: SnackBarBehavior.floating,
|
// behavior: SnackBarBehavior.floating,
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleInternationalFilter(String query) {
|
void handleInternationalFilter(String query) {
|
||||||
@ -313,19 +309,60 @@ class _MISforexState extends State<MISforex>
|
|||||||
setState(() {
|
setState(() {
|
||||||
filteredInternational =
|
filteredInternational =
|
||||||
internationalData.where((object) {
|
internationalData.where((object) {
|
||||||
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
final fromDateRaw = object['forex_from_date'];
|
||||||
(object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
String newFromDate = '';
|
||||||
(object['passenger_name']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
|
||||||
(object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
if (fromDateRaw != null && fromDateRaw is String) {
|
||||||
(object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
try {
|
||||||
(object['visiting_country']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
final parsedDate = DateTime.parse(fromDateRaw);
|
||||||
(object['amount']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
newFromDate =
|
||||||
(object['forex_from_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
'${parsedDate.day.toString().padLeft(2, '0')}-${parsedDate.month.toString().padLeft(2, '0')}-${parsedDate.year}';
|
||||||
(object['forex_to_date']?.toLowerCase().contains(lowerQuery));
|
} catch (e) {
|
||||||
|
// fallback if date is not parsable
|
||||||
|
newFromDate = fromDateRaw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final toDateRaw = object['flight_travel_date'];
|
||||||
|
String newToDate = '';
|
||||||
|
|
||||||
|
if (toDateRaw != null && toDateRaw is String) {
|
||||||
|
try {
|
||||||
|
final parsedDate = DateTime.parse(toDateRaw);
|
||||||
|
newToDate =
|
||||||
|
'${parsedDate.day.toString().padLeft(2, '0')}-${parsedDate.month.toString().padLeft(2, '0')}-${parsedDate.year}';
|
||||||
|
} catch (e) {
|
||||||
|
// fallback if date is not parsable
|
||||||
|
newToDate = toDateRaw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(object['employee_code']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(object['passenger_name']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(object['so_number']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(object['functional_department']?.toLowerCase().contains(
|
||||||
|
lowerQuery,
|
||||||
|
) ??
|
||||||
|
false) ||
|
||||||
|
(object['visiting_country']?.toLowerCase().contains(
|
||||||
|
lowerQuery,
|
||||||
|
) ??
|
||||||
|
false) ||
|
||||||
|
(object['amount']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
|
(newFromDate.toLowerCase().contains(lowerQuery)) ||
|
||||||
|
(newToDate.toLowerCase().contains(lowerQuery));
|
||||||
}).toList();
|
}).toList();
|
||||||
currentPage = 0;
|
currentPage = 0;
|
||||||
});
|
});
|
||||||
print("handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}");
|
print(
|
||||||
|
"handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -399,7 +436,7 @@ class _MISforexState extends State<MISforex>
|
|||||||
children: [
|
children: [
|
||||||
buildTitle(isDesktop),
|
buildTitle(isDesktop),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
buildExports(isDesktop)
|
buildExports(isDesktop),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: Column(
|
: Column(
|
||||||
@ -407,9 +444,9 @@ class _MISforexState extends State<MISforex>
|
|||||||
children: [
|
children: [
|
||||||
buildTitle(isDesktop),
|
buildTitle(isDesktop),
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
buildExports(isDesktop)
|
buildExports(isDesktop),
|
||||||
],
|
],
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
|
|
||||||
@ -450,13 +487,34 @@ class _MISforexState extends State<MISforex>
|
|||||||
internationalData.isEmpty
|
internationalData.isEmpty
|
||||||
? Center(
|
? Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Text(
|
child: Column(
|
||||||
"No data found",
|
mainAxisSize: MainAxisSize.min,
|
||||||
style: GoogleFonts.poppins(
|
children: [
|
||||||
fontSize: 14,
|
SizedBox(
|
||||||
fontWeight: FontWeight.w500,
|
height:
|
||||||
|
MediaQuery.of(context).size.height / 4,
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
"No Records Found",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Please ensure the selected dates contain report data.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -470,7 +528,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
vertical: 8,
|
vertical: 8,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
/// Title on the left
|
/// Title on the left
|
||||||
@ -482,14 +541,16 @@ class _MISforexState extends State<MISforex>
|
|||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Colors.grey[700],
|
color: Colors.grey[700],
|
||||||
),
|
),
|
||||||
overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow
|
overflow:
|
||||||
|
TextOverflow
|
||||||
|
.ellipsis, // Ensures title doesn't overflow
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
SizedBox(width: 16),
|
SizedBox(width: 16),
|
||||||
Container(
|
Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.2,
|
width:
|
||||||
|
MediaQuery.of(context).size.width * 0.2,
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: searchInternationalController,
|
controller: searchInternationalController,
|
||||||
@ -506,17 +567,23 @@ class _MISforexState extends State<MISforex>
|
|||||||
size: 18,
|
size: 18,
|
||||||
),
|
),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade200,
|
color: Colors.grey.shade200,
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade300,
|
color: Colors.grey.shade300,
|
||||||
width: 1,
|
width: 1,
|
||||||
@ -526,7 +593,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
style: GoogleFonts.poppins(fontSize: 12),
|
style: GoogleFonts.poppins(fontSize: 12),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
])
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
// Table container
|
// Table container
|
||||||
Container(
|
Container(
|
||||||
@ -539,7 +607,11 @@ class _MISforexState extends State<MISforex>
|
|||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
final double minWidth =
|
final double minWidth =
|
||||||
isDesktop ? constraints.maxWidth : 1300;
|
isDesktop ? constraints.maxWidth : 1300;
|
||||||
List<Map<String, dynamic>> newInternationalData =filteredInternational.isNotEmpty ? filteredInternational : internationalData;
|
List<Map<String, dynamic>>
|
||||||
|
newInternationalData =
|
||||||
|
filteredInternational.isNotEmpty
|
||||||
|
? filteredInternational
|
||||||
|
: internationalData;
|
||||||
// Pagination logic
|
// Pagination logic
|
||||||
List<Map<String, dynamic>>
|
List<Map<String, dynamic>>
|
||||||
paginatedInternational =
|
paginatedInternational =
|
||||||
@ -548,17 +620,47 @@ class _MISforexState extends State<MISforex>
|
|||||||
.take(itemsPerPage)
|
.take(itemsPerPage)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return ((searchInternationalController.text.isNotEmpty && filteredInternational.isEmpty)
|
return ((searchInternationalController
|
||||||
|
.text
|
||||||
|
.isNotEmpty &&
|
||||||
|
filteredInternational.isEmpty)
|
||||||
? Center(
|
? Center(
|
||||||
child: Text(
|
child: Padding(
|
||||||
"No data found",
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height:
|
||||||
|
MediaQuery.of(
|
||||||
|
context,
|
||||||
|
).size.height /
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"No Records Found",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 14,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Please ensure the selected dates contain report data.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
:Column(
|
: Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
@ -568,15 +670,20 @@ class _MISforexState extends State<MISforex>
|
|||||||
minWidth: minWidth,
|
minWidth: minWidth,
|
||||||
),
|
),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection:
|
||||||
|
Axis.vertical,
|
||||||
child: DataTable(
|
child: DataTable(
|
||||||
dividerThickness: 0.5,
|
dividerThickness: 0.5,
|
||||||
columnSpacing:
|
columnSpacing:
|
||||||
isDesktop ? 30.0 : 24.0,
|
isDesktop ? 30.0 : 24.0,
|
||||||
border: TableBorder(
|
border: TableBorder(
|
||||||
horizontalInside: BorderSide(
|
horizontalInside:
|
||||||
|
BorderSide(
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
color: Colors.grey.shade200,
|
color:
|
||||||
|
Colors
|
||||||
|
.grey
|
||||||
|
.shade200,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
columns: [
|
columns: [
|
||||||
@ -587,7 +694,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
GoogleFonts.poppins(
|
GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight.w600,
|
FontWeight
|
||||||
|
.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -598,7 +706,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
GoogleFonts.poppins(
|
GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight.w600,
|
FontWeight
|
||||||
|
.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -609,7 +718,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
GoogleFonts.poppins(
|
GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight.w600,
|
FontWeight
|
||||||
|
.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -620,7 +730,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
GoogleFonts.poppins(
|
GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight.w600,
|
FontWeight
|
||||||
|
.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -631,7 +742,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
GoogleFonts.poppins(
|
GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight.w600,
|
FontWeight
|
||||||
|
.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -642,7 +754,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
GoogleFonts.poppins(
|
GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight.w600,
|
FontWeight
|
||||||
|
.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -653,7 +766,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
GoogleFonts.poppins(
|
GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight.w600,
|
FontWeight
|
||||||
|
.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -664,7 +778,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
GoogleFonts.poppins(
|
GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight.w600,
|
FontWeight
|
||||||
|
.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -675,7 +790,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
GoogleFonts.poppins(
|
GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight.w600,
|
FontWeight
|
||||||
|
.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -803,7 +919,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
PaginationControls(
|
PaginationControls(
|
||||||
currentPage: currentPage,
|
currentPage: currentPage,
|
||||||
itemsPerPage: itemsPerPage,
|
itemsPerPage: itemsPerPage,
|
||||||
totalItems: newInternationalData.length,
|
totalItems:
|
||||||
|
newInternationalData.length,
|
||||||
activeColor: layoutColor,
|
activeColor: layoutColor,
|
||||||
onPageChanged: (page) {
|
onPageChanged: (page) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -832,7 +949,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Widget buildTitle(bool isDesktop){
|
|
||||||
|
Widget buildTitle(bool isDesktop) {
|
||||||
return // Left side: Breadcrumb inside a Container (optional)
|
return // Left side: Breadcrumb inside a Container (optional)
|
||||||
Container(
|
Container(
|
||||||
child: BreadcrumbNavigation(
|
child: BreadcrumbNavigation(
|
||||||
@ -844,16 +962,15 @@ class _MISforexState extends State<MISforex>
|
|||||||
onTap: (context) {
|
onTap: (context) {
|
||||||
// Navigator.pushNamed(context, '/report');
|
// Navigator.pushNamed(context, '/report');
|
||||||
context.go("/report");
|
context.go("/report");
|
||||||
}
|
},
|
||||||
),
|
|
||||||
BreadcrumbItem(
|
|
||||||
title: 'MIS Forex Report ',
|
|
||||||
),
|
),
|
||||||
|
BreadcrumbItem(title: 'MIS Forex Report '),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Widget buildExports(bool isDesktop){
|
|
||||||
|
Widget buildExports(bool isDesktop) {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
@ -863,10 +980,7 @@ class _MISforexState extends State<MISforex>
|
|||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||||
horizontal: 20,
|
|
||||||
vertical: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
onPressed: handleDownload,
|
onPressed: handleDownload,
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -879,11 +993,7 @@ class _MISforexState extends State<MISforex>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
Icon(
|
Icon(Icons.file_present_outlined, size: 15, color: Colors.white),
|
||||||
Icons.file_present_outlined,
|
|
||||||
size: 15,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -916,14 +1026,14 @@ class _MISforexState extends State<MISforex>
|
|||||||
// ),
|
// ),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildFromDateField(bool isDesktop) {
|
Widget buildFromDateField(bool isDesktop) {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text( "From Date *",
|
Text(
|
||||||
|
"From Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -965,12 +1075,9 @@ class _MISforexState extends State<MISforex>
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
floatingLabelBehavior:
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
FloatingLabelBehavior.never,
|
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
vertical: 16,
|
|
||||||
),
|
|
||||||
suffixIcon: const Icon(
|
suffixIcon: const Icon(
|
||||||
Icons.calendar_today,
|
Icons.calendar_today,
|
||||||
size: 16,
|
size: 16,
|
||||||
@ -997,7 +1104,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text( "To Date *",
|
Text(
|
||||||
|
"To Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -1013,13 +1121,10 @@ class _MISforexState extends State<MISforex>
|
|||||||
height: 40,
|
height: 40,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final fromDateText =
|
final fromDateText = textControllers["from_date"]?.text;
|
||||||
textControllers["from_date"]?.text;
|
|
||||||
DateTime? mintoDate;
|
DateTime? mintoDate;
|
||||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||||
mintoDate = DateFormat(
|
mintoDate = DateFormat('dd-MM-yyyy').parse(fromDateText);
|
||||||
'dd-MM-yyyy',
|
|
||||||
).parse(fromDateText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final pickedDate = await showDatePicker(
|
final pickedDate = await showDatePicker(
|
||||||
@ -1044,16 +1149,10 @@ class _MISforexState extends State<MISforex>
|
|||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Select Date",
|
labelText: "Select Date",
|
||||||
labelStyle: TextStyle(
|
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||||
fontSize: 12,
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
floatingLabelBehavior:
|
|
||||||
FloatingLabelBehavior.never,
|
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding: EdgeInsets.symmetric(
|
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||||
vertical: 16,
|
|
||||||
),
|
|
||||||
suffixIcon: Icon(
|
suffixIcon: Icon(
|
||||||
Icons.calendar_today,
|
Icons.calendar_today,
|
||||||
size: 16,
|
size: 16,
|
||||||
@ -1072,8 +1171,7 @@ class _MISforexState extends State<MISforex>
|
|||||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||||
maxLines: 2, // Allow it to wrap onto two lines
|
maxLines: 2, // Allow it to wrap onto two lines
|
||||||
overflow:
|
overflow:
|
||||||
TextOverflow
|
TextOverflow.ellipsis, // Add ellipsis if it still overflows
|
||||||
.ellipsis, // Add ellipsis if it still overflows
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -1081,11 +1179,8 @@ class _MISforexState extends State<MISforex>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget buildSearchButton(bool isDesktop) {
|
Widget buildSearchButton(bool isDesktop) {
|
||||||
return
|
return Padding(
|
||||||
Padding(
|
padding: isDesktop ? const EdgeInsets.only(top: 22) : EdgeInsets.zero,
|
||||||
padding: isDesktop
|
|
||||||
? const EdgeInsets.only(top: 22)
|
|
||||||
: EdgeInsets.zero,
|
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: isDesktop ? null : double.infinity,
|
width: isDesktop ? null : double.infinity,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
@ -1098,23 +1193,17 @@ class _MISforexState extends State<MISforex>
|
|||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||||
horizontal: 20,
|
|
||||||
vertical: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
handleSubmit();
|
handleSubmit();
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize:
|
mainAxisSize: MainAxisSize.min, // Ensures content fits nicely
|
||||||
MainAxisSize.min, // Ensures content fits nicely
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Search",
|
"Search",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(fontSize: isDesktop ? 13 : 11),
|
||||||
fontSize: isDesktop ? 13 : 11,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(width: 8), // spacing between icon and text
|
SizedBox(width: 8), // spacing between icon and text
|
||||||
Icon(Icons.search, size: 15, color: Colors.white),
|
Icon(Icons.search, size: 15, color: Colors.white),
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -112,9 +112,12 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
|
|
||||||
String getTabName(int index) {
|
String getTabName(int index) {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0: return "domestic";
|
case 0:
|
||||||
case 1: return "international";
|
return "domestic";
|
||||||
default: return "domestic"; // return "Unknown";
|
case 1:
|
||||||
|
return "international";
|
||||||
|
default:
|
||||||
|
return "domestic"; // return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,13 +334,13 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
excelName,
|
excelName,
|
||||||
);
|
);
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
// ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
// SnackBar(
|
||||||
backgroundColor: Colors.green,
|
// backgroundColor: result['status'] ? Colors.green : Colors.red,
|
||||||
content: Text(result as String),
|
// content: Text(result['message']),
|
||||||
behavior: SnackBarBehavior.floating,
|
// behavior: SnackBarBehavior.floating,
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDomesticFilter(String query) {
|
void handleDomesticFilter(String query) {
|
||||||
@ -345,13 +348,17 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
setState(() {
|
setState(() {
|
||||||
filteredDomestic =
|
filteredDomestic =
|
||||||
domesticData.where((object) {
|
domesticData.where((object) {
|
||||||
return (object['Service']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
return (object['Service']?.toLowerCase().contains(lowerQuery) ??
|
||||||
(object['flight_service_count']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
false) ||
|
||||||
|
(object['service_count']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery));
|
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery));
|
||||||
}).toList();
|
}).toList();
|
||||||
currentPage1 = 0;
|
currentPage1 = 0;
|
||||||
});
|
});
|
||||||
print("handleDomesticFilter > Total entries: ${filteredDomestic?.length ?? 0}");
|
print(
|
||||||
|
"handleDomesticFilter > Total entries: ${filteredDomestic?.length ?? 0}",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleInternationalFilter(String query) {
|
void handleInternationalFilter(String query) {
|
||||||
@ -359,16 +366,19 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
setState(() {
|
setState(() {
|
||||||
filteredInternational =
|
filteredInternational =
|
||||||
internationalData.where((object) {
|
internationalData.where((object) {
|
||||||
return (object['Service']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
return (object['Service']?.toLowerCase().contains(lowerQuery) ??
|
||||||
(object['flight_service_count']?.toLowerCase().contains(lowerQuery) ?? false) ||
|
false) ||
|
||||||
|
(object['service_count']?.toLowerCase().contains(lowerQuery) ??
|
||||||
|
false) ||
|
||||||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery));
|
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery));
|
||||||
}).toList();
|
}).toList();
|
||||||
currentPage2 = 0;
|
currentPage2 = 0;
|
||||||
});
|
});
|
||||||
print("handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}");
|
print(
|
||||||
|
"handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// Widget build(BuildContext context) {
|
// Widget build(BuildContext context) {
|
||||||
// // TODO: implement build
|
// // TODO: implement build
|
||||||
@ -429,7 +439,6 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
// ------------------- First Row -------------------
|
|
||||||
// ------------------- First Row -------------------
|
// ------------------- First Row -------------------
|
||||||
Container(
|
Container(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
@ -440,7 +449,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
children: [
|
children: [
|
||||||
buildTitle(isDesktop),
|
buildTitle(isDesktop),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
buildExports(isDesktop)
|
buildExports(isDesktop),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: Column(
|
: Column(
|
||||||
@ -448,9 +457,9 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
children: [
|
children: [
|
||||||
buildTitle(isDesktop),
|
buildTitle(isDesktop),
|
||||||
SizedBox(height: 8),
|
SizedBox(height: 8),
|
||||||
buildExports(isDesktop)
|
buildExports(isDesktop),
|
||||||
],
|
],
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
|
|
||||||
@ -507,13 +516,34 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
: domesticData.isEmpty
|
: domesticData.isEmpty
|
||||||
? Center(
|
? Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Text(
|
child: Column(
|
||||||
"No data found",
|
mainAxisSize: MainAxisSize.min,
|
||||||
style: GoogleFonts.poppins(
|
children: [
|
||||||
fontSize: 14,
|
SizedBox(
|
||||||
fontWeight: FontWeight.w500,
|
height:
|
||||||
|
MediaQuery.of(context).size.height / 4,
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
"No Records Found",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Please ensure the selected dates contain report data.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -545,7 +575,9 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.2,
|
width:
|
||||||
|
MediaQuery.of(context).size.width *
|
||||||
|
0.2,
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: searchDomesticController,
|
controller: searchDomesticController,
|
||||||
@ -562,24 +594,32 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
size: 18,
|
size: 18,
|
||||||
),
|
),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade200,
|
color: Colors.grey.shade200,
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade300,
|
color: Colors.grey.shade300,
|
||||||
width: 1,
|
width: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
style: GoogleFonts.poppins(fontSize: 12),
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// SizedBox(width: 16),
|
// SizedBox(width: 16),
|
||||||
@ -687,8 +727,10 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
final double minWidth =
|
final double minWidth =
|
||||||
isDesktop ? constraints.maxWidth : 1300;
|
isDesktop ? constraints.maxWidth : 1300;
|
||||||
|
|
||||||
List<Map<String, dynamic>> newDomesticData =filteredDomestic.isNotEmpty ? filteredDomestic : domesticData;
|
List<Map<String, dynamic>> newDomesticData =
|
||||||
|
filteredDomestic.isNotEmpty
|
||||||
|
? filteredDomestic
|
||||||
|
: domesticData;
|
||||||
|
|
||||||
// Pagination logic
|
// Pagination logic
|
||||||
List<Map<String, dynamic>>
|
List<Map<String, dynamic>>
|
||||||
@ -698,14 +740,43 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
.take(itemsPerPage1)
|
.take(itemsPerPage1)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return (
|
return ((searchDomesticController
|
||||||
(searchDomesticController.text.isNotEmpty && filteredDomestic.isEmpty)
|
.text
|
||||||
|
.isNotEmpty &&
|
||||||
|
filteredDomestic.isEmpty)
|
||||||
? Center(
|
? Center(
|
||||||
child: Text(
|
child: Padding(
|
||||||
"No data found",
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height:
|
||||||
|
MediaQuery.of(
|
||||||
|
context,
|
||||||
|
).size.height /
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"No Records Found",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 14,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Please ensure the selected dates contain report data.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -713,17 +784,21 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection:
|
||||||
|
Axis.horizontal,
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
minWidth: minWidth,
|
minWidth: minWidth,
|
||||||
),
|
),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection:
|
||||||
|
Axis.vertical,
|
||||||
child: DataTable(
|
child: DataTable(
|
||||||
dividerThickness: 0.5,
|
dividerThickness: 0.5,
|
||||||
columnSpacing:
|
columnSpacing:
|
||||||
isDesktop ? 30.0 : 24.0,
|
isDesktop
|
||||||
|
? 30.0
|
||||||
|
: 24.0,
|
||||||
border: TableBorder(
|
border: TableBorder(
|
||||||
horizontalInside:
|
horizontalInside:
|
||||||
BorderSide(
|
BorderSide(
|
||||||
@ -781,8 +856,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['Service']}',
|
'${entry['Service']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -790,9 +864,8 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
),
|
),
|
||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['flight_service_count']}',
|
'${entry['service_count']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -801,8 +874,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['plan_trip_type']}',
|
'${entry['plan_trip_type']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -821,7 +893,8 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
PaginationControls(
|
PaginationControls(
|
||||||
currentPage: currentPage1,
|
currentPage: currentPage1,
|
||||||
itemsPerPage: itemsPerPage1,
|
itemsPerPage: itemsPerPage1,
|
||||||
totalItems: newDomesticData.length,
|
totalItems:
|
||||||
|
newDomesticData.length,
|
||||||
activeColor: layoutColor,
|
activeColor: layoutColor,
|
||||||
onPageChanged: (page) {
|
onPageChanged: (page) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -847,13 +920,34 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
internationalData.isEmpty
|
internationalData.isEmpty
|
||||||
? Center(
|
? Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Text(
|
child: Column(
|
||||||
"No data found",
|
mainAxisSize: MainAxisSize.min,
|
||||||
style: GoogleFonts.poppins(
|
children: [
|
||||||
fontSize: 14,
|
SizedBox(
|
||||||
fontWeight: FontWeight.w500,
|
height:
|
||||||
|
MediaQuery.of(context).size.height / 4,
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
"No Records Found",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Please ensure the selected dates contain report data.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -984,7 +1078,8 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
vertical: 8,
|
vertical: 8,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
/// Title on the left
|
/// Title on the left
|
||||||
@ -996,17 +1091,21 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Colors.grey[700],
|
color: Colors.grey[700],
|
||||||
),
|
),
|
||||||
overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow
|
overflow:
|
||||||
|
TextOverflow
|
||||||
|
.ellipsis, // Ensures title doesn't overflow
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
SizedBox(width: 16),
|
SizedBox(width: 16),
|
||||||
Container(
|
Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.2,
|
width:
|
||||||
|
MediaQuery.of(context).size.width *
|
||||||
|
0.2,
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: searchInternationalController,
|
controller:
|
||||||
|
searchInternationalController,
|
||||||
onChanged: handleInternationalFilter,
|
onChanged: handleInternationalFilter,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Search ...",
|
hintText: "Search ...",
|
||||||
@ -1020,27 +1119,36 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
size: 18,
|
size: 18,
|
||||||
),
|
),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade200,
|
color: Colors.grey.shade200,
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(
|
||||||
|
12,
|
||||||
|
),
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: Colors.grey.shade300,
|
color: Colors.grey.shade300,
|
||||||
width: 1,
|
width: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
style: GoogleFonts.poppins(fontSize: 12),
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
])
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
height:
|
height:
|
||||||
@ -1053,7 +1161,11 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
final double minWidth =
|
final double minWidth =
|
||||||
isDesktop ? constraints.maxWidth : 1300;
|
isDesktop ? constraints.maxWidth : 1300;
|
||||||
List<Map<String, dynamic>> newInternationalData =filteredInternational.isNotEmpty ? filteredInternational : internationalData;
|
List<Map<String, dynamic>>
|
||||||
|
newInternationalData =
|
||||||
|
filteredInternational.isNotEmpty
|
||||||
|
? filteredInternational
|
||||||
|
: internationalData;
|
||||||
// Pagination logic
|
// Pagination logic
|
||||||
List<Map<String, dynamic>>
|
List<Map<String, dynamic>>
|
||||||
paginatedInternational =
|
paginatedInternational =
|
||||||
@ -1062,13 +1174,43 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
.take(itemsPerPage2)
|
.take(itemsPerPage2)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return ((searchInternationalController.text.isNotEmpty && filteredInternational.isEmpty)
|
return ((searchInternationalController
|
||||||
|
.text
|
||||||
|
.isNotEmpty &&
|
||||||
|
filteredInternational.isEmpty)
|
||||||
? Center(
|
? Center(
|
||||||
child: Text(
|
child: Padding(
|
||||||
"No data found",
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height:
|
||||||
|
MediaQuery.of(
|
||||||
|
context,
|
||||||
|
).size.height /
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"No Records Found",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 14,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Please ensure the selected dates contain report data.",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -1076,17 +1218,21 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection:
|
||||||
|
Axis.horizontal,
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
minWidth: minWidth,
|
minWidth: minWidth,
|
||||||
),
|
),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection:
|
||||||
|
Axis.vertical,
|
||||||
child: DataTable(
|
child: DataTable(
|
||||||
dividerThickness: 0.5,
|
dividerThickness: 0.5,
|
||||||
columnSpacing:
|
columnSpacing:
|
||||||
isDesktop ? 30.0 : 24.0,
|
isDesktop
|
||||||
|
? 30.0
|
||||||
|
: 24.0,
|
||||||
border: TableBorder(
|
border: TableBorder(
|
||||||
horizontalInside:
|
horizontalInside:
|
||||||
BorderSide(
|
BorderSide(
|
||||||
@ -1144,8 +1290,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['Service']}',
|
'${entry['Service']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1153,9 +1298,8 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
),
|
),
|
||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['flight_service_count']}',
|
'${entry['service_count']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1164,8 +1308,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
DataCell(
|
DataCell(
|
||||||
Text(
|
Text(
|
||||||
'${entry['plan_trip_type']}',
|
'${entry['plan_trip_type']}',
|
||||||
style:
|
style: GoogleFonts.poppins(
|
||||||
GoogleFonts.poppins(
|
|
||||||
fontSize:
|
fontSize:
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
@ -1184,7 +1327,8 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
PaginationControls(
|
PaginationControls(
|
||||||
currentPage: currentPage2,
|
currentPage: currentPage2,
|
||||||
itemsPerPage: itemsPerPage2,
|
itemsPerPage: itemsPerPage2,
|
||||||
totalItems: newInternationalData.length,
|
totalItems:
|
||||||
|
newInternationalData.length,
|
||||||
activeColor: layoutColor,
|
activeColor: layoutColor,
|
||||||
onPageChanged: (page) {
|
onPageChanged: (page) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -1217,7 +1361,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildTitle(bool isDesktop){
|
Widget buildTitle(bool isDesktop) {
|
||||||
return // Left side: Breadcrumb inside a Container (optional)
|
return // Left side: Breadcrumb inside a Container (optional)
|
||||||
Container(
|
Container(
|
||||||
child: BreadcrumbNavigation(
|
child: BreadcrumbNavigation(
|
||||||
@ -1229,17 +1373,15 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
onTap: (context) {
|
onTap: (context) {
|
||||||
// Navigator.pushNamed(context, '/report');
|
// Navigator.pushNamed(context, '/report');
|
||||||
context.go("/report");
|
context.go("/report");
|
||||||
}
|
},
|
||||||
),
|
|
||||||
BreadcrumbItem(
|
|
||||||
title: 'Service Analysis Report',
|
|
||||||
),
|
),
|
||||||
|
BreadcrumbItem(title: 'Service Analysis Report'),
|
||||||
],
|
],
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildExports(bool isDesktop){
|
Widget buildExports(bool isDesktop) {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
@ -1249,10 +1391,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||||
horizontal: 20,
|
|
||||||
vertical: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
onPressed: handleDownload,
|
onPressed: handleDownload,
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -1265,11 +1404,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
Icon(
|
Icon(Icons.file_present_outlined, size: 15, color: Colors.white),
|
||||||
Icons.file_present_outlined,
|
|
||||||
size: 15,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1302,14 +1437,14 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
// ),
|
// ),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildFromDateField(bool isDesktop) {
|
Widget buildFromDateField(bool isDesktop) {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text( "From Date *",
|
Text(
|
||||||
|
"From Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -1350,12 +1485,9 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
floatingLabelBehavior:
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
FloatingLabelBehavior.never,
|
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
vertical: 16,
|
|
||||||
),
|
|
||||||
suffixIcon: const Icon(
|
suffixIcon: const Icon(
|
||||||
Icons.calendar_today,
|
Icons.calendar_today,
|
||||||
size: 16,
|
size: 16,
|
||||||
@ -1382,7 +1514,8 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text( "To Date *",
|
Text(
|
||||||
|
"To Date *",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -1398,13 +1531,10 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
height: 40,
|
height: 40,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final fromDateText =
|
final fromDateText = textControllers["from_date"]?.text;
|
||||||
textControllers["from_date"]?.text;
|
|
||||||
DateTime? mintoDate;
|
DateTime? mintoDate;
|
||||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||||
mintoDate = DateFormat(
|
mintoDate = DateFormat('dd-MM-yyyy').parse(fromDateText);
|
||||||
'dd-MM-yyyy',
|
|
||||||
).parse(fromDateText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final pickedDate = await showDatePicker(
|
final pickedDate = await showDatePicker(
|
||||||
@ -1429,16 +1559,10 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Select Date",
|
labelText: "Select Date",
|
||||||
labelStyle: TextStyle(
|
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||||
fontSize: 12,
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
floatingLabelBehavior:
|
|
||||||
FloatingLabelBehavior.never,
|
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding: EdgeInsets.symmetric(
|
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||||
vertical: 16,
|
|
||||||
),
|
|
||||||
suffixIcon: Icon(
|
suffixIcon: Icon(
|
||||||
Icons.calendar_today,
|
Icons.calendar_today,
|
||||||
size: 16,
|
size: 16,
|
||||||
@ -1457,8 +1581,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||||
maxLines: 2, // Allow it to wrap onto two lines
|
maxLines: 2, // Allow it to wrap onto two lines
|
||||||
overflow:
|
overflow:
|
||||||
TextOverflow
|
TextOverflow.ellipsis, // Add ellipsis if it still overflows
|
||||||
.ellipsis, // Add ellipsis if it still overflows
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -1466,11 +1589,8 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget buildSearchButton(bool isDesktop) {
|
Widget buildSearchButton(bool isDesktop) {
|
||||||
return
|
return Padding(
|
||||||
Padding(
|
padding: isDesktop ? const EdgeInsets.only(top: 22) : EdgeInsets.zero,
|
||||||
padding: isDesktop
|
|
||||||
? const EdgeInsets.only(top: 22)
|
|
||||||
: EdgeInsets.zero,
|
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: isDesktop ? null : double.infinity,
|
width: isDesktop ? null : double.infinity,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
@ -1483,23 +1603,17 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||||
horizontal: 20,
|
|
||||||
vertical: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
handleSubmit();
|
handleSubmit();
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize:
|
mainAxisSize: MainAxisSize.min, // Ensures content fits nicely
|
||||||
MainAxisSize.min, // Ensures content fits nicely
|
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Search",
|
"Search",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(fontSize: isDesktop ? 13 : 11),
|
||||||
fontSize: isDesktop ? 13 : 11,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(width: 8), // spacing between icon and text
|
SizedBox(width: 8), // spacing between icon and text
|
||||||
Icon(Icons.search, size: 15, color: Colors.white),
|
Icon(Icons.search, size: 15, color: Colors.white),
|
||||||
@ -1509,5 +1623,4 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,11 +36,12 @@ class TravellerDataState extends State<TravellerData> {
|
|||||||
final ApiService apiService = ApiService();
|
final ApiService apiService = ApiService();
|
||||||
Map<String, dynamic>? apiData;
|
Map<String, dynamic>? apiData;
|
||||||
|
|
||||||
final Map<String, FocusNode> focusNodes = {
|
// final Map<String, FocusNode> focusNodes = {
|
||||||
"name": FocusNode(),
|
// "name": FocusNode(),
|
||||||
"description": FocusNode(),
|
// "description": FocusNode(),
|
||||||
};
|
// };
|
||||||
|
Map<String, FocusNode> focusNodes = {};
|
||||||
|
Map<String, bool> focusStates = {};
|
||||||
final Map<String, TextEditingController> controllers = {};
|
final Map<String, TextEditingController> controllers = {};
|
||||||
Map<String, String> errorMessages = {};
|
Map<String, String> errorMessages = {};
|
||||||
|
|
||||||
@ -71,6 +72,15 @@ class TravellerDataState extends State<TravellerData> {
|
|||||||
apiData = null;
|
apiData = null;
|
||||||
for (var field in dataHeader) {
|
for (var field in dataHeader) {
|
||||||
controllers[field] = TextEditingController();
|
controllers[field] = TextEditingController();
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (widget.travellerId != null) {
|
if (widget.travellerId != null) {
|
||||||
@ -90,8 +100,18 @@ class TravellerDataState extends State<TravellerData> {
|
|||||||
for (var controller in controllers.values) {
|
for (var controller in controllers.values) {
|
||||||
controller.dispose();
|
controller.dispose();
|
||||||
}
|
}
|
||||||
|
for (var node in focusNodes.values) {
|
||||||
|
node.dispose();
|
||||||
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
void _addFocusListener(FocusNode node, Function(bool) updateState) {
|
||||||
|
node.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
updateState(node.hasFocus);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void updateTravellerDetails() {
|
void updateTravellerDetails() {
|
||||||
print("Inside Update Function - ${widget.travellerData}");
|
print("Inside Update Function - ${widget.travellerData}");
|
||||||
@ -134,10 +154,10 @@ class TravellerDataState extends State<TravellerData> {
|
|||||||
if (data[field] == null || data[field]!.trim().isEmpty) {
|
if (data[field] == null || data[field]!.trim().isEmpty) {
|
||||||
errorMessages[field] = "Required";
|
errorMessages[field] = "Required";
|
||||||
|
|
||||||
if (!hasFocused) {
|
// if (!hasFocused) {
|
||||||
focusNodes[field]?.requestFocus();
|
// focusNodes[field]?.requestFocus();
|
||||||
hasFocused = true;
|
// hasFocused = true;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,14 +306,14 @@ class TravellerDataState extends State<TravellerData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["first_nameFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: controllers["first_name"],
|
controller: controllers["first_name"],
|
||||||
focusNode: focusNodes["first_name"],
|
focusNode: focusNodes["first_nameFocusNode"],
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "First Name",
|
labelText: "First Name",
|
||||||
@ -331,14 +351,14 @@ class TravellerDataState extends State<TravellerData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["last_nameFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: controllers["last_name"],
|
controller: controllers["last_name"],
|
||||||
focusNode: focusNodes["last_name"],
|
focusNode: focusNodes["last_nameFocusNode"],
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Last Name",
|
labelText: "Last Name",
|
||||||
@ -376,14 +396,14 @@ class TravellerDataState extends State<TravellerData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["emailFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: controllers["email"],
|
controller: controllers["email"],
|
||||||
focusNode: focusNodes["email"],
|
focusNode: focusNodes["emailFocusNode"],
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Email",
|
labelText: "Email",
|
||||||
@ -421,14 +441,14 @@ class TravellerDataState extends State<TravellerData> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
CustomTextFieldForexWrapper(
|
CustomTextFieldForexWrapper(
|
||||||
isFocused: false,
|
isFocused: focusStates["mobileFocused"] ?? false,
|
||||||
isDesktop: widget.isDesktop,
|
isDesktop: widget.isDesktop,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: controllers["mobile"],
|
controller: controllers["mobile"],
|
||||||
focusNode: focusNodes["mobile"],
|
focusNode: focusNodes["mobileFocusNode"],
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: "Mobile",
|
labelText: "Mobile",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1261,7 +1261,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget buildNationality() {
|
Widget buildNationality() {
|
||||||
List<String> nationalityOptions = ["Indian", "International"];
|
List<String> nationalityOptions = ["Indian", "International","other nationality"];
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@ -27,7 +27,7 @@ class UserListScreen extends StatefulWidget {
|
|||||||
class _UserListScreenState extends State<UserListScreen> {
|
class _UserListScreenState extends State<UserListScreen> {
|
||||||
final ApiService apiService = ApiService();
|
final ApiService apiService = ApiService();
|
||||||
late Future<List<dynamic>> futureUsers;
|
late Future<List<dynamic>> futureUsers;
|
||||||
|
late bool _dialogShown = false;
|
||||||
late Map<String, dynamic> userSingleData;
|
late Map<String, dynamic> userSingleData;
|
||||||
List<dynamic>? apiCountryData;
|
List<dynamic>? apiCountryData;
|
||||||
String? selectedUserId;
|
String? selectedUserId;
|
||||||
@ -219,6 +219,54 @@ class _UserListScreenState extends State<UserListScreen> {
|
|||||||
print("handDel - $userId");
|
print("handDel - $userId");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showConfirmationDialog(String subtitle, List<String> successList, List<Map<String, String>> failedList) {
|
||||||
|
_dialogShown = true;
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
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);
|
||||||
|
_dialogShown = false;
|
||||||
|
},
|
||||||
|
child: Text("Close"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<void> handleUpload() async {
|
Future<void> handleUpload() async {
|
||||||
final String apiUrldata = '$apiUrl/api/user/userUpload'; // api
|
final String apiUrldata = '$apiUrl/api/user/userUpload'; // api
|
||||||
final String? token = await getToken(); // 2kn
|
final String? token = await getToken(); // 2kn
|
||||||
@ -303,32 +351,51 @@ class _UserListScreenState extends State<UserListScreen> {
|
|||||||
|
|
||||||
// Check the status code of the response
|
// Check the status code of the response
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
Map<String, dynamic> data = json.decode(responseString);
|
Map<String, dynamic> responseData = json.decode(responseString);
|
||||||
if (data['status'] == 'success') {
|
|
||||||
print(data['message']);
|
final message = responseData['message'] ?? '';
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
final status = responseData['status'] ?? '';
|
||||||
SnackBar(
|
final data = responseData['data'] ?? {};
|
||||||
content: Text(data['message']),
|
|
||||||
backgroundColor: Colors.green.shade500,
|
final List<String> successList = List<String>.from(data['successfulUsers'] ?? []);
|
||||||
behavior: SnackBarBehavior.floating,
|
final List<Map<String, String>> failedList = List<Map<String, String>>.from(
|
||||||
),
|
(data['failedUsers'] ?? []).map((item) => Map<String, String>.from(item)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
_showConfirmationDialog(message, successList, failedList);
|
||||||
|
|
||||||
|
// final successfulUsers = List.from(data['successfulUsers'] ?? []);
|
||||||
|
// final failedUsers = List.from(data['failedUsers'] ?? []);
|
||||||
|
|
||||||
|
// Unified SnackBar logic
|
||||||
|
// ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
// SnackBar(
|
||||||
|
// content: Text(
|
||||||
|
// combinedMessage,
|
||||||
|
// style: TextStyle(color: Colors.white),
|
||||||
|
// ),
|
||||||
|
// backgroundColor: Colors.green,
|
||||||
|
// behavior: SnackBarBehavior.floating,
|
||||||
|
// // duration: Duration(seconds: 6),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
|
||||||
|
// Refresh list if needed
|
||||||
refreshUserList();
|
refreshUserList();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
print(data['message']);
|
// For non-200 responses
|
||||||
|
final errorMsg = 'Failed to upload file: ${response.reasonPhrase}';
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(data['message']),
|
content: Text(errorMsg),
|
||||||
backgroundColor: Colors.redAccent,
|
backgroundColor: Colors.redAccent,
|
||||||
behavior: SnackBarBehavior.floating,
|
behavior: SnackBarBehavior.floating,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
refreshUserList();
|
print(errorMsg);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
print('Something went wrong');
|
|
||||||
print('Failed to upload file: ${response.reasonPhrase}');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
//api url
|
//api url
|
||||||
const String apiUrl = 'http://apitest.tripapprovaltool.com/tstat_be';
|
const String apiUrl = 'http://apitest.tripapprovaltool.com/tstat_be';
|
||||||
// const String apiUrl = 'https://uat.tripapprovaltool.com/tstat_be';
|
// const String apiUrl = 'https://uat.tripapprovaltool.com/tstat_be';
|
||||||
|
|
||||||
@ -11,6 +11,7 @@ import 'package:frontend/Screens/plans/create_plans.dart';
|
|||||||
import 'package:frontend/Screens/plans/list_plans.dart';
|
import 'package:frontend/Screens/plans/list_plans.dart';
|
||||||
import 'package:frontend/Screens/policy/policy.dart';
|
import 'package:frontend/Screens/policy/policy.dart';
|
||||||
import 'package:frontend/Screens/policy/policy_list.dart';
|
import 'package:frontend/Screens/policy/policy_list.dart';
|
||||||
|
import 'package:frontend/Screens/userManagement/create_traveller_agent/createTravelAgent.dart';
|
||||||
import 'package:frontend/Screens/userManagement/create_user/create_user1.dart';
|
import 'package:frontend/Screens/userManagement/create_user/create_user1.dart';
|
||||||
import 'package:frontend/Screens/userManagement/user_List.dart';
|
import 'package:frontend/Screens/userManagement/user_List.dart';
|
||||||
import 'package:frontend/routes/organizationSetting.dart';
|
import 'package:frontend/routes/organizationSetting.dart';
|
||||||
@ -39,6 +40,7 @@ import '../Screens/reports/misAir.dart';
|
|||||||
import '../Screens/reports/misHotel.dart';
|
import '../Screens/reports/misHotel.dart';
|
||||||
import '../Screens/reports/misForex.dart';
|
import '../Screens/reports/misForex.dart';
|
||||||
import '../Screens/reports/guestHouse.dart';
|
import '../Screens/reports/guestHouse.dart';
|
||||||
|
import '../Screens/userManagement/create_traveller_agent/listTravelAgent.dart';
|
||||||
|
|
||||||
import 'mainLayout.dart';
|
import 'mainLayout.dart';
|
||||||
|
|
||||||
@ -176,6 +178,14 @@ final GoRouter router = GoRouter(
|
|||||||
path: '/guestHouseReport',
|
path: '/guestHouseReport',
|
||||||
builder: (context, state) => GuestHouse(),
|
builder: (context, state) => GuestHouse(),
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/listTravelAgent',
|
||||||
|
builder: (context, state) => TravelAgentListScreen(),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/CreateTravelAgent',
|
||||||
|
builder: (context, state) => CreateTravelAgentFormDetials(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -146,6 +146,12 @@ class OrganizationSettingState extends State<OrganizationSetting> {
|
|||||||
'label': 'Traveller (Non Employee)',
|
'label': 'Traveller (Non Employee)',
|
||||||
'description': 'Create and Edit Traveller',
|
'description': 'Create and Edit Traveller',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'value': '/listTravelAgent',
|
||||||
|
'icon': Icons.person_pin_outlined,
|
||||||
|
'label': 'Travel Agents',
|
||||||
|
'description': 'Create and Edit Travel Agent',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// List<Widget> rows = [];
|
// List<Widget> rows = [];
|
||||||
|
|||||||
@ -643,25 +643,6 @@ class ApiService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> viewPlanTravelAgent(
|
|
||||||
BuildContext context,
|
|
||||||
String planId, {
|
|
||||||
bool isViewMode = false,
|
|
||||||
bool isMyTrips = false,
|
|
||||||
}) async {
|
|
||||||
try {
|
|
||||||
Map<String, dynamic> planData = await getViewPlanEdit(planId);
|
|
||||||
print("ViewAAA - $planData");
|
|
||||||
|
|
||||||
context.go(
|
|
||||||
'/travelagent/trips',
|
|
||||||
extra: {'planData': planData, 'isViewMode': isViewMode},
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
print("Error fetching plan: $e");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map<String, dynamic>> fetchUserApprovalList() async {
|
Future<Map<String, dynamic>> fetchUserApprovalList() async {
|
||||||
String? orgId = await getOrgId();
|
String? orgId = await getOrgId();
|
||||||
String? userId = await getUserId();
|
String? userId = await getUserId();
|
||||||
@ -1301,6 +1282,25 @@ class ApiService {
|
|||||||
false; // Default to false if dismissed
|
false; // Default to false if dismissed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<void> viewPlanTravelAgent(
|
||||||
|
BuildContext context,
|
||||||
|
String planId, {
|
||||||
|
bool isViewMode = false,
|
||||||
|
bool isMyTrips = false,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
Map<String, dynamic> planData = await getViewPlanEdit(planId);
|
||||||
|
print("ViewAAA - $planData");
|
||||||
|
|
||||||
|
context.go(
|
||||||
|
'/travelagent/trips',
|
||||||
|
extra: {'planData': planData, 'isViewMode': isViewMode},
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print("Error fetching plan: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> getCostCenterDetailsFind(int id) async {
|
Future<Map<String, dynamic>> getCostCenterDetailsFind(int id) async {
|
||||||
final String apiUrldata = '$apiUrl/api/findCostCenter?cost_center_id=$id';
|
final String apiUrldata = '$apiUrl/api/findCostCenter?cost_center_id=$id';
|
||||||
|
|
||||||
|
|||||||
@ -63,25 +63,25 @@ class _CustomTextFieldForexWrapperState
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
// color: widget.color,
|
// color: widget.color,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(8),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: widget.isFocused ? layoutColor! : Color(0xFFD6D5E6),
|
color: widget.isFocused ? layoutColor! : Color(0xFFD6D5E6),
|
||||||
// color: widget.isFocused ? Color(0xFF78B4FC) : Color(0xFFD6D5E6),
|
// color: widget.isFocused ? Color(0xFF78B4FC) : Color(0xFFD6D5E6),
|
||||||
width: widget.isFocused ? 1.0 : 0.5,
|
width: widget.isFocused ? 1.0 : 0.5,
|
||||||
),
|
),
|
||||||
boxShadow:
|
// boxShadow:
|
||||||
widget.isFocused
|
// widget.isFocused
|
||||||
? [
|
// ? [
|
||||||
BoxShadow(
|
// BoxShadow(
|
||||||
color: Colors.white,
|
// color: Colors.white,
|
||||||
// color: Color.fromRGBO(120, 180, 252, 0.3),
|
// // color: Color.fromRGBO(120, 180, 252, 0.3),
|
||||||
// color: Color.fromRGBO(120, 180, 252, 0.3),
|
// // color: Color.fromRGBO(120, 180, 252, 0.3),
|
||||||
blurRadius: 5,
|
// blurRadius: 5,
|
||||||
spreadRadius: 2,
|
// spreadRadius: 2,
|
||||||
offset: Offset(0, 1),
|
// offset: Offset(0, 1),
|
||||||
),
|
// ),
|
||||||
]
|
// ]
|
||||||
: [],
|
// : [],
|
||||||
),
|
),
|
||||||
// decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
// color: widget.color,
|
// color: widget.color,
|
||||||
|
|||||||
88
lib/widgets/popup_travelAgentList_action.dart
Normal file
88
lib/widgets/popup_travelAgentList_action.dart
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
|
import '../services/apiService.dart';
|
||||||
|
import 'custom_popup.dart';
|
||||||
|
|
||||||
|
class UserActionsMenu extends StatelessWidget {
|
||||||
|
final ApiService apiService = ApiService();
|
||||||
|
final Map<String, dynamic> user;
|
||||||
|
final Future<Map<String, dynamic>> Function(int userId) getUserDetails;
|
||||||
|
|
||||||
|
UserActionsMenu({
|
||||||
|
super.key,
|
||||||
|
required this.user,
|
||||||
|
required this.getUserDetails,
|
||||||
|
});
|
||||||
|
|
||||||
|
int getUserId(dynamic value) {
|
||||||
|
if (value is String) return int.parse(value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return PopupMenuButton<int>(
|
||||||
|
color: Colors.white,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
offset: Offset(0, 30),
|
||||||
|
icon: Icon(
|
||||||
|
Icons.more_vert,
|
||||||
|
color: Color(0xFF475569),
|
||||||
|
size: 14,
|
||||||
|
),
|
||||||
|
itemBuilder: (context) => [
|
||||||
|
CustomPopupMenuEntry(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
child: Tooltip(
|
||||||
|
message: 'View Details',
|
||||||
|
child: Icon(Icons.remove_red_eye,
|
||||||
|
color: Color(0xFF475569), size: 18)
|
||||||
|
),
|
||||||
|
// child: Icon(Icons.remove_red_eye,
|
||||||
|
// color: Color(0xFF475569), size: 18,),
|
||||||
|
onTap: () async {
|
||||||
|
Navigator.pop(context); // Close the menu
|
||||||
|
final userId = getUserId(user['user_id']);
|
||||||
|
final usersData = await getUserDetails(userId);
|
||||||
|
context.go("/CreateTravelAgent", extra: {
|
||||||
|
"selectedUser": usersData,
|
||||||
|
"isViewMode": true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
GestureDetector(
|
||||||
|
child: Tooltip(
|
||||||
|
message: 'Edit Details',
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/IconsImg/edit.png',
|
||||||
|
width: 20,
|
||||||
|
height: 15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
Navigator.pop(context); // Close the menu
|
||||||
|
final userId = getUserId(user['user_id']);
|
||||||
|
final usersData = await getUserDetails(userId);
|
||||||
|
context.go("/CreateTravelAgent", extra: {
|
||||||
|
"selectedUser": usersData,
|
||||||
|
"isViewMode": false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user