import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:nhancepolicy/customAppBar/enrollmentAppBar.dart'; import 'package:nhancepolicy/excel_verification.dart'; import 'package:nhancepolicy/models/environment.dart'; import 'package:nhancepolicy/service/api_service.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 '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 'customAppBar/customFooter.dart'; class hrPolicyDetails extends StatefulWidget { const hrPolicyDetails({Key? key}) : super(key: key); @override State createState() => _HrPolicyDetailsState(); } class _HrPolicyDetailsState extends State with TickerProviderStateMixin { Uint8List? fileBytes; late String _token; List> getEmpDependenceByClintId = []; bool isLoading = false; bool _isLoading = false; // dynamic clintID; late TabController _tabController; // List dataPolicy = []; List reversedDataPolicy = []; List> originalData = []; // Original data source List> filteredData = []; // Filtered data source dynamic argumentsData; dynamic policyType; dynamic policyName; dynamic clientPolicyId; dynamic clientId; dynamic empRefId; int inceptionType = 0; TextEditingController searchController = TextEditingController(); late ApiService apiService; @override void initState() { super.initState(); apiService = ApiService(context); // Initialize ApiService here _tabController = TabController(length: 4, vsync: this); _loadToken(); } @override void dispose() { _tabController.dispose(); super.dispose(); } Future _loadToken() async { print('1'); final SharedPreferences prefs = await SharedPreferences.getInstance(); final token = prefs.getString('hrtoken'); if (token != null && token.isNotEmpty) { print('2'); setState(() { _token = token; }); Map? decodedToken = Jwt.parseJwt(token); empRefId = prefs.getString('empRefId'); // clintID = decodedToken['client_id']; getPolicyDetails(); } 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 _saveArgumentsDataToLocalStorage(argumentsData) async { print('6'); print('argumentsData'); final prefs = await SharedPreferences.getInstance(); await prefs.setString('hrSelectArgumentsData', jsonEncode(argumentsData)); } Future getPolicyDetails() async { print('3'); try { print('4'); setState(() { if (argumentsData != null && argumentsData is Map) { print('5'); _saveArgumentsDataToLocalStorage(argumentsData); print('7'); if (argumentsData['type'] == 'GPA') { print('8'); _isLoading = true; clientPolicyId = argumentsData['client_policy_id']; clientId = argumentsData['client_id']; policyType = argumentsData['type']; policyName = argumentsData['policy_name']; String int_inception_type = argumentsData['inception_type']; inceptionType = int.parse(int_inception_type); getEmployeeAndDependence(clientId, clientPolicyId); } else if (argumentsData['type'] == 'GMC') { _isLoading = true; clientPolicyId = argumentsData['client_policy_id']; clientId = argumentsData['client_id']; policyType = argumentsData['type']; policyName = argumentsData['policy_name']; String int_inception_type = argumentsData['inception_type']; inceptionType = int.parse(int_inception_type); getEmployeeAndDependence(clientId, clientPolicyId); } else if (argumentsData['type'] == 'GMC - Parents') { _isLoading = true; clientPolicyId = argumentsData['client_policy_id']; clientId = argumentsData['client_id']; policyType = argumentsData['type']; policyName = argumentsData['policy_name']; String int_inception_type = argumentsData['inception_type']; inceptionType = int.parse(int_inception_type); getEmployeeAndDependence(clientId, clientPolicyId); } else if (argumentsData['type'] == 'GMC - Topup') { _isLoading = true; clientPolicyId = argumentsData['client_policy_id']; clientId = argumentsData['client_id']; policyType = argumentsData['type']; policyName = argumentsData['policy_name']; String int_inception_type = argumentsData['inception_type']; inceptionType = int.parse(int_inception_type); getEmployeeAndDependence(clientId, clientPolicyId); } else if (argumentsData['type'] == 'GMC - Topup(Parents)') { _isLoading = true; clientPolicyId = argumentsData['client_policy_id']; clientId = argumentsData['client_id']; policyType = argumentsData['type']; policyName = argumentsData['policy_name']; String int_inception_type = argumentsData['inception_type']; inceptionType = int.parse(int_inception_type); getEmployeeAndDependence(clientId, clientPolicyId); } else if (argumentsData['type'] == 'EDLI') { _isLoading = true; clientPolicyId = argumentsData['client_policy_id']; clientId = argumentsData['client_id']; policyType = argumentsData['type']; policyName = argumentsData['policy_name']; String int_inception_type = argumentsData['inception_type']; inceptionType = int.parse(int_inception_type); getEmployeeAndDependence(clientId, clientPolicyId); } else if (argumentsData['type'] == 'GTLI') { _isLoading = true; clientPolicyId = argumentsData['client_policy_id']; clientId = argumentsData['client_id']; policyType = argumentsData['type']; policyName = argumentsData['policy_name']; String int_inception_type = argumentsData['inception_type']; inceptionType = int.parse(int_inception_type); getEmployeeAndDependence(clientId, clientPolicyId); } } }); } catch (e) { _isLoading = false; print('Exception occurred: $e'); } finally { setState(() { _isLoading = false; }); } } Future getEmployeeAndDependence(clintID, getPolicyNo) async { print('9'); setState(() { isLoading = true; }); try { print('10'); final response = await apiService.getEmployeeAndDependenceToApi( clintID!, getPolicyNo!, empRefId!); if (response['status'] == 'success') { setState(() { isLoading = false; }); setState(() { getEmpDependenceByClintId = List>.from(response['data']); originalData = getEmpDependenceByClintId; filteredData = List.from(originalData); print('filteredData'); print(filteredData); }); } else { setState(() { isLoading = false; }); // ToastHelper.showWarningToast( // context, 'Request failed with status: ${response.statusCode}'); print('Request failed with status: ${response['code']}'); } } catch (e) { setState(() { isLoading = false; }); print('Exception occurred: $e'); } finally { setState(() { _isLoading = false; }); } } void _uploadFile(type) async { var argumentType; if (type == 'GPA') { // argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails2; argumentType = 'GPA'; } else if (type == 'GMC') { // argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails1; argumentType = '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, 'excelVerify', arguments: argumentsData); // 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 // } // }); // }); // } } // Implement a method to handle the search functionality void search(String query) { print(query); // Check if the query is empty if (query.isEmpty) { // If search query is empty, show all data setState(() { filteredData = List.from(originalData); }); } else { // Filter the original data based on the search query setState(() { filteredData = originalData.where((row) { // Implement your filter logic here // For example, check if any field in the row contains the query // Adjust this logic based on your data structure return row['emp_code'] .toString() .toLowerCase() .contains(query.toLowerCase()) || row['name'] .toString() .toLowerCase() .contains(query.toLowerCase()) || row['relationship'] .toString() .toLowerCase() .contains(query.toLowerCase()) || row['dob'] .toString() .toLowerCase() .contains(query.toLowerCase()) || row['gender'] .toString() .toLowerCase() .contains(query.toLowerCase()) || row['mobile'] .toString() .toLowerCase() .contains(query.toLowerCase()); }).toList(); }); } print(filteredData.length); } 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=$clientId&client_policy_id=$clientPolicyId&client_branch_id=$empRefId'); var response = await http.get( url, headers: { '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', '$policyName - ($policyType).xlsx') ..click(); // Revoke the download URL to free up resources html.Url.revokeObjectUrl(url); } else { // Handle error print('Failed to download Excel file: ${response.statusCode}'); } } @override Widget build(BuildContext context) { dynamic arguments = ModalRoute.of(context)!.settings.arguments; print('arguments'); print(arguments); if (arguments != null && arguments is Map) { argumentsData = arguments; print('argumentsData $argumentsData'); } if (filteredData == []) { return Scaffold( appBar: CustomAppBar(), body: Stack(children: [ SingleChildScrollView( child: Container( color: Color(0xFFEFF3F6), child: Column( children: [ Center( child: Text('No Data Available'), ) ], ), ), ), if (isLoading) Container( color: Color(0x98FFFCE5), // Semi-transparent background child: Center( child: // Your GIF loader widget Image.asset( height: 60, width: 60, 'assets/nhance-loader.gif'), // Adjust path to your GIF loader ), ), Align( alignment: Alignment.bottomCenter, child: Container( width: double.infinity, // Make the footer full width child: CustomFooter(), ), ), ])); } else { return Scaffold( appBar: CustomAppBar(), body: Stack(children: [ Container( padding: const EdgeInsets.only( top: 30, bottom: 70, left: 30, right: 30), color: Color(0xFFEFF3F6), height: MediaQuery.of(context).size.height, child: Card( elevation: 0, color: Colors.white, child: SingleChildScrollView( child: Column( children: [ Center( child: Padding( padding: const EdgeInsets.all(20), child: _isLoading ? Center(child: CircularProgressIndicator()) : originalData.isNotEmpty ? SingleChildScrollView( child: Column( children: [ Container( padding: EdgeInsets.all( 10), // Set your desired padding color: Color( 0xFFE26728), // Set your desired background color child: Row( children: [ Expanded( flex: 6, child: Container( alignment: Alignment .centerLeft, // Align text to the center child: Text( '$policyName - ($policyType)', textAlign: TextAlign .center, // Align text to the center style: GoogleFonts.poppins( fontSize: 16, fontWeight: FontWeight.w500, color: Colors.white, ), ), ), ), Expanded( flex: 6, child: Container( alignment: Alignment .centerRight, // Align text to the center child: MouseRegion( cursor: SystemMouseCursors .click, child: GestureDetector( onTap: () async { final prefs = await SharedPreferences .getInstance(); await prefs.remove( 'hrSelectArgumentsData'); Navigator.pushNamed( context, 'hrDashboard'); }, child: Icon( Icons .close, // Replace with your desired icon color: Colors .white, // Replace with your desired icon color ), ), ), ), ), ], ), ), SizedBox(height: 20), Row( children: [ Expanded( flex: (policyType == 'GPA' || policyType == 'GMC') ? 8 : 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 ), ), controller: searchController, onChanged: search, // 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: (policyType == 'GPA' || policyType == 'GMC') ? 5 : 0), if ((policyType == 'GPA' || policyType == 'GMC' || policyType == 'EDLI' || policyType == 'GTLI') && inceptionType == 2) Expanded( flex: 2, child: Container( alignment: Alignment.centerRight, child: Row( mainAxisAlignment: MainAxisAlignment .center, children: [ Expanded( child: ElevatedButton( onPressed: () => _uploadFile( policyType), 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.start, children: [ Container( padding: EdgeInsets.all( 10), // Set your desired padding color: Color( 0xFFE26728), // Set your desired background color child: Row( children: [ Expanded( flex: 6, child: Container( alignment: Alignment .centerLeft, // Align text to the center child: Text( (policyName != null && policyType != null) ? '$policyName - ($policyType)' : '', textAlign: TextAlign .center, // Align text to the center style: GoogleFonts.poppins( fontSize: 16, fontWeight: FontWeight.w500, color: Colors.white, ), ), ), ), Expanded( flex: 6, child: Container( alignment: Alignment .centerRight, // Align text to the center child: MouseRegion( cursor: SystemMouseCursors .click, child: GestureDetector( onTap: () { Navigator.pushNamed( context, 'hrDashboard'); }, child: Icon( Icons .close, // Replace with your desired icon color: Colors .white, // Replace with your desired icon color ), ), ), ), ), ], ), ), SizedBox(height: 200), if (inceptionType == 2) Center( child: ElevatedButton( onPressed: () => _uploadFile(policyType), child: Text( 'Import Data', style: TextStyle( color: Colors.white), ), style: ElevatedButton.styleFrom( backgroundColor: Color(0xFFE26728), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular( 5), ), ), ), ) else Center( child: Text( 'No Data Available', style: GoogleFonts.poppins( fontSize: 16, letterSpacing: 0, color: Colors.black, fontWeight: FontWeight.w300, ), ), ) ], ), ), ), ), ], ), )), ), if (isLoading) Container( color: Color(0x98FFFCE5), // Semi-transparent background child: Center( child: // Your GIF loader widget Image.asset( height: 60, width: 60, 'assets/nhance-loader.gif'), // Adjust path to your GIF loader ), ), Align( alignment: Alignment.bottomCenter, child: Container( width: double.infinity, // Make the footer full width child: CustomFooter(), ), ), ])); } } Widget _buildDataTableGPA(context) { if (filteredData.isEmpty) { SizedBox(height: 25); return Text('No available data'); } else { return Card( elevation: 0, color: Colors.white, // Set elevation to 0 for no shadow child: PaginatedDataTable( rowsPerPage: filteredData.length, // Adjust rows per page as needed columns: [ DataColumn(label: Text('Employee ID')), DataColumn(label: Text('TPA ID')), DataColumn(label: Text('Name')), DataColumn(label: Text('Relationship')), DataColumn(label: Text('Date of Birth')), DataColumn(label: Text('Gender')), DataColumn(label: Text('Mobile No')), // DataColumn(label: Text('Date of Joining')), DataColumn(label: Text('Date Coverage')), DataColumn(label: Text('Email')), DataColumn(label: Text('SI')), DataColumn(label: Text('Grade')), DataColumn(label: Text('Basic Pay')), ], source: _DependenceDataSource0(filteredData, 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'; // String doj = row['doj'] != null ? formatDateString(row['doj']) : 'N/A'; String dateCoverage = row['date_coverage'] != null ? formatDateString(row['date_coverage']) : '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['tpa_id'].toString(), style: textStyle)), 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)), // DataCell(Text(doj, style: textStyle)), DataCell(Text(dateCoverage, style: textStyle)), DataCell(Text(row['email_corporate'] ?? 'N/A', style: textStyle)), DataCell(Text(row['basic_cover_si'] ?? 'N/A', style: textStyle)), DataCell(Text(row['grade'] ?? 'N/A', style: textStyle)), DataCell(Text(row['basic_pay'] ?? 'N/A', style: textStyle)), ], ); } @override bool get isRowCountApproximate => false; @override int get rowCount => _data.length; @override int get selectedRowCount => 0; void _navigateToAnotherPage(row) async { print(row['mobile']); final SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setBool('showBackToHR', true); prefs.setString('employee_id', row['employee_id']); // 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; } } // 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); }