Merge branch 'main' of bitbucket.org:venbainformationtechnology/ts-tat

This commit is contained in:
venbaittech 2025-06-19 09:16:47 +05:30
commit 1fcd57f676
6 changed files with 1016 additions and 264 deletions

View File

@ -53,9 +53,10 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
List<Map<String, dynamic>> internationalData = []; List<Map<String, dynamic>> internationalData = [];
// Map<String, dynamic> domesticData = {}; // Map<String, dynamic> domesticData = {};
// Map<String, dynamic> internationalData = {}; // Map<String, dynamic> internationalData = {};
// List<Map<String, dynamic>> filteredDomestic = []; List<Map<String, dynamic>> filteredDomestic = [];
List filteredInternational = []; List<Map<String, dynamic>> filteredInternational = [];
TextEditingController searchController = TextEditingController(); TextEditingController searchDomesticController = TextEditingController();
TextEditingController searchInternationalController = TextEditingController();
bool loaderFlag = false; bool loaderFlag = false;
@ -100,9 +101,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
switch (index) { switch (index) {
case 0: return "domestic"; case 0: return "domestic";
case 1: return "international"; case 1: return "international";
default: default: return "domestic"; // return "Unknown";
// return "Unknown";
return "domestic";
} }
} }
@ -159,7 +158,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
loadInitialData(); loadInitialData();
}); });
} catch (e) { } catch (e) {
print("service report : $e"); print("advance report : $e");
} }
} }
@ -260,7 +259,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
domesticData = List<Map<String, dynamic>>.from( domesticData = List<Map<String, dynamic>>.from(
result['status'] == 'success' ? result['data']['domestic'] ?? [] : [], result['status'] == 'success' ? result['data']['domestic'] ?? [] : [],
); );
// filteredDomestic = domesticData; filteredDomestic = domesticData;
internationalData = List<Map<String, dynamic>>.from( internationalData = List<Map<String, dynamic>>.from(
@ -268,6 +267,8 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
? result['data']['international'] ?? [] ? result['data']['international'] ?? []
: [], : [],
); );
filteredInternational = internationalData;
loaderFlag = false; loaderFlag = false;
}); });
} catch (e) { } catch (e) {
@ -327,44 +328,42 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
); );
} }
// void handleDomesticFilter(String query) { void handleDomesticFilter(String query) {
// print(" so sad :( ** ");
// print("filtereddomesticData: $domesticData");
//
// final lowerQuery = query.toLowerCase();
// setState(() {
// filteredDomestic =
// domesticData.where((object) {
// return (object['plan_id']?.toLowerCase().contains(lowerQuery) ?? false) ||
// (object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) ||
// (object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) ||
// (object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) ||
// (object['flight_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
// (object['plan_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
// (object['sector']?.toLowerCase().contains(lowerQuery));
// }).toList();
// currentPage1 = 0;
// });
// print("filtereddomesticData: $filteredDomestic");
// }
// void handleInternationalFilter(String query) { final lowerQuery = query.toLowerCase();
// final lowerQuery = query.toLowerCase(); setState(() {
// setState(() { filteredDomestic =
// filteredInternational = domesticData.where((object) {
// internationalData.where((object) { return (object['plan_id']?.toLowerCase().contains(lowerQuery) ?? false) ||
// return (object['plan_id']?.toLowerCase().contains(lowerQuery) ?? false) || (object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) ||
// (object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) || (object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) ||
// (object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) || (object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) ||
// (object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) || (object['flight_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
// (object['flight_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) || (object['plan_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
// (object['plan_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) || (object['sector']?.toLowerCase().contains(lowerQuery));
// (object['sector']?.toLowerCase().contains(lowerQuery)); }).toList();
// }).toList(); currentPage1 = 0;
// currentPage1 = 0; });
// }); print("handleDomesticFilter > Total entries: ${filteredDomestic?.length ?? 0}");
// print("filteredInternational: $filteredInternational"); }
// }
void handleInternationalFilter(String query) {
final lowerQuery = query.toLowerCase();
setState(() {
filteredInternational =
internationalData.where((object) {
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['flight_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['sector']?.toLowerCase().contains(lowerQuery));
}).toList();
currentPage2 = 0;
});
print("handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}");
}
@override @override
// Widget build(BuildContext context) { // Widget build(BuildContext context) {
@ -763,45 +762,45 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
.ellipsis, // Ensures title doesn't overflow .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: searchController, controller: searchDomesticController,
// onChanged: handleDomesticFilter, onChanged: handleDomesticFilter,
// decoration: InputDecoration( decoration: InputDecoration(
// hintText: "Search ...", hintText: "Search ...",
// hintStyle: TextStyle( hintStyle: TextStyle(
// fontSize: 12, fontSize: 12,
// color: Color(0xFF9E9DBD), color: Color(0xFF9E9DBD),
// ), ),
// prefixIcon: Icon( prefixIcon: Icon(
// Icons.search, Icons.search,
// color: Color(0xFF9E9DBD), color: Color(0xFF9E9DBD),
// 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),
// ), ),
// ), ),
// /// Buttons on the right // /// Buttons on the right
// Row( // Row(
// children: [ // children: [
@ -907,19 +906,29 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
isDesktop ? constraints.maxWidth : 1300; isDesktop ? constraints.maxWidth : 1300;
// List<Map<String, dynamic>> newDomesticData = List<Map<String, dynamic>> newDomesticData =filteredDomestic.isNotEmpty ? filteredDomestic : domesticData;
// filteredDomestic.isNotEmpty ? filteredDomestic : domesticData;
// Pagination logic // Pagination logic
List<Map<String, dynamic>> List<Map<String, dynamic>>
paginatedDomestic = paginatedDomestic =
domesticData newDomesticData
.skip(currentPage1 * itemsPerPage1) .skip(currentPage1 * itemsPerPage1)
.take(itemsPerPage1) .take(itemsPerPage1)
.toList(); .toList();
return Column( return (
(searchDomesticController.text.isNotEmpty && filteredDomestic.isEmpty)
? Center(
child: Text(
"No data found",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
)
: Column(
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -1119,7 +1128,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
PaginationControls( PaginationControls(
currentPage: currentPage1, currentPage: currentPage1,
itemsPerPage: itemsPerPage1, itemsPerPage: itemsPerPage1,
totalItems: domesticData.length, totalItems: newDomesticData.length,
activeColor: layoutColor, activeColor: layoutColor,
onPageChanged: (page) { onPageChanged: (page) {
setState(() { setState(() {
@ -1134,7 +1143,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
}, },
), ),
], ],
); ));
}, },
), ),
), ),
@ -1281,14 +1290,64 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
horizontal: 16.0, horizontal: 16.0,
vertical: 8, vertical: 8,
), ),
child: Text( child: Row(
"International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})", mainAxisAlignment: MainAxisAlignment.spaceBetween,
style: GoogleFonts.poppins( crossAxisAlignment: CrossAxisAlignment.center,
fontSize: 13, children: [
fontWeight: FontWeight.w500, /// Title on the left
color: Colors.grey[700], Expanded(
), child: Text(
), "International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})",
style: GoogleFonts.poppins(
fontSize: 13,
fontWeight: FontWeight.w500,
color: Colors.grey[700],
),
overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow
),
),
SizedBox(width: 16),
Container(
width: MediaQuery.of(context).size.width * 0.2,
height: 40,
child: TextField(
controller: searchInternationalController,
onChanged: handleInternationalFilter,
decoration: InputDecoration(
hintText: "Search ...",
hintStyle: TextStyle(
fontSize: 12,
color: Color(0xFF9E9DBD),
),
prefixIcon: Icon(
Icons.search,
color: Color(0xFF9E9DBD),
size: 18,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade200,
width: 0.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade300,
width: 1,
),
),
),
style: GoogleFonts.poppins(fontSize: 12),
),
),
])
), ),
Container( Container(
height: height:
@ -1301,16 +1360,26 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
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;
// Pagination logic // Pagination logic
List<Map<String, dynamic>> List<Map<String, dynamic>>
paginatedInternational = paginatedInternational =
internationalData newInternationalData
.skip(currentPage2 * itemsPerPage2) .skip(currentPage2 * itemsPerPage2)
.take(itemsPerPage2) .take(itemsPerPage2)
.toList(); .toList();
return Column( return ((searchInternationalController.text.isNotEmpty && filteredInternational.isEmpty)
? Center(
child: Text(
"No data found",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
)
:Column(
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -1510,7 +1579,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
PaginationControls( PaginationControls(
currentPage: currentPage2, currentPage: currentPage2,
itemsPerPage: itemsPerPage2, itemsPerPage: itemsPerPage2,
totalItems: internationalData.length, totalItems: newInternationalData.length,
activeColor: layoutColor, activeColor: layoutColor,
onPageChanged: (page) { onPageChanged: (page) {
setState(() { setState(() {
@ -1525,7 +1594,7 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
}, },
), ),
], ],
); ));
}, },
), ),
), ),

View File

@ -53,6 +53,10 @@ class _GuestHouseState extends State<GuestHouse>
List<Map<String, dynamic>> internationalData = []; List<Map<String, dynamic>> internationalData = [];
// Map<String, dynamic> domesticData = {}; // Map<String, dynamic> domesticData = {};
// Map<String, dynamic> internationalData = {}; // Map<String, dynamic> internationalData = {};
List<Map<String, dynamic>> filteredDomestic = [];
List<Map<String, dynamic>> filteredInternational = [];
TextEditingController searchDomesticController = TextEditingController();
TextEditingController searchInternationalController = TextEditingController();
bool loaderFlag = false; bool loaderFlag = false;
@ -107,13 +111,9 @@ class _GuestHouseState extends State<GuestHouse>
String getTabName(int index) { String getTabName(int index) {
switch (index) { switch (index) {
case 0: case 0: return "domestic";
return "domestic"; case 1: return "international";
case 1: default: return "domestic"; // return "Unknown";
return "international";
default:
// return "Unknown";
return "domestic";
} }
} }
@ -158,7 +158,7 @@ class _GuestHouseState extends State<GuestHouse>
loadInitialData(); loadInitialData();
}); });
} catch (e) { } catch (e) {
print("service report : $e"); print("guest report : $e");
} }
} }
@ -277,6 +277,10 @@ class _GuestHouseState extends State<GuestHouse>
? result['data']['international'] ?? [] ? result['data']['international'] ?? []
: [], : [],
); );
filteredDomestic = domesticData;
filteredInternational = internationalData;
loaderFlag = false; loaderFlag = false;
}); });
} catch (e) { } catch (e) {
@ -336,6 +340,50 @@ class _GuestHouseState extends State<GuestHouse>
); );
} }
void handleDomesticFilter(String query) {
final lowerQuery = query.toLowerCase();
setState(() {
filteredDomestic =
domesticData.where((object) {
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) ||
(object['flight_travel_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['sector']?.toLowerCase().contains(lowerQuery));
}).toList();
currentPage1 = 0;
});
print("handleDomesticFilter > Total entries: ${filteredDomestic?.length ?? 0}");
}
void handleInternationalFilter(String query) {
final lowerQuery = query.toLowerCase();
setState(() {
filteredInternational =
internationalData.where((object) {
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) ||
(object['flight_travel_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['sector']?.toLowerCase().contains(lowerQuery));
}).toList();
currentPage2 = 0;
});
print("handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}");
}
@override @override
// Widget build(BuildContext context) { // Widget build(BuildContext context) {
// // TODO: implement build // // TODO: implement build
@ -708,6 +756,44 @@ class _GuestHouseState extends State<GuestHouse>
.ellipsis, // Ensures title doesn't overflow .ellipsis, // Ensures title doesn't overflow
), ),
), ),
Container(
width: MediaQuery.of(context).size.width * 0.2,
height: 40,
child: TextField(
controller: searchDomesticController,
onChanged: handleDomesticFilter,
decoration: InputDecoration(
hintText: "Search ...",
hintStyle: TextStyle(
fontSize: 12,
color: Color(0xFF9E9DBD),
),
prefixIcon: Icon(
Icons.search,
color: Color(0xFF9E9DBD),
size: 18,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade200,
width: 0.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade300,
width: 1,
),
),
),
style: GoogleFonts.poppins(fontSize: 12),
),
),
// SizedBox(width: 16), // SizedBox(width: 16),
// /// Buttons on the right // /// Buttons on the right
// Row( // Row(
@ -813,15 +899,29 @@ 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;
// Pagination logic // Pagination logic
List<Map<String, dynamic>> List<Map<String, dynamic>>
paginatedDomestic = paginatedDomestic =
domesticData newDomesticData
.skip(currentPage1 * itemsPerPage1) .skip(currentPage1 * itemsPerPage1)
.take(itemsPerPage1) .take(itemsPerPage1)
.toList(); .toList();
return Column( return (
(searchDomesticController.text.isNotEmpty && filteredDomestic.isEmpty)
? Center(
child: Text(
"No data found",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
)
: Column(
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -1073,7 +1173,7 @@ class _GuestHouseState extends State<GuestHouse>
PaginationControls( PaginationControls(
currentPage: currentPage1, currentPage: currentPage1,
itemsPerPage: itemsPerPage1, itemsPerPage: itemsPerPage1,
totalItems: domesticData.length, totalItems: newDomesticData.length,
activeColor: layoutColor, activeColor: layoutColor,
onPageChanged: (page) { onPageChanged: (page) {
setState(() { setState(() {
@ -1088,7 +1188,7 @@ class _GuestHouseState extends State<GuestHouse>
}, },
), ),
], ],
); ));
}, },
), ),
), ),
@ -1235,14 +1335,64 @@ class _GuestHouseState extends State<GuestHouse>
horizontal: 16.0, horizontal: 16.0,
vertical: 8, vertical: 8,
), ),
child: Text( child: Row(
"International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})", mainAxisAlignment: MainAxisAlignment.spaceBetween,
style: GoogleFonts.poppins( crossAxisAlignment: CrossAxisAlignment.center,
fontSize: 13, children: [
fontWeight: FontWeight.w500, /// Title on the left
color: Colors.grey[700], Expanded(
), child: Text(
), "International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})",
style: GoogleFonts.poppins(
fontSize: 13,
fontWeight: FontWeight.w500,
color: Colors.grey[700],
),
overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow
),
),
SizedBox(width: 16),
Container(
width: MediaQuery.of(context).size.width * 0.2,
height: 40,
child: TextField(
controller: searchInternationalController,
onChanged: handleInternationalFilter,
decoration: InputDecoration(
hintText: "Search ...",
hintStyle: TextStyle(
fontSize: 12,
color: Color(0xFF9E9DBD),
),
prefixIcon: Icon(
Icons.search,
color: Color(0xFF9E9DBD),
size: 18,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade200,
width: 0.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade300,
width: 1,
),
),
),
style: GoogleFonts.poppins(fontSize: 12),
),
),
])
), ),
Container( Container(
height: height:
@ -1255,16 +1405,26 @@ 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;
// Pagination logic // Pagination logic
List<Map<String, dynamic>> List<Map<String, dynamic>>
paginatedInternational = paginatedInternational =
internationalData newInternationalData
.skip(currentPage2 * itemsPerPage2) .skip(currentPage2 * itemsPerPage2)
.take(itemsPerPage2) .take(itemsPerPage2)
.toList(); .toList();
return Column( return ((searchInternationalController.text.isNotEmpty && filteredInternational.isEmpty)
? Center(
child: Text(
"No data found",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
)
:Column(
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -1526,7 +1686,7 @@ class _GuestHouseState extends State<GuestHouse>
PaginationControls( PaginationControls(
currentPage: currentPage2, currentPage: currentPage2,
itemsPerPage: itemsPerPage2, itemsPerPage: itemsPerPage2,
totalItems: internationalData.length, totalItems: newInternationalData.length,
activeColor: layoutColor, activeColor: layoutColor,
onPageChanged: (page) { onPageChanged: (page) {
setState(() { setState(() {
@ -1541,7 +1701,7 @@ class _GuestHouseState extends State<GuestHouse>
}, },
), ),
], ],
); ));
}, },
), ),
), ),

View File

@ -52,6 +52,10 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
List<Map<String, dynamic>> internationalData = []; List<Map<String, dynamic>> internationalData = [];
// Map<String, dynamic> domesticData = {}; // Map<String, dynamic> domesticData = {};
// Map<String, dynamic> internationalData = {}; // Map<String, dynamic> internationalData = {};
List<Map<String, dynamic>> filteredDomestic = [];
List<Map<String, dynamic>> filteredInternational = [];
TextEditingController searchDomesticController = TextEditingController();
TextEditingController searchInternationalController = TextEditingController();
bool loaderFlag = false; bool loaderFlag = false;
@ -106,13 +110,9 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
String getTabName(int index) { String getTabName(int index) {
switch (index) { switch (index) {
case 0: case 0: return "domestic";
return "domestic"; case 1: return "international";
case 1: default: return "domestic"; // return "Unknown";
return "international";
default:
// return "Unknown";
return "domestic";
} }
} }
@ -157,7 +157,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
loadInitialData(); loadInitialData();
}); });
} catch (e) { } catch (e) {
print("service report : $e"); print("Air report : $e");
} }
} }
@ -276,6 +276,10 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
? result['data']['international'] ?? [] ? result['data']['international'] ?? []
: [], : [],
); );
filteredDomestic = domesticData;
filteredInternational = internationalData;
loaderFlag = false; loaderFlag = false;
}); });
} catch (e) { } catch (e) {
@ -335,6 +339,49 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
); );
} }
void handleDomesticFilter(String query) {
final lowerQuery = query.toLowerCase();
setState(() {
filteredDomestic =
domesticData.where((object) {
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) ||
(object['flight_travel_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['sector']?.toLowerCase().contains(lowerQuery));
}).toList();
currentPage1 = 0;
});
print("handleDomesticFilter > Total entries: ${filteredDomestic?.length ?? 0}");
}
void handleInternationalFilter(String query) {
final lowerQuery = query.toLowerCase();
setState(() {
filteredInternational =
internationalData.where((object) {
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) ||
(object['flight_travel_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['sector']?.toLowerCase().contains(lowerQuery));
}).toList();
currentPage2 = 0;
});
print("handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}");
}
@override @override
// Widget build(BuildContext context) { // Widget build(BuildContext context) {
// // TODO: implement build // // TODO: implement build
@ -734,6 +781,44 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
.ellipsis, // Ensures title doesn't overflow .ellipsis, // Ensures title doesn't overflow
), ),
), ),
Container(
width: MediaQuery.of(context).size.width * 0.2,
height: 40,
child: TextField(
controller: searchDomesticController,
onChanged: handleDomesticFilter,
decoration: InputDecoration(
hintText: "Search ...",
hintStyle: TextStyle(
fontSize: 12,
color: Color(0xFF9E9DBD),
),
prefixIcon: Icon(
Icons.search,
color: Color(0xFF9E9DBD),
size: 18,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade200,
width: 0.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade300,
width: 1,
),
),
),
style: GoogleFonts.poppins(fontSize: 12),
),
),
// SizedBox(width: 16), // SizedBox(width: 16),
// /// Buttons on the right // /// Buttons on the right
// Row( // Row(
@ -839,15 +924,29 @@ 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;
// Pagination logic // Pagination logic
List<Map<String, dynamic>> List<Map<String, dynamic>>
paginatedDomestic = paginatedDomestic =
domesticData newDomesticData
.skip(currentPage1 * itemsPerPage1) .skip(currentPage1 * itemsPerPage1)
.take(itemsPerPage1) .take(itemsPerPage1)
.toList(); .toList();
return Column( return (
(searchDomesticController.text.isNotEmpty && filteredDomestic.isEmpty)
? Center(
child: Text(
"No data found",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
)
: Column(
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -1099,7 +1198,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
PaginationControls( PaginationControls(
currentPage: currentPage1, currentPage: currentPage1,
itemsPerPage: itemsPerPage1, itemsPerPage: itemsPerPage1,
totalItems: domesticData.length, totalItems: newDomesticData.length,
activeColor: layoutColor, activeColor: layoutColor,
onPageChanged: (page) { onPageChanged: (page) {
setState(() { setState(() {
@ -1114,7 +1213,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
}, },
), ),
], ],
); ));
}, },
), ),
), ),
@ -1261,14 +1360,64 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
horizontal: 16.0, horizontal: 16.0,
vertical: 8, vertical: 8,
), ),
child: Text( child: Row(
"International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})", mainAxisAlignment: MainAxisAlignment.spaceBetween,
style: GoogleFonts.poppins( crossAxisAlignment: CrossAxisAlignment.center,
fontSize: 13, children: [
fontWeight: FontWeight.w500, /// Title on the left
color: Colors.grey[700], Expanded(
), child: Text(
), "International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})",
style: GoogleFonts.poppins(
fontSize: 13,
fontWeight: FontWeight.w500,
color: Colors.grey[700],
),
overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow
),
),
SizedBox(width: 16),
Container(
width: MediaQuery.of(context).size.width * 0.2,
height: 40,
child: TextField(
controller: searchInternationalController,
onChanged: handleInternationalFilter,
decoration: InputDecoration(
hintText: "Search ...",
hintStyle: TextStyle(
fontSize: 12,
color: Color(0xFF9E9DBD),
),
prefixIcon: Icon(
Icons.search,
color: Color(0xFF9E9DBD),
size: 18,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade200,
width: 0.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade300,
width: 1,
),
),
),
style: GoogleFonts.poppins(fontSize: 12),
),
),
])
), ),
Container( Container(
height: height:
@ -1281,16 +1430,26 @@ 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;
// Pagination logic // Pagination logic
List<Map<String, dynamic>> List<Map<String, dynamic>>
paginatedInternational = paginatedInternational =
internationalData newInternationalData
.skip(currentPage2 * itemsPerPage2) .skip(currentPage2 * itemsPerPage2)
.take(itemsPerPage2) .take(itemsPerPage2)
.toList(); .toList();
return Column( return ((searchInternationalController.text.isNotEmpty && filteredInternational.isEmpty)
? Center(
child: Text(
"No data found",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
)
: Column(
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -1557,7 +1716,7 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
}, },
), ),
], ],
); ));
}, },
), ),
), ),

View File

@ -38,21 +38,18 @@ class _MISforexState extends State<MISforex>
Color? layoutColor; Color? layoutColor;
Color? bodyColor; Color? bodyColor;
int currentPage1 = 0; int currentPage = 0;
int itemsPerPage1 = 10; int itemsPerPage = 10;
int currentPage2 = 0; String selectedTabName = 'international';
int itemsPerPage2 = 10;
late TabController _tabController;
String selectedTabName = 'domestic';
Map<String, FocusNode> focusNodes = {}; Map<String, FocusNode> focusNodes = {};
Map<String, bool> focusStates = {}; Map<String, bool> focusStates = {};
Map<String, TextEditingController> textControllers = {}; Map<String, TextEditingController> textControllers = {};
Map<String, String> errorMessages = {}; Map<String, String> errorMessages = {};
// Map<String, dynamic> MISforexReport = {}; // Map<String, dynamic> MISforexReport = {};
List<Map<String, dynamic>> domesticData = [];
List<Map<String, dynamic>> internationalData = []; List<Map<String, dynamic>> internationalData = [];
// Map<String, dynamic> domesticData = {};
// Map<String, dynamic> internationalData = {}; // Map<String, dynamic> internationalData = {};
List<Map<String, dynamic>> filteredInternational = [];
TextEditingController searchInternationalController = TextEditingController();
bool loaderFlag = false; bool loaderFlag = false;
@ -80,17 +77,6 @@ class _MISforexState extends State<MISforex>
focusStates["from_date"] = false; focusStates["from_date"] = false;
} }
_tabController = TabController(length: 2, vsync: this);
_tabController.addListener(() {
if (_tabController.indexIsChanging == false) {
// Only fire when tab change is complete
setState(() {
selectedTabName = getTabName(_tabController.index);
});
print(" :) :X Selected Tab: ${getTabName(_tabController.index)}");
}
});
// Add focus listeners // Add focus listeners
focusNodes.forEach((key, focusNode) { focusNodes.forEach((key, focusNode) {
@ -105,17 +91,6 @@ class _MISforexState extends State<MISforex>
// fetchMISforexReport(); // fetchMISforexReport();
} }
String getTabName(int index) {
switch (index) {
case 0:
return "domestic";
case 1:
return "international";
default:
// return "Unknown";
return "domestic";
}
}
void _addFocusListener(FocusNode node, Function(bool) updateState) { void _addFocusListener(FocusNode node, Function(bool) updateState) {
node.addListener(() { node.addListener(() {
@ -158,7 +133,7 @@ class _MISforexState extends State<MISforex>
loadInitialData(); loadInitialData();
}); });
} catch (e) { } catch (e) {
print("service report : $e"); print("Forex report : $e");
} }
} }
@ -213,12 +188,9 @@ class _MISforexState extends State<MISforex>
errorMessages.remove("from_date"); errorMessages.remove("from_date");
errorMessages.remove("to_date"); errorMessages.remove("to_date");
setState(() { setState(() {
domesticData = [];
internationalData = []; internationalData = [];
currentPage1 = 0; currentPage = 0;
itemsPerPage1 = 10; itemsPerPage = 10;
currentPage2 = 0;
itemsPerPage2 = 10;
}); });
final fromDateText = textControllers["from_date"]?.text; final fromDateText = textControllers["from_date"]?.text;
final toDateText = textControllers["to_date"]?.text; final toDateText = textControllers["to_date"]?.text;
@ -271,9 +243,11 @@ class _MISforexState extends State<MISforex>
// 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']['international'] ?? [] ? result['data'] ?? []
: [], : [],
); );
filteredInternational = internationalData;
loaderFlag = false; loaderFlag = false;
}); });
} catch (e) { } catch (e) {
@ -310,7 +284,7 @@ class _MISforexState extends State<MISforex>
final formattedToDate = DateFormat('yyyy-MM-dd').format(toDate); final formattedToDate = DateFormat('yyyy-MM-dd').format(toDate);
final name = final name =
'MIS Forex - $selectedTabName Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})'; 'MIS Forex - International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})';
final safeName = name.replaceAll(RegExp(r'[^\w\s-]'), ''); final safeName = name.replaceAll(RegExp(r'[^\w\s-]'), '');
final excelName = '$safeName'; final excelName = '$safeName';
@ -333,6 +307,26 @@ class _MISforexState extends State<MISforex>
); );
} }
void handleInternationalFilter(String query) {
final lowerQuery = query.toLowerCase();
setState(() {
filteredInternational =
internationalData.where((object) {
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) ||
(object['forex_from_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['forex_to_date']?.toLowerCase().contains(lowerQuery));
}).toList();
currentPage = 0;
});
print("handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}");
}
@override @override
// Widget build(BuildContext context) { // Widget build(BuildContext context) {
// // TODO: implement build // // TODO: implement build
@ -698,14 +692,64 @@ class _MISforexState extends State<MISforex>
horizontal: 16.0, horizontal: 16.0,
vertical: 8, vertical: 8,
), ),
child: Text( child: Row(
"International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})", mainAxisAlignment: MainAxisAlignment.spaceBetween,
style: GoogleFonts.poppins( crossAxisAlignment: CrossAxisAlignment.center,
fontSize: 13, children: [
fontWeight: FontWeight.w500, /// Title on the left
color: Colors.grey[700], Expanded(
), child: Text(
), "International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})",
style: GoogleFonts.poppins(
fontSize: 13,
fontWeight: FontWeight.w500,
color: Colors.grey[700],
),
overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow
),
),
SizedBox(width: 16),
Container(
width: MediaQuery.of(context).size.width * 0.2,
height: 40,
child: TextField(
controller: searchInternationalController,
onChanged: handleInternationalFilter,
decoration: InputDecoration(
hintText: "Search ...",
hintStyle: TextStyle(
fontSize: 12,
color: Color(0xFF9E9DBD),
),
prefixIcon: Icon(
Icons.search,
color: Color(0xFF9E9DBD),
size: 18,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade200,
width: 0.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade300,
width: 1,
),
),
),
style: GoogleFonts.poppins(fontSize: 12),
),
),
])
), ),
// Table container // Table container
Container( Container(
@ -718,16 +762,26 @@ 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;
// Pagination logic // Pagination logic
List<Map<String, dynamic>> List<Map<String, dynamic>>
paginatedInternational = paginatedInternational =
internationalData newInternationalData
.skip(currentPage2 * itemsPerPage2) .skip(currentPage * itemsPerPage)
.take(itemsPerPage2) .take(itemsPerPage)
.toList(); .toList();
return Column( return ((searchInternationalController.text.isNotEmpty && filteredInternational.isEmpty)
? Center(
child: Text(
"No data found",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
)
:Column(
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -970,24 +1024,24 @@ class _MISforexState extends State<MISforex>
), ),
), ),
PaginationControls( PaginationControls(
currentPage: currentPage2, currentPage: currentPage,
itemsPerPage: itemsPerPage2, itemsPerPage: itemsPerPage,
totalItems: internationalData.length, totalItems: newInternationalData.length,
activeColor: layoutColor, activeColor: layoutColor,
onPageChanged: (page) { onPageChanged: (page) {
setState(() { setState(() {
currentPage2 = page; currentPage = page;
}); });
}, },
onItemsPerPageChanged: (items) { onItemsPerPageChanged: (items) {
setState(() { setState(() {
itemsPerPage2 = items; itemsPerPage = items;
currentPage2 = 0; currentPage = 0;
}); });
}, },
), ),
], ],
); ));
}, },
), ),
), ),

View File

@ -54,6 +54,10 @@ class _MIShotelState extends State<MIShotel>
List<Map<String, dynamic>> internationalData = []; List<Map<String, dynamic>> internationalData = [];
// Map<String, dynamic> domesticData = {}; // Map<String, dynamic> domesticData = {};
// Map<String, dynamic> internationalData = {}; // Map<String, dynamic> internationalData = {};
List<Map<String, dynamic>> filteredDomestic = [];
List<Map<String, dynamic>> filteredInternational = [];
TextEditingController searchDomesticController = TextEditingController();
TextEditingController searchInternationalController = TextEditingController();
bool loaderFlag = false; bool loaderFlag = false;
@ -108,13 +112,9 @@ class _MIShotelState extends State<MIShotel>
String getTabName(int index) { String getTabName(int index) {
switch (index) { switch (index) {
case 0: case 0: return "domestic";
return "domestic"; case 1: return "international";
case 1: default: return "domestic"; // return "Unknown";
return "international";
default:
// return "Unknown";
return "domestic";
} }
} }
@ -142,7 +142,7 @@ class _MIShotelState extends State<MIShotel>
loadInitialData(); loadInitialData();
}); });
} catch (e) { } catch (e) {
print("service report : $e"); print("hotel report : $e");
} }
} }
void loadInitialData() async { void loadInitialData() async {
@ -266,6 +266,9 @@ class _MIShotelState extends State<MIShotel>
internationalData = List<Map<String, dynamic>>.from( internationalData = List<Map<String, dynamic>>.from(
result['status'] == 'success' ? result['data']['international'] ?? [] : [] result['status'] == 'success' ? result['data']['international'] ?? [] : []
); );
filteredDomestic = domesticData;
filteredInternational = internationalData;
loaderFlag = false; loaderFlag = false;
}); });
} catch (e) { } catch (e) {
@ -323,6 +326,51 @@ class _MIShotelState extends State<MIShotel>
), ),
); );
} }
void handleDomesticFilter(String query) {
final lowerQuery = query.toLowerCase();
setState(() {
filteredDomestic =
domesticData.where((object) {
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['employee_name']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['hotel_name']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['check_in_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['check_out_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['hotel_city']?.toLowerCase().contains(lowerQuery));
}).toList();
currentPage1 = 0;
});
print("handleDomesticFilter > Total entries: ${filteredDomestic?.length ?? 0}");
}
void handleInternationalFilter(String query) {
final lowerQuery = query.toLowerCase();
setState(() {
filteredInternational =
internationalData.where((object) {
return (object['plan_id']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['employee_code']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['employee_name']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['so_number']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['functional_department']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['hotel_name']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['check_in_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['check_out_date']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['hotel_city']?.toLowerCase().contains(lowerQuery));
}).toList();
currentPage2 = 0;
});
print("handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}");
}
@override @override
// Widget build(BuildContext context) { // Widget build(BuildContext context) {
// // TODO: implement build // // TODO: implement build
@ -698,6 +746,44 @@ class _MIShotelState extends State<MIShotel>
overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow
), ),
), ),
Container(
width: MediaQuery.of(context).size.width * 0.2,
height: 40,
child: TextField(
controller: searchDomesticController,
onChanged: handleDomesticFilter,
decoration: InputDecoration(
hintText: "Search ...",
hintStyle: TextStyle(
fontSize: 12,
color: Color(0xFF9E9DBD),
),
prefixIcon: Icon(
Icons.search,
color: Color(0xFF9E9DBD),
size: 18,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade200,
width: 0.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade300,
width: 1,
),
),
),
style: GoogleFonts.poppins(fontSize: 12),
),
),
// SizedBox(width: 16), // SizedBox(width: 16),
// /// Buttons on the right // /// Buttons on the right
// Row( // Row(
@ -802,13 +888,29 @@ class _MIShotelState extends State<MIShotel>
builder: (context, constraints) { builder: (context, constraints) {
final double minWidth = isDesktop ? constraints.maxWidth : 1300; final double minWidth = isDesktop ? constraints.maxWidth : 1300;
List<Map<String, dynamic>> newDomesticData =filteredDomestic.isNotEmpty ? filteredDomestic : domesticData;
// Pagination logic // Pagination logic
List<Map<String, dynamic>> paginatedDomestic = domesticData List<Map<String, dynamic>>
paginatedDomestic =
newDomesticData
.skip(currentPage1 * itemsPerPage1) .skip(currentPage1 * itemsPerPage1)
.take(itemsPerPage1) .take(itemsPerPage1)
.toList(); .toList();
return Column( return (
(searchDomesticController.text.isNotEmpty && filteredDomestic.isEmpty)
? Center(
child: Text(
"No data found",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
)
: Column(
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -870,7 +972,7 @@ class _MIShotelState extends State<MIShotel>
PaginationControls( PaginationControls(
currentPage: currentPage1, currentPage: currentPage1,
itemsPerPage: itemsPerPage1, itemsPerPage: itemsPerPage1,
totalItems: domesticData.length, totalItems: newDomesticData.length,
activeColor: layoutColor, activeColor: layoutColor,
onPageChanged: (page) { onPageChanged: (page) {
setState(() { setState(() {
@ -885,7 +987,7 @@ class _MIShotelState extends State<MIShotel>
}, },
), ),
], ],
); ));
}, },
), ),
), ),
@ -1027,10 +1129,64 @@ class _MIShotelState extends State<MIShotel>
// ), // ),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8), padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8),
child: Text( child: Row(
"International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})", mainAxisAlignment: MainAxisAlignment.spaceBetween,
style: GoogleFonts.poppins(fontSize: 13, fontWeight: FontWeight.w500, color: Colors.grey[700]), crossAxisAlignment: CrossAxisAlignment.center,
), children: [
/// Title on the left
Expanded(
child: Text(
"International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})",
style: GoogleFonts.poppins(
fontSize: 13,
fontWeight: FontWeight.w500,
color: Colors.grey[700],
),
overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow
),
),
SizedBox(width: 16),
Container(
width: MediaQuery.of(context).size.width * 0.2,
height: 40,
child: TextField(
controller: searchInternationalController,
onChanged: handleInternationalFilter,
decoration: InputDecoration(
hintText: "Search ...",
hintStyle: TextStyle(
fontSize: 12,
color: Color(0xFF9E9DBD),
),
prefixIcon: Icon(
Icons.search,
color: Color(0xFF9E9DBD),
size: 18,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade200,
width: 0.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade300,
width: 1,
),
),
),
style: GoogleFonts.poppins(fontSize: 12),
),
),
])
), ),
Container( Container(
height : isDesktop ? MediaQuery.of(context).size.height * 0.51 : 200, height : isDesktop ? MediaQuery.of(context).size.height * 0.51 : 200,
@ -1038,14 +1194,24 @@ class _MIShotelState extends State<MIShotel>
child: LayoutBuilder( child: LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
final double minWidth = isDesktop ? constraints.maxWidth : 1300; final double minWidth = isDesktop ? constraints.maxWidth : 1300;
List<Map<String, dynamic>> newInternationalData =filteredInternational.isNotEmpty ? filteredInternational : internationalData;
// Pagination logic // Pagination logic
List<Map<String, dynamic>> paginatedInternational = internationalData List<Map<String, dynamic>> paginatedInternational = newInternationalData
.skip(currentPage2 * itemsPerPage2) .skip(currentPage2 * itemsPerPage2)
.take(itemsPerPage2) .take(itemsPerPage2)
.toList(); .toList();
return Column( return ((searchInternationalController.text.isNotEmpty && filteredInternational.isEmpty)
? Center(
child: Text(
"No data found",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
)
: Column(
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -1104,7 +1270,7 @@ class _MIShotelState extends State<MIShotel>
PaginationControls( PaginationControls(
currentPage: currentPage2, currentPage: currentPage2,
itemsPerPage: itemsPerPage2, itemsPerPage: itemsPerPage2,
totalItems: internationalData.length, totalItems: newInternationalData.length,
activeColor: layoutColor, activeColor: layoutColor,
onPageChanged: (page) { onPageChanged: (page) {
setState(() { setState(() {
@ -1119,7 +1285,7 @@ class _MIShotelState extends State<MIShotel>
}, },
), ),
], ],
); ));
}, },
), ),
), ),

View File

@ -53,6 +53,10 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
List<Map<String, dynamic>> internationalData = []; List<Map<String, dynamic>> internationalData = [];
// Map<String, dynamic> domesticData = {}; // Map<String, dynamic> domesticData = {};
// Map<String, dynamic> internationalData = {}; // Map<String, dynamic> internationalData = {};
List<Map<String, dynamic>> filteredDomestic = [];
List<Map<String, dynamic>> filteredInternational = [];
TextEditingController searchDomesticController = TextEditingController();
TextEditingController searchInternationalController = TextEditingController();
bool loaderFlag = false; bool loaderFlag = false;
@ -107,13 +111,9 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
String getTabName(int index) { String getTabName(int index) {
switch (index) { switch (index) {
case 0: case 0: return "domestic";
return "domestic"; case 1: return "international";
case 1: default: return "domestic"; // return "Unknown";
return "international";
default:
// return "Unknown";
return "domestic";
} }
} }
@ -277,6 +277,9 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
? result['data']['international'] ?? [] ? result['data']['international'] ?? []
: [], : [],
); );
filteredDomestic = domesticData;
filteredInternational = internationalData;
loaderFlag = false; loaderFlag = false;
}); });
} catch (e) { } catch (e) {
@ -336,6 +339,35 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
); );
} }
void handleDomesticFilter(String query) {
final lowerQuery = query.toLowerCase();
setState(() {
filteredDomestic =
domesticData.where((object) {
return (object['Service']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['flight_service_count']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery));
}).toList();
currentPage1 = 0;
});
print("handleDomesticFilter > Total entries: ${filteredDomestic?.length ?? 0}");
}
void handleInternationalFilter(String query) {
final lowerQuery = query.toLowerCase();
setState(() {
filteredInternational =
internationalData.where((object) {
return (object['Service']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['flight_service_count']?.toLowerCase().contains(lowerQuery) ?? false) ||
(object['plan_trip_type']?.toLowerCase().contains(lowerQuery));
}).toList();
currentPage2 = 0;
});
print("handleInternationalFilter > Total entries: ${filteredInternational?.length ?? 0}");
}
@override @override
// Widget build(BuildContext context) { // Widget build(BuildContext context) {
// // TODO: implement build // // TODO: implement build
@ -708,6 +740,44 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
.ellipsis, // Ensures title doesn't overflow .ellipsis, // Ensures title doesn't overflow
), ),
), ),
Container(
width: MediaQuery.of(context).size.width * 0.2,
height: 40,
child: TextField(
controller: searchDomesticController,
onChanged: handleDomesticFilter,
decoration: InputDecoration(
hintText: "Search ...",
hintStyle: TextStyle(
fontSize: 12,
color: Color(0xFF9E9DBD),
),
prefixIcon: Icon(
Icons.search,
color: Color(0xFF9E9DBD),
size: 18,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade200,
width: 0.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade300,
width: 1,
),
),
),
style: GoogleFonts.poppins(fontSize: 12),
),
),
// SizedBox(width: 16), // SizedBox(width: 16),
// /// Buttons on the right // /// Buttons on the right
// Row( // Row(
@ -813,15 +883,29 @@ 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;
// Pagination logic // Pagination logic
List<Map<String, dynamic>> List<Map<String, dynamic>>
paginatedDomestic = paginatedDomestic =
domesticData newDomesticData
.skip(currentPage1 * itemsPerPage1) .skip(currentPage1 * itemsPerPage1)
.take(itemsPerPage1) .take(itemsPerPage1)
.toList(); .toList();
return Column( return (
(searchDomesticController.text.isNotEmpty && filteredDomestic.isEmpty)
? Center(
child: Text(
"No data found",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
)
: Column(
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -933,7 +1017,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
PaginationControls( PaginationControls(
currentPage: currentPage1, currentPage: currentPage1,
itemsPerPage: itemsPerPage1, itemsPerPage: itemsPerPage1,
totalItems: domesticData.length, totalItems: newDomesticData.length,
activeColor: layoutColor, activeColor: layoutColor,
onPageChanged: (page) { onPageChanged: (page) {
setState(() { setState(() {
@ -948,7 +1032,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
}, },
), ),
], ],
); ));
}, },
), ),
), ),
@ -1095,14 +1179,64 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
horizontal: 16.0, horizontal: 16.0,
vertical: 8, vertical: 8,
), ),
child: Text( child: Row(
"International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})", mainAxisAlignment: MainAxisAlignment.spaceBetween,
style: GoogleFonts.poppins( crossAxisAlignment: CrossAxisAlignment.center,
fontSize: 13, children: [
fontWeight: FontWeight.w500, /// Title on the left
color: Colors.grey[700], Expanded(
), child: Text(
), "International Report (From: ${textControllers["from_date"]?.text} To: ${textControllers["to_date"]?.text})",
style: GoogleFonts.poppins(
fontSize: 13,
fontWeight: FontWeight.w500,
color: Colors.grey[700],
),
overflow: TextOverflow.ellipsis, // Ensures title doesn't overflow
),
),
SizedBox(width: 16),
Container(
width: MediaQuery.of(context).size.width * 0.2,
height: 40,
child: TextField(
controller: searchInternationalController,
onChanged: handleInternationalFilter,
decoration: InputDecoration(
hintText: "Search ...",
hintStyle: TextStyle(
fontSize: 12,
color: Color(0xFF9E9DBD),
),
prefixIcon: Icon(
Icons.search,
color: Color(0xFF9E9DBD),
size: 18,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade200,
width: 0.5,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade300,
width: 1,
),
),
),
style: GoogleFonts.poppins(fontSize: 12),
),
),
])
), ),
Container( Container(
height: height:
@ -1115,16 +1249,26 @@ 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;
// Pagination logic // Pagination logic
List<Map<String, dynamic>> List<Map<String, dynamic>>
paginatedInternational = paginatedInternational =
internationalData newInternationalData
.skip(currentPage2 * itemsPerPage2) .skip(currentPage2 * itemsPerPage2)
.take(itemsPerPage2) .take(itemsPerPage2)
.toList(); .toList();
return Column( return ((searchInternationalController.text.isNotEmpty && filteredInternational.isEmpty)
? Center(
child: Text(
"No data found",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
)
: Column(
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -1236,7 +1380,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
PaginationControls( PaginationControls(
currentPage: currentPage2, currentPage: currentPage2,
itemsPerPage: itemsPerPage2, itemsPerPage: itemsPerPage2,
totalItems: internationalData.length, totalItems: newInternationalData.length,
activeColor: layoutColor, activeColor: layoutColor,
onPageChanged: (page) { onPageChanged: (page) {
setState(() { setState(() {
@ -1251,7 +1395,7 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
}, },
), ),
], ],
); ));
}, },
), ),
), ),