import 'package:flutter/material.dart'; import 'package:nhancepolicy/customAppBar/customAppBar.dart'; import 'package:nhancepolicy/presentation/preFileUpload.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:jwt_decode/jwt_decode.dart'; import 'dart:convert'; import 'dart:async'; import 'package:http/http.dart' as http; import 'package:nhancepolicy/customAppBar/toastHelper.dart'; // import 'dart:html' as html; import 'package:universal_html/html.dart' as html; import 'dart:typed_data'; import 'dart:io'; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:intl/intl.dart'; import 'package:excel/excel.dart'; import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart' as path; import 'config/environment.dart'; import 'package:nhancepolicy/logger.dart'; class MyHrHome extends StatefulWidget { const MyHrHome({Key? key}) : super(key: key); @override State createState() => _MyHrHomeState(); } class _MyHrHomeState extends State with TickerProviderStateMixin { Uint8List? fileBytes; late String _token; List> getEmpDependenceByClintIdGMC = []; List> getEmpDependenceByClintIdGPA = []; List> getEmpDependenceByClintIdAddOnsSi = []; List> getEmpDependenceByClintIdAddOnsDependent = []; dynamic getPolicyNameDetails0; dynamic getPolicyNameDetails1; dynamic getPolicyNameDetails2; dynamic getPolicyNo0; dynamic getPolicyNo1; dynamic getPolicyNo2; bool _isLoading = false; dynamic clintID; late TabController _tabController; List dataPolicy = []; List reversedDataPolicy = []; List> originalDataGpa = []; // Original data source List> filteredDataGpa = []; // Filtered data source List> originalDataGmc = []; // Original data source List> filteredDataGmc = []; // Filtered data source List> originalDataAddOnsSi = []; // Original data source List> filteredDataAddOnsSi = []; List> originalDataAddOnsDependent = []; // Original data source List> filteredDataAddOnsDependent = []; @override void initState() { super.initState(); _tabController = TabController(length: 4, vsync: this); _loadToken(); } @override void dispose() { _tabController.dispose(); super.dispose(); } Future _loadToken() async { final SharedPreferences prefs = await SharedPreferences.getInstance(); final token = prefs.getString('hrtoken'); if (token != null && token.isNotEmpty) { setState(() { _token = token; }); Map? decodedToken = Jwt.parseJwt(token); clintID = decodedToken['client_id']; getPolicyName(clintID); } else { // Token is empty or null, handle accordingly (e.g., navigate to login screen) // For now, let's navigate to the login screen ToastHelper.showErrorToast(context, 'Session Out'); Navigator.pushReplacementNamed(context, 'hrLogin'); } } Future getPolicyName(String clintID) async { setState(() { _isLoading = true; }); var url = Uri.parse(Environment.apiUrl + 'getClientPolicy?client_id=' + clintID); try { var response = await http.get( url, headers: { 'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y', 'Authorization': 'Bearer $_token', }, ); if (response.statusCode == 200) { Map data = json.decode(response.body); if (data['status'] == 'success') { logDebug(data); setState(() { dataPolicy = List>.from(data['data']); logDebug(dataPolicy); // reversedDataPolicy = dataPolicy.reversed.toList(); // getPolicyNameDetails0 = dataPolicy[0]['policy_name']; // logDebug(getPolicyNameDetails0); // getPolicyNameDetails1 = dataPolicy[1]['policy_name']; // logDebug(getPolicyNameDetails1); // getPolicyNameDetails2 = dataPolicy[2]['policy_name']; // logDebug(getPolicyNameDetails2); // getPolicyNo0 = dataPolicy[0]['client_policy_id']; // logDebug(getPolicyNameDetails1); // getPolicyNo1 = dataPolicy[1]['client_policy_id']; // logDebug(getPolicyNameDetails1); // getPolicyNo2 = dataPolicy[2]['client_policy_id']; // logDebug(getPolicyNameDetails2); }); // Code to execute periodically every 2 seconds dataPolicy.forEach((policy) { if (policy['type'] == 'GPA') { String clientPolicyId = policy['client_policy_id']; String clientId = policy['client_id']; getEmployeeAndDependenceGPA(clientId, clientPolicyId); } else if (policy['type'] == 'GMC') { String clientPolicyId = policy['client_policy_id']; String clientId = policy['client_id']; getEmployeeAndDependenceGMC(clientId, clientPolicyId); } else if (policy['type'] == 'SI TopUp') { String clientPolicyId = policy['client_policy_id']; String clientId = policy['client_id']; getEmployeeAndDependenceAddOnsSi(clientId, clientPolicyId); } else if (policy['type'] == 'Dependent AddOn') { String clientPolicyId = policy['client_policy_id']; String clientId = policy['client_id']; getEmployeeAndDependenceAddOnsDependent(clientId, clientPolicyId); } // Extract client_policy_id from the policy object }); // getEmployeeAndDependenceGPA(clintID, getPolicyNo2); // getEmployeeAndDependenceGMC(clintID, getPolicyNo1); // getEmployeeAndDependenceAddOns(clintID, getPolicyNo0); } else { ToastHelper.showWarningToast( context, 'API request failed with status: ${data['status']}'); logDebug('API request failed with status: ${data['status']}'); } } else { ToastHelper.showWarningToast( context, 'Request failed with status: ${response.statusCode}'); logDebug('Request failed with status: ${response.statusCode}'); } } catch (e) { logDebug('Exception occurred: $e'); } finally { setState(() { _isLoading = false; }); } } Future getEmployeeAndDependenceGPA(clintID, getPolicyNo) async { setState(() { _isLoading = true; }); var url = Uri.parse(Environment.apiUrl + 'getEmployeeAndDependenceByClientId?client_id=$clintID&client_policy_id=$getPolicyNo'); try { var response = await http.get( url, headers: { 'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y', 'Authorization': 'Bearer $_token', }, ); if (response.statusCode == 200) { Map data = json.decode(response.body); if (data['status'] == 'success') { setState(() { getEmpDependenceByClintIdGPA = List>.from(data['data']); originalDataGpa = getEmpDependenceByClintIdGPA; filteredDataGpa = List.from(originalDataGpa); logDebug('filteredDataGpa'); logDebug(filteredDataGpa); }); } else { ToastHelper.showWarningToast( context, 'API request failed with status: ${data['status']}'); logDebug('API request failed with status: ${data['status']}'); } } else { ToastHelper.showWarningToast( context, 'Request failed with status: ${response.statusCode}'); logDebug('Request failed with status: ${response.statusCode}'); } } catch (e) { logDebug('Exception occurred: $e'); } finally { setState(() { _isLoading = false; }); } } Future getEmployeeAndDependenceGMC(clintID, getPolicyNo) async { setState(() { _isLoading = true; }); var url = Uri.parse(Environment.apiUrl + 'getEmployeeAndDependenceByClientId?client_id=$clintID&client_policy_id=$getPolicyNo'); try { var response = await http.get( url, headers: { 'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y', 'Authorization': 'Bearer $_token', }, ); if (response.statusCode == 200) { Map data = json.decode(response.body); if (data['status'] == 'success') { setState(() { getEmpDependenceByClintIdGMC = List>.from(data['data']); originalDataGmc = getEmpDependenceByClintIdGMC; filteredDataGmc = List.from(originalDataGmc); }); } else { ToastHelper.showErrorToast( context, 'API request failed with status: ${data['status']}'); logDebug('API request failed with status: ${data['status']}'); } } else { ToastHelper.showErrorToast( context, 'Request failed with status: ${response.statusCode}'); logDebug('Request failed with status: ${response.statusCode}'); } } catch (e) { logDebug('Exception occurred: $e'); } finally { setState(() { _isLoading = false; }); } } Future getEmployeeAndDependenceAddOnsSi(clintID, getPolicyNo) async { setState(() { _isLoading = true; }); var url = Uri.parse(Environment.apiUrl + 'getEmployeeAndDependenceByClientId?client_id=$clintID&client_policy_id=$getPolicyNo'); try { var response = await http.get( url, headers: { 'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y', 'Authorization': 'Bearer $_token', }, ); if (response.statusCode == 200) { Map data = json.decode(response.body); if (data['status'] == 'success') { setState(() { getEmpDependenceByClintIdAddOnsSi = List>.from(data['data']); originalDataAddOnsSi = getEmpDependenceByClintIdAddOnsSi; filteredDataAddOnsSi = List.from(originalDataAddOnsSi); }); } else { ToastHelper.showErrorToast( context, 'API request failed with status: ${data['status']}'); logDebug('API request failed with status: ${data['status']}'); } } else { ToastHelper.showErrorToast( context, 'Request failed with status: ${response.statusCode}'); logDebug('Request failed with status: ${response.statusCode}'); } } catch (e) { logDebug('Exception occurred: $e'); } finally { setState(() { _isLoading = false; }); } } Future getEmployeeAndDependenceAddOnsDependent( clintID, getPolicyNo) async { setState(() { _isLoading = true; }); var url = Uri.parse(Environment.apiUrl + 'getEmployeeAndDependenceByClientId?client_id=$clintID&client_policy_id=$getPolicyNo'); try { var response = await http.get( url, headers: { 'Authorization': 'Bearer $_token', 'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y', }, ); if (response.statusCode == 200) { Map data = json.decode(response.body); if (data['status'] == 'success') { setState(() { getEmpDependenceByClintIdAddOnsDependent = List>.from(data['data']); originalDataAddOnsDependent = getEmpDependenceByClintIdAddOnsDependent; filteredDataAddOnsDependent = List.from(originalDataAddOnsDependent); }); } else { ToastHelper.showErrorToast( context, 'API request failed with status: ${data['status']}'); logDebug('API request failed with status: ${data['status']}'); } } else { ToastHelper.showErrorToast( context, 'Request failed with status: ${response.statusCode}'); logDebug('Request failed with status: ${response.statusCode}'); } } catch (e) { logDebug('Exception occurred: $e'); } finally { setState(() { _isLoading = false; }); } } void _uploadFile(importPolicyName) async { var argumentDetails; if (importPolicyName == 'GPA') { // argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails2; argumentDetails = 'GPA'; } else if (importPolicyName == 'GMC') { // argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails1; argumentDetails = 'GMC'; } // else if (importPolicyName == 'SI-TopUp') { // // argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails0; // argumentDetails = 'SI-TopUp'; // } else if (importPolicyName == 'Dependent-AddOn') { // // argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails0; // argumentDetails = 'Dependent-AddOn'; // } Navigator.pushNamed(context, 'preFileUpload', arguments: argumentDetails); return; if (kIsWeb) { final input = html.FileUploadInputElement(); input.accept = '.xlsx'; input.click(); input.onChange.listen((event) async { final file = input.files!.first; final reader = html.FileReader(); reader.readAsArrayBuffer(file); reader.onLoadEnd.listen((event) async { final Uint8List? fileBytes = reader.result as Uint8List?; if (fileBytes != null) { // Call function to process Excel data } }); }); } } void searchGpa(String query) { setState(() { if (query.isEmpty) { // If search query is empty, show all data filteredDataGpa = List.from(originalDataGpa); } else { // Filter the data based on the search query filteredDataGpa = originalDataGpa.where((item) { // Implement your filter logic here, for example: return item['emp_code'].toLowerCase().contains(query.toLowerCase()); }).toList(); } }); } void searchGmc(String query) { setState(() { if (query.isEmpty) { // If search query is empty, show all data filteredDataGmc = List.from(originalDataGmc); } else { // Filter the data based on the search query filteredDataGmc = originalDataGmc.where((item) { // Implement your filter logic here, for example: return item['emp_code'].toLowerCase().contains(query.toLowerCase()); }).toList(); } }); } void searchAddOnsSi(String query) { setState(() { if (query.isEmpty) { // If search query is empty, show all data filteredDataAddOnsSi = List.from(originalDataAddOnsSi); } else { // Filter the data based on the search query filteredDataAddOnsSi = originalDataAddOnsSi.where((item) { // Implement your filter logic here, for example: return item['emp_code'].toLowerCase().contains(query.toLowerCase()); }).toList(); } }); } void searchAddOnsDependent(String query) { setState(() { if (query.isEmpty) { // If search query is empty, show all data filteredDataAddOnsDependent = List.from(originalDataAddOnsDependent); } else { // Filter the data based on the search query filteredDataAddOnsDependent = originalDataAddOnsDependent.where((item) { // Implement your filter logic here, for example: return item['emp_code'].toLowerCase().contains(query.toLowerCase()); }).toList(); } }); } Future downloadExcel() async { // API endpoint to download the Excel file // Send GET request to the API var url = Uri.parse(Environment.apiUrl + 'exportDataByClientPolicyId?client_id=$clintID&client_policy_id=62'); var response = await http.get( url, headers: { 'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y', 'Authorization': 'Bearer $_token', }, ); // Check if the request was successful (status code 200) // Check if the request was successful (status code 200) // Check if the request was successful (status code 200) if (response.statusCode == 200) { // Create a blob from the response body final blob = html.Blob([response.bodyBytes]); // Generate a download URL for the blob final url = html.Url.createObjectUrlFromBlob(blob); // Create a link element to trigger the download final anchor = html.AnchorElement(href: url) ..setAttribute('download', 'excel_file.xlsx') ..click(); // Revoke the download URL to free up resources html.Url.revokeObjectUrl(url); } else { // Handle error logDebug('Failed to download Excel file: ${response.statusCode}'); } } @override Widget build(BuildContext context) { if (dataPolicy == []) { return Scaffold( appBar: CustomAppBar(), body: SingleChildScrollView( child: Container( color: Color(0xFFEFF3F6), child: Column( children: [ Center( child: Text('No Data Available'), ) ], ), ), )); } else { return Scaffold( appBar: CustomAppBar(), body: Container( padding: const EdgeInsets.all(20), color: Color(0xFFEFF3F6), child: Card( elevation: 0, child: Column( children: [ TabBar( labelColor: Colors.white, // Selected tab color unselectedLabelColor: Colors.grey, // Unselected tab color indicator: BoxDecoration( color: Color(0xFFE26728), // Background color of selected tab ), indicatorSize: TabBarIndicatorSize.label, controller: _tabController, tabs: dataPolicy != null && dataPolicy.isNotEmpty ? dataPolicy.map((policy) { return Tab( child: Container( width: double.infinity, alignment: Alignment.center, padding: EdgeInsets.symmetric(vertical: 0), child: Text( '${policy['type']} : ${policy['policy_name']}'), ), ); }).toList() : [ Tab(text: 'Loading...') ], // Display a loading tab if dataPolicy is null or empty // tabs: [ // Tab( // child: Container( // width: double.maxFinite, // alignment: Alignment.center, // padding: EdgeInsets.symmetric(vertical: 0), // child: Text('GPA-' + (getPolicyNameDetails0 ?? '')), // ), // ), // Tab( // child: Container( // width: double.infinity, // alignment: Alignment.center, // padding: EdgeInsets.symmetric(vertical: 0), // child: Text('GMC-' + (getPolicyNameDetails1 ?? '')), // ), // ), // ], ), Expanded( child: TabBarView( controller: _tabController, children: [ Center( child: Padding( padding: const EdgeInsets.all(20), child: _isLoading ? Center(child: CircularProgressIndicator()) : filteredDataGpa.isNotEmpty ? SingleChildScrollView( child: Column( children: [ Row( children: [ Expanded( flex: 8, child: Container( alignment: Alignment.centerLeft, child: Container( width: 350, // Set your desired width here height: 40, // Set your desired height here decoration: BoxDecoration( boxShadow: [ BoxShadow( color: Color.fromRGBO( 255, 255, 255, 0.5), // Shadow color with opacity offset: Offset(5, 5), // Shadow position (horizontal, vertical) blurRadius: 10, // Blur radius spreadRadius: 0, // Spread radius ), ], borderRadius: BorderRadius.circular( 5), ), child: TextField( textAlignVertical: TextAlignVertical .center, // Center the text vertically decoration: InputDecoration( hintText: 'Search', suffixIcon: Icon(Icons.search), contentPadding: EdgeInsets.all( 10), // Adjust the horizontal padding border: OutlineInputBorder( borderSide: BorderSide( color: Color( 0xFFf5f5f7)), // Set border color to gray ), ), onChanged: searchGpa, // Call the search method on text change ), )), ), Expanded( flex: 2, child: Container( alignment: Alignment.centerRight, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: ElevatedButton( onPressed: () => {downloadExcel()}, child: Text( 'Export', style: TextStyle( color: Colors.white), ), style: ElevatedButton .styleFrom( backgroundColor: Color(0xFFE26728), shape: RoundedRectangleBorder( borderRadius: BorderRadius .circular( 5), ), ), ), ), ], ), ), ), SizedBox(width: 5), Expanded( flex: 2, child: Container( alignment: Alignment.centerRight, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: ElevatedButton( onPressed: () => _uploadFile('GPA'), child: Text( 'Import Data', style: TextStyle( color: Colors.white), ), style: ElevatedButton .styleFrom( backgroundColor: Color(0xFFE26728), shape: RoundedRectangleBorder( borderRadius: BorderRadius .circular( 5), ), ), ), ), ], ), ), ), ], ), SizedBox(height: 20), Row( children: [ Expanded( child: SingleChildScrollView( child: _buildDataTableGPA(context), ), ) ], ), ], )) : Container( height: MediaQuery.of(context).size.height, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Center( child: ElevatedButton( onPressed: () => _uploadFile('GPA'), child: Text( 'Import Data', style: TextStyle( color: Colors.white), ), style: ElevatedButton.styleFrom( backgroundColor: Color(0xFFE26728), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), ), ), ) ], ), ), ), ), Center( child: Padding( padding: const EdgeInsets.all(20), child: _isLoading ? Center(child: CircularProgressIndicator()) : filteredDataGmc.isNotEmpty ? SingleChildScrollView( child: Column( children: [ Row( children: [ Expanded( flex: 10, child: Container( alignment: Alignment.centerLeft, child: Container( width: 350, // Set your desired width here height: 40, // Set your desired height here decoration: BoxDecoration( boxShadow: [ BoxShadow( color: Color.fromRGBO( 255, 255, 255, 0.5), // Shadow color with opacity offset: Offset(5, 5), // Shadow position (horizontal, vertical) blurRadius: 10, // Blur radius spreadRadius: 0, // Spread radius ), ], borderRadius: BorderRadius .circular(5), ), child: TextField( textAlignVertical: TextAlignVertical .center, // Center the text vertically decoration: InputDecoration( hintText: 'Search', suffixIcon: Icon( Icons.search), contentPadding: EdgeInsets.all( 10), // Adjust the horizontal padding border: OutlineInputBorder( borderSide: BorderSide( color: Color( 0xFFf5f5f7)), // Set border color to gray ), ), onChanged: searchGmc, // Call the search method on text change ), )), ), Expanded( flex: 2, child: Container( alignment: Alignment.centerRight, child: Row( mainAxisAlignment: MainAxisAlignment .spaceEvenly, children: [ Expanded( child: ElevatedButton( onPressed: () => _uploadFile( 'GMC'), child: Text( 'Import', style: TextStyle( color: Colors .white), ), style: ElevatedButton .styleFrom( backgroundColor: Color( 0xFFE26728), shape: RoundedRectangleBorder( borderRadius: BorderRadius .circular( 5), ), ), ), ) ], ), ), ), ], ), SizedBox(height: 20), Row( children: [ Expanded( child: SingleChildScrollView( child: _buildDataTableGMC( context), ), ) ], ), ], ), ) : Container( height: MediaQuery.of(context).size.height, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Center( child: ElevatedButton( onPressed: () => _uploadFile('GMC'), child: Text( 'Import Data', style: TextStyle( color: Colors.white), ), style: ElevatedButton.styleFrom( backgroundColor: Color(0xFFE26728), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), ), ), ) ], ), ), ), ), Center( child: Padding( padding: const EdgeInsets.all(20), child: _isLoading ? Center(child: CircularProgressIndicator()) : filteredDataAddOnsSi.isNotEmpty ? SingleChildScrollView( child: Column( children: [ Row( children: [ Expanded( flex: 10, child: Container( alignment: Alignment.centerLeft, child: Container( width: 350, // Set your desired width here height: 40, // Set your desired height here decoration: BoxDecoration( boxShadow: [ BoxShadow( color: Color.fromRGBO( 255, 255, 255, 0.5), // Shadow color with opacity offset: Offset(5, 5), // Shadow position (horizontal, vertical) blurRadius: 10, // Blur radius spreadRadius: 0, // Spread radius ), ], borderRadius: BorderRadius .circular(5), ), child: TextField( textAlignVertical: TextAlignVertical .center, // Center the text vertically decoration: InputDecoration( hintText: 'Search', suffixIcon: Icon( Icons.search), contentPadding: EdgeInsets.all( 10), // Adjust the horizontal padding border: OutlineInputBorder( borderSide: BorderSide( color: Color( 0xFFf5f5f7)), // Set border color to gray ), ), onChanged: searchAddOnsSi, // Call the search method on text change ), )), ), // Expanded( // flex: 2, // child: Container( // alignment: Alignment.centerRight, // child: Row( // mainAxisAlignment: // MainAxisAlignment.spaceEvenly, // children: [ // Expanded( // child: ElevatedButton( // onPressed: () => // _uploadFile('ADDONS'), // child: Text( // 'Import', // style: TextStyle( // color: Colors.white), // ), // style: ElevatedButton // .styleFrom( // backgroundColor: // Color(0xFFE26728), // shape: // RoundedRectangleBorder( // borderRadius: // BorderRadius // .circular(5), // ), // ), // ), // ) // ], // ), // ), // ), ], ), SizedBox(height: 20), Row( children: [ Expanded( child: SingleChildScrollView( child: _buildDataTableAddOnsSi( context), ), ) ], ), ], ), ) : Container( height: MediaQuery.of(context).size.height, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Center( child: Text( 'No Data Available', style: TextStyle( color: Colors.black), ), ) ], ), ), ), ), Center( child: Padding( padding: const EdgeInsets.all(20), child: _isLoading ? Center(child: CircularProgressIndicator()) : filteredDataAddOnsDependent.isNotEmpty ? SingleChildScrollView( child: Column( children: [ Row( children: [ Expanded( flex: 10, child: Container( alignment: Alignment.centerLeft, child: Container( width: 350, // Set your desired width here height: 40, // Set your desired height here decoration: BoxDecoration( boxShadow: [ BoxShadow( color: Color.fromRGBO( 255, 255, 255, 0.5), // Shadow color with opacity offset: Offset(5, 5), // Shadow position (horizontal, vertical) blurRadius: 10, // Blur radius spreadRadius: 0, // Spread radius ), ], borderRadius: BorderRadius .circular(5), ), child: TextField( textAlignVertical: TextAlignVertical .center, // Center the text vertically decoration: InputDecoration( hintText: 'Search', suffixIcon: Icon( Icons.search), contentPadding: EdgeInsets.all( 10), // Adjust the horizontal padding border: OutlineInputBorder( borderSide: BorderSide( color: Color( 0xFFf5f5f7)), // Set border color to gray ), ), onChanged: searchAddOnsDependent, // Call the search method on text change ), )), ), // Expanded( // flex: 2, // child: Container( // alignment: Alignment.centerRight, // child: Row( // mainAxisAlignment: // MainAxisAlignment.spaceEvenly, // children: [ // Expanded( // child: ElevatedButton( // onPressed: () => // _uploadFile('ADDONS'), // child: Text( // 'Import', // style: TextStyle( // color: Colors.white), // ), // style: ElevatedButton // .styleFrom( // backgroundColor: // Color(0xFFE26728), // shape: // RoundedRectangleBorder( // borderRadius: // BorderRadius // .circular(5), // ), // ), // ), // ) // ], // ), // ), // ), ], ), SizedBox(height: 20), Row( children: [ Expanded( child: SingleChildScrollView( child: _buildDataTableAddOnsDependent( context), ), ) ], ), ], ), ) : Container( height: MediaQuery.of(context).size.height, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Center( child: Text( 'No Data Available', style: TextStyle( color: Colors.black), ), ) ], ), ), ), ), ], ), ), ], ), ), ), ); } } Widget _buildDataTableGPA(context) { if (filteredDataGpa.isEmpty) { SizedBox(height: 25); return Text('No available data'); } else { return Card( elevation: 0, // Set elevation to 0 for no shadow child: PaginatedDataTable( rowsPerPage: 25, // Adjust rows per page as needed columns: [ DataColumn(label: Text('Employee ID')), DataColumn(label: Text('Name')), DataColumn(label: Text('Relationship')), DataColumn(label: Text('Date of Birth')), DataColumn(label: Text('Gender')), DataColumn(label: Text('Mobile No')), ], source: _DependenceDataSource0(filteredDataGpa, context), ), ); } } Widget _buildDataTableGMC(context) { if (filteredDataGmc.isEmpty) { SizedBox(height: 25); return Text('No available data'); } else { return Card( elevation: 0, // Set elevation to 0 for no shadow child: PaginatedDataTable( rowsPerPage: 25, // Adjust rows per page as needed columns: [ DataColumn(label: Text('Employee ID')), DataColumn(label: Text('Name')), DataColumn(label: Text('Relationship')), DataColumn(label: Text('Date of Birth')), DataColumn(label: Text('Gender')), DataColumn(label: Text('Mobile No')), ], source: _DependenceDataSource1(filteredDataGmc, context), ), ); } } Widget _buildDataTableAddOnsSi(context) { if (filteredDataAddOnsSi.isEmpty) { SizedBox(height: 25); return Text('No available data'); } else { return Card( elevation: 0, // Set elevation to 0 for no shadow child: PaginatedDataTable( rowsPerPage: 25, // Adjust rows per page as needed columns: [ DataColumn(label: Text('Employee ID')), DataColumn(label: Text('Name')), DataColumn(label: Text('Relationship')), DataColumn(label: Text('Date of Birth')), DataColumn(label: Text('Gender')), DataColumn(label: Text('Mobile No')), ], source: _DependenceDataSource2(filteredDataAddOnsSi, context), ), ); } } Widget _buildDataTableAddOnsDependent(context) { if (filteredDataAddOnsDependent.isEmpty) { SizedBox(height: 25); return Text('No available data'); } else { return Card( elevation: 0, // Set elevation to 0 for no shadow child: PaginatedDataTable( rowsPerPage: 25, // Adjust rows per page as needed columns: [ DataColumn(label: Text('Employee ID')), DataColumn(label: Text('Name')), DataColumn(label: Text('Relationship')), DataColumn(label: Text('Date of Birth')), DataColumn(label: Text('Gender')), DataColumn(label: Text('Mobile No')), ], source: _DependenceDataSource2(filteredDataAddOnsDependent, context), ), ); } } } class _DependenceDataSource0 extends DataTableSource { final List> _data; final BuildContext context; _DependenceDataSource0(this._data, this.context); @override DataRow getRow(int index) { final row = _data[index]; Color rowColor = Colors.transparent; TextStyle textStyle = TextStyle(color: Colors.black); bool isClickable = false; if (row['relationship'] == 'Self') { rowColor = Color(0xFFFFF1DD); // Setting background color for 'Self' rows textStyle = TextStyle(color: Colors.black); isClickable = true; // Making 'Self' rows clickable } // Format date of birth to "July 10, 1996" String dob = row['dob'] != null ? formatDateString(row['dob']) : 'N/A'; return DataRow( color: MaterialStateColor.resolveWith( (states) => rowColor), // Setting row background color cells: [ DataCell( Text(row['emp_code'].toString(), style: textStyle), onTap: isClickable ? () => _navigateToAnotherPage(row) : null, // Navigation only for 'Self' rows ), DataCell(Text(row['name'].toString(), style: textStyle)), DataCell(Text(row['relationship'].toString(), style: textStyle)), DataCell(Text(dob, style: textStyle)), DataCell(Text(row['gender'] ?? 'N/A', style: textStyle)), DataCell(Text(row['mobile'] ?? 'N/A', style: textStyle)), ], ); } @override bool get isRowCountApproximate => false; @override int get rowCount => _data.length; @override int get selectedRowCount => 0; void _navigateToAnotherPage(row) { logDebug(row['mobile']); // Navigation logic here Navigator.pushNamed(context, 'empDetails', arguments: {'mobile': row['mobile']}); } String formatDateString(String dateString) { // Parse the date string to DateTime object DateTime dateTime = DateTime.parse(dateString); // Format the DateTime object to "dd-mm-yyyy" String formattedDate = DateFormat('dd-MM-yyyy').format(dateTime); return formattedDate; } } class _DependenceDataSource1 extends DataTableSource { final List> _data; final BuildContext context; _DependenceDataSource1(this._data, this.context); @override DataRow getRow(int index) { final row = _data[index]; Color rowColor = Colors.transparent; TextStyle textStyle = TextStyle(color: Colors.black); bool isClickable = false; if (row['relationship'] == 'Self') { rowColor = Color(0xFFFFF1DD); // Setting background color for 'Self' rows textStyle = TextStyle(color: Colors.black); isClickable = true; // Making 'Self' rows clickable } // Format date of birth to "July 10, 1996" String dob = row['dob'] != null ? formatDateString(row['dob']) : 'N/A'; return DataRow( color: MaterialStateColor.resolveWith((states) => rowColor), cells: [ DataCell( Text(row['emp_code'].toString(), style: textStyle), onTap: isClickable ? () => _navigateToAnotherPage(row) : null, // Navigation only for 'Self' rows ), DataCell(Text(row['name'].toString(), style: textStyle)), DataCell(Text(row['relationship'].toString(), style: textStyle)), DataCell(Text(dob, style: textStyle)), DataCell(Text(row['gender'] ?? 'N/A', style: textStyle)), DataCell(Text(row['mobile'] ?? 'N/A', style: textStyle)), ]); } @override bool get isRowCountApproximate => false; @override int get rowCount => _data.length; @override int get selectedRowCount => 0; void _navigateToAnotherPage(row) { logDebug(row); Navigator.pushNamed(context, 'empDetails', arguments: {'mobile': row['mobile']}); } String formatDateString(String dateString) { // Parse the date string to DateTime object DateTime dateTime = DateTime.parse(dateString); // Format the DateTime object to "dd-mm-yyyy" String formattedDate = DateFormat('dd-MM-yyyy').format(dateTime); return formattedDate; } } class _DependenceDataSource2 extends DataTableSource { final List> _data; final BuildContext context; _DependenceDataSource2(this._data, this.context); @override DataRow getRow(int index) { final row = _data[index]; Color rowColor = Colors.transparent; TextStyle textStyle = TextStyle(color: Colors.black); bool isClickable = false; if (row['relationship'] == 'Self') { rowColor = Color(0xFFFFF1DD); // Setting background color for 'Self' rows textStyle = TextStyle(color: Colors.black); isClickable = true; // Making 'Self' rows clickable } // Format date of birth to "July 10, 1996" String dob = row['dob'] != null ? formatDateString(row['dob']) : 'N/A'; return DataRow( color: MaterialStateColor.resolveWith((states) => rowColor), cells: [ DataCell( Text(row['emp_code'].toString(), style: textStyle), onTap: isClickable ? () => _navigateToAnotherPage(row) : null, // Navigation only for 'Self' rows ), DataCell(Text(row['name'].toString(), style: textStyle)), DataCell(Text(row['relationship'].toString(), style: textStyle)), DataCell(Text(dob, style: textStyle)), DataCell(Text(row['gender'] ?? 'N/A', style: textStyle)), DataCell(Text(row['mobile'] ?? 'N/A', style: textStyle)), ]); } @override bool get isRowCountApproximate => false; @override int get rowCount => _data.length; @override int get selectedRowCount => 0; void _navigateToAnotherPage(row) { logDebug(row); Navigator.pushNamed(context, 'empDetails', arguments: {'mobile': row['mobile']}); } String formatDateString(String dateString) { // Parse the date string to DateTime object DateTime dateTime = DateTime.parse(dateString); // Format the DateTime object to "dd-mm-yyyy" String formattedDate = DateFormat('dd-MM-yyyy').format(dateTime); return formattedDate; } } class _DependenceDataSource3 extends DataTableSource { final List> _data; final BuildContext context; _DependenceDataSource3(this._data, this.context); @override DataRow getRow(int index) { final row = _data[index]; Color rowColor = Colors.transparent; TextStyle textStyle = TextStyle(color: Colors.black); bool isClickable = false; if (row['relationship'] == 'Self') { rowColor = Color(0xFFFFF1DD); // Setting background color for 'Self' rows textStyle = TextStyle(color: Colors.black); isClickable = true; // Making 'Self' rows clickable } // Format date of birth to "July 10, 1996" String dob = row['dob'] != null ? formatDateString(row['dob']) : 'N/A'; return DataRow( color: MaterialStateColor.resolveWith((states) => rowColor), cells: [ DataCell( Text(row['emp_code'].toString(), style: textStyle), onTap: isClickable ? () => _navigateToAnotherPage(row) : null, // Navigation only for 'Self' rows ), DataCell(Text(row['name'].toString(), style: textStyle)), DataCell(Text(row['relationship'].toString(), style: textStyle)), DataCell(Text(dob, style: textStyle)), DataCell(Text(row['gender'] ?? 'N/A', style: textStyle)), DataCell(Text(row['mobile'] ?? 'N/A', style: textStyle)), ]); } @override bool get isRowCountApproximate => false; @override int get rowCount => _data.length; @override int get selectedRowCount => 0; void _navigateToAnotherPage(row) { logDebug(row); Navigator.pushNamed(context, 'empDetails', arguments: {'mobile': row['mobile']}); } String formatDateString(String dateString) { // Parse the date string to DateTime object DateTime dateTime = DateTime.parse(dateString); // Format the DateTime object to "dd-mm-yyyy" String formattedDate = DateFormat('dd-MM-yyyy').format(dateTime); return formattedDate; } } // Sample Data class representing each element in the array class Data { final dynamic value; final int row; final int column; final String sheet; Data(this.value, this.row, this.column, this.sheet); }