diff --git a/assets/hrLogin.jpg b/assets/hrLogin.jpg new file mode 100644 index 0000000..e2b0892 Binary files /dev/null and b/assets/hrLogin.jpg differ diff --git a/lib/customAppBar/toastHelper.dart b/lib/customAppBar/toastHelper.dart index ab65bbe..ec1a706 100644 --- a/lib/customAppBar/toastHelper.dart +++ b/lib/customAppBar/toastHelper.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:fluttertoast/fluttertoast.dart'; +// import 'package:fluttertoast/fluttertoast.dart'; class ToastHelper { static void showSuccessToast(BuildContext context, String message) { @@ -15,14 +15,14 @@ class ToastHelper { } static void _showToast(BuildContext context, String message, Color color) { - Fluttertoast.showToast( - msg: message, - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.TOP, - timeInSecForIosWeb: 5, - backgroundColor: color, - textColor: Colors.white, - fontSize: 16.0, - ); + // Fluttertoast.showToast( + // msg: message, + // toastLength: Toast.LENGTH_SHORT, + // gravity: ToastGravity.TOP, + // timeInSecForIosWeb: 5, + // backgroundColor: color, + // textColor: Colors.white, + // fontSize: 16.0, + // ); } } diff --git a/lib/excel_verification.dart b/lib/excel_verification.dart new file mode 100644 index 0000000..3c8db1d --- /dev/null +++ b/lib/excel_verification.dart @@ -0,0 +1,566 @@ +import 'dart:typed_data'; +import 'package:flutter/material.dart'; +import 'package:jwt_decode/jwt_decode.dart'; +import 'package:nhancepolicy/customAppBar/customAppBar.dart'; +import 'dart:convert'; +import 'dart:async'; +import 'package:http/http.dart' as http; +import 'package:nhancepolicy/models/environment.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:universal_html/html.dart' as html; +import 'package:flutter/foundation.dart' show kIsWeb; +import 'package:excel/excel.dart'; + +class excelVerify extends StatefulWidget { + const excelVerify({Key? key}) : super(key: key); + + @override + State createState() => _excelVerifyState(); +} + +class _excelVerifyState extends State { + Uint8List? fileBytes; + Uint8List? fileBytes2; + late String _token; + dynamic getPolicyNo; + bool _isLoading = false; + dynamic getPolicyNameDetails; + dynamic clintID; + String? fileName; + int _currentStep = 0; // Step index tracker + List dataPolicy = []; + dynamic validationArray = []; + dynamic missingColumnErrorMsg = 0; + dynamic columnIndexMismatchCount = 0; + dynamic columnMissingCount = 0; + List> extractedData = []; + + @override + void initState() { + super.initState(); + _loadToken(); + } + + @override + void dispose() { + super.dispose(); + } + + Future _loadToken() async { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + final token = prefs.getString('token'); + if (token != null) { + setState(() { + _token = token; + }); + Map? decodedToken = Jwt.parseJwt(token); + clintID = decodedToken['client_id'].toString(); + await getPolicyName(clintID); + } else { + _token = 'null'; + // Handle the case when token is not available + } + } + + 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: { + 'Authorization': 'Bearer $_token', + }, + ); + if (response.statusCode == 200) { + Map data = json.decode(response.body); + if (data['status'] == 'success') { + print(data); + setState(() { + dataPolicy = List>.from(data['data']); + print(dataPolicy); + getPolicyNameDetails = dataPolicy[0]['policy_name']; + print(getPolicyNameDetails); + getPolicyNo = dataPolicy[0]['client_policy_id']; + }); + + print('Successfully Sent'); + } else { + print('API request failed with status: ${data['status']}'); + } + } else { + print('Request failed with status: ${response.statusCode}'); + } + } catch (e) { + print('Exception occurred: $e'); + } finally { + setState(() { + _isLoading = false; + }); + } + } + + void _uploadFile(importPolicyName) async { + 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 { + Uint8List? fileBytes = reader.result as Uint8List?; + Uint8List? fileBytes2 = reader.result as Uint8List?; + if (fileBytes != null) { + // Call function to process Excel data + setState(() { + fileName = file.name; + }); + + print(fileName); + _processExcelData(fileBytes); + } + }); + }); + } + } + + void _processExcelData(Uint8List fileBytes) { + // Decode the Excel file and extract relevant data + // Assuming dataArray is your array containing Excel data + List> dataArray = decodeExcelData(fileBytes); + + // print(dataArray[0].toString()); + // Extract Name, Age, and City from the array + print(dataArray[0].length); + + if (dataArray[0].length == 10) { + for (int i = 0; i < dataArray.length; i++) { + Map dataMap = { + "SNo": dataArray[i][0].value, + "EmpCode": dataArray[i][1].value, + "Name": dataArray[i][2].value, + "DOJ": dataArray[i][3].value, + "Gender": dataArray[i][4].value, + "Relation": dataArray[i][5].value, + "DOB": dataArray[i][6].value, + "Mail": dataArray[i][7].value, + "Mobile": dataArray[i][8].value, + "SI": dataArray[i][9].value, + }; + if (i == 0) { + // print(dataMap); + validationArray.add(dataMap); + } else { + // print(dataMap); + extractedData.add(dataMap); + } + } + // Do something with extracted data (e.g., display in UI) + + print(extractedData); + print(validationArray); + + validationArray[0].forEach((key, value) { + print(key); + print(value); + if (key.toString() != value.toString()) { + // If key and value are not equal, increment mismatch count + columnIndexMismatchCount++; + } + if (value.toString() == 'null') { + // If value is null, increment missing count + columnMissingCount++; + } + }); + + print('columnIndexMismatchCount: $columnIndexMismatchCount'); + print('columnMissingCount: $columnMissingCount'); + } else { + print('Some Column is Missing'); + var columnMissingCount = 10 - dataArray[0].length; + missingColumnErrorMsg = columnMissingCount; + print(missingColumnErrorMsg); + } + } + + // Placeholder function for decoding Excel data + List> decodeExcelData(Uint8List fileBytes) { + // Implement your logic to decode Excel data here + // This function should return your array containing Excel data + // For example, you can use the excel package to decode the Excel file + // Import the excel package in your pubspec.yaml file: + // dependencies: + // excel: ^1.1.0 + // Then use the following code to decode the Excel file: + + // Import the necessary packages + // import 'package:excel/excel.dart'; + + // Create an Excel instance from the fileBytes + final excel = Excel.decodeBytes(fileBytes); + + // Assuming there's only one sheet in the Excel file + final sheet = excel.tables.keys.first; + final table = excel.tables[sheet]!; + + // Convert Excel table to a List> + // Convert Excel table to a List> + List> dataArray = []; + for (int rowIdx = 0; rowIdx < table.rows.length; rowIdx++) { + List rowData = []; + for (int colIdx = 0; colIdx < table.rows[rowIdx].length; colIdx++) { + var value = table.rows[rowIdx][colIdx]?.value; + rowData.add(Data(value, rowIdx, colIdx, sheet)); + } + dataArray.add(rowData); + } + return dataArray; + } + + Future sendExcelFIleTOAPI() async { + print('_processExcelData'); + print(fileBytes2); + if (fileBytes == null) { + print('return'); + return; // No file selected + } + + // URL of the API where you want to send the file + final apiUrl = Environment.apiUrl + 'employeeUpload'; + + // Create a multipart request + final request = http.MultipartRequest('POST', Uri.parse(apiUrl)); + + // Attach the file to the request + // Set authorization token in headers + request.headers['Authorization'] = 'Bearer $_token'; + request.files.add(http.MultipartFile.fromBytes('file', fileBytes!, + filename: fileName)); // Specify filename here + request.fields['client_id'] = clintID; + request.fields['policy_id'] = '1'; + + // Send the request + final response = await request.send(); + + // Check the status code of the response + if (response.statusCode == 200) { + // ToastHelper.showSuccessToast(context, 'File uploaded successfully'); + print('File uploaded successfully'); + Navigator.pushNamed(context, 'hrHome'); + } else { + // ToastHelper.showSuccessToast( + // context, 'Failed to upload file: ${response.reasonPhrase}'); + print('Failed to upload file: ${response.reasonPhrase}'); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar(), + body: Container( + padding: const EdgeInsets.all(20), + color: Color(0xFFEFF3F6), + child: Card( + elevation: 0, + child: Column( + children: [ + Expanded( + child: Stepper( + type: StepperType.horizontal, + currentStep: _currentStep, + onStepContinue: _currentStep == 2 + ? null + : () { + if (_currentStep == 0) { + // For the first step, allow continue if fileName is not null + if (fileName != null) { + setState(() { + _currentStep += 1; + }); + } + } else if (_currentStep == 1) { + // For the second step, allow continue if both errors are 0 + if (missingColumnErrorMsg == 0 && + columnIndexMismatchCount == 0) { + setState(() { + _currentStep += 1; + }); + } + } + // setState(() { + // // Increment the current step when the user clicks continue + // if (_currentStep < 2) { + // _currentStep += 1; + // } + // }); + }, + onStepCancel: () { + setState(() { + // Decrement the current step when the user clicks cancel + if (_currentStep > 0) { + _currentStep -= 1; + } + }); + }, + steps: [ + Step( + title: Container( + child: Text( + 'Import Excel', + style: TextStyle( + color: Color(0xFFE26728), + ), + ), + ), + content: Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + flex: 6, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 10), + alignment: Alignment.center, + color: Colors.grey[200], + height: 300, // Adjust height as needed + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + fileName != null + ? Text( + 'File Uploaded: $fileName', + style: TextStyle(fontSize: 16), + ) + : ElevatedButton( + onPressed: () => + _uploadFile('Policy Name'), + child: Text( + 'Import', + style: TextStyle( + color: Colors.white), + ), + style: ElevatedButton.styleFrom( + backgroundColor: + Color(0xFFE26728), + ), + ), + SizedBox(height: 20), // Add some space + // Drag and drop widget goes here + // Example: DragTarget or Draggable + // For example, a DragTarget that accepts Draggable widgets + // if (fileName != null) + // Text( + // 'File Uploaded: $fileName', + // style: TextStyle(fontSize: 16), + // ), + if (fileName == null) + DragTarget( + builder: (BuildContext context, + List candidateData, + List rejectedData) { + return Container( + width: 200, + height: 200, + alignment: Alignment.center, + color: Colors.blue, + child: Text( + 'Drag and drop file to import'), + ); + }, + onAccept: (data) { + // Handle accepted data + }, + ), + ], + ), + ), + ), + ], + ), + ), + isActive: _currentStep == 0, + ), + Step( + title: Text( + 'Excel Validation', + style: TextStyle(color: Color(0xFFE26728)), + ), + content: Padding( + padding: EdgeInsets.only( + top: 30, + bottom: 30, + left: 300, + right: + 300), // Adjust the horizontal padding as needed + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + _buildRowWithIcon( + missingColumnErrorMsg == 0 + ? Icons.check_circle + : Icons.error, + 'No of column missing - $missingColumnErrorMsg', + iconColor: missingColumnErrorMsg == 0 + ? Colors.green + : Colors.red, // Set color based on condition + ), + if (missingColumnErrorMsg == 0) + _buildRowWithIcon( + columnIndexMismatchCount == 0 + ? Icons.check_circle + : Icons.error, + 'Column Index is Missmatching - $columnIndexMismatchCount', + iconColor: columnIndexMismatchCount == 0 + ? Colors.green + : Colors.red, + ), + // _buildRowWithIcon( + // columnMissingCount == 0 + // ? Icons.check_circle + // : Icons.error, + // 'Column Missing - $columnMissingCount', + // iconColor: columnMissingCount == 0 + // ? Colors.green + // : Colors.red, + // ), + ], + ), + ), + isActive: _currentStep == 1, + ), + Step( + title: Text( + 'Preview', + style: TextStyle(color: Color(0xFFE26728)), + ), + content: Column( + children: [ + Row( + children: [ + Expanded( + child: SingleChildScrollView( + child: _buildDataTable(), + ), + ) + ], + ), + ], + ), + isActive: _currentStep == 2, + ), + ], + ), + ), + SizedBox(height: 20), + if (_currentStep == 2) + Align( + alignment: Alignment.bottomRight, + child: ElevatedButton( + onPressed: () { + sendExcelFIleTOAPI(); + }, + child: Text( + 'Complete', + style: TextStyle(color: Colors.white), + ), + style: ElevatedButton.styleFrom( + backgroundColor: Color(0xFFE26728), + ), + ), + ), + SizedBox(height: 20), + ], + ), + ), + ), + ); + } + + Widget _buildDataTable() { + if (extractedData.isEmpty) { + SizedBox(height: 25); + return Text('No available data'); + } else { + return Card( + elevation: 0, // Set elevation to 0 for no shadow + child: PaginatedDataTable( + rowsPerPage: 10, // Adjust rows per page as needed + columns: [ + DataColumn(label: Text('S.No')), + DataColumn(label: Text('Employee ID')), + DataColumn(label: Text('Name')), + DataColumn(label: Text('Date of Joining')), + DataColumn(label: Text('Gender')), + DataColumn(label: Text('Relationship')), + DataColumn(label: Text('Date of Birth')), + DataColumn(label: Text('Mail')), + DataColumn(label: Text('Mobile No')), + DataColumn(label: Text('SI')), + ], + source: _DependenceDataSource0(extractedData), + ), + ); + } + } + + Widget _buildRowWithIcon(IconData iconData, String text, + {Color iconColor = Colors.black}) { + return Row( + children: [ + Icon( + iconData, + color: iconColor, // Set color based on the parameter + ), + SizedBox(width: 8), // Add some space between icon and text + Text(text), // Text widget + ], + ); + } +} + +class Data { + final dynamic value; + final int row; + final int column; + final String sheet; + + Data(this.value, this.row, this.column, this.sheet); +} + +class _DependenceDataSource0 extends DataTableSource { + final List> _data; + _DependenceDataSource0(this._data); + + @override + DataRow getRow(int index) { + final row = _data[index]; + return DataRow(cells: [ + DataCell(Text(row['SNo'].toString())), + DataCell(Text(row['EmpCode'].toString())), + DataCell(Text(row['Name'].toString())), + DataCell(Text(row['DOJ']?.toString() ?? 'N/A')), + DataCell(Text(row['Gender']?.toString() ?? 'N/A')), + DataCell(Text(row['Relation']?.toString() ?? 'N/A')), + DataCell(Text(row['DOB']?.toString() ?? 'N/A')), + DataCell(Text(row['Mail']?.toString() ?? 'N/A')), + DataCell(Text(row['Mobile']?.toString() ?? 'N/A')), + DataCell(Text(row['SI']?.toString() ?? 'N/A')), + ]); + } + + @override + bool get isRowCountApproximate => false; + + @override + int get rowCount => _data.length; + + @override + int get selectedRowCount => 0; +} diff --git a/lib/home.dart b/lib/home.dart index 5bddaeb..4d5b3d1 100644 --- a/lib/home.dart +++ b/lib/home.dart @@ -10,7 +10,7 @@ import 'dart:io'; import 'package:nhancepolicy/responsive.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:jwt_decode/jwt_decode.dart'; -import 'package:fluttertoast/fluttertoast.dart'; +// import 'package:fluttertoast/fluttertoast.dart'; import 'package:nhancepolicy/customAppBar/toastHelper.dart'; // void main() { @@ -482,17 +482,17 @@ class _MyAppState extends State { // Check the response status code if (response.statusCode == 200) { - ToastHelper.showSuccessToast(context, 'Successfully Saved'); + // ToastHelper.showSuccessToast(context, 'Successfully Saved'); getEmpDetails(empCodeString); } else { // Handle other status codes - ToastHelper.showErrorToast(context, 'Failed to update user details'); + // ToastHelper.showErrorToast(context, 'Failed to update user details'); print('Request failed with status: ${response.statusCode}'); } } catch (e) { // Handle exceptions print('Exception occurred: $e'); - ToastHelper.showErrorToast(context, 'Exception occurred: $e'); + // ToastHelper.showErrorToast(context, 'Exception occurred: $e'); } } } @@ -519,8 +519,8 @@ class _MyAppState extends State { throw Exception('Failed to fetch relationship list'); } } catch (error) { - ToastHelper.showErrorToast( - context, 'Error fetching relationship list: $error'); + // ToastHelper.showErrorToast( + // context, 'Error fetching relationship list: $error'); print('Error fetching relationship list: $error'); // Handle error accordingly, e.g., show a snackbar with an error message } @@ -586,8 +586,8 @@ class _MyAppState extends State { } catch (error) { // Handle any errors that occur during the API call // print('Error removing family member: $error'); - ToastHelper.showErrorToast( - context, 'Error removing family member: $error'); + // ToastHelper.showErrorToast( + // context, 'Error removing family member: $error'); } } @@ -640,14 +640,14 @@ class _MyAppState extends State { setState(() { getEmpDetails(empCodeString); }); - ToastHelper.showSuccessToast(context, "Saved successfully!"); + // ToastHelper.showSuccessToast(context, "Saved successfully!"); } } else { // Failed to save member - ToastHelper.showErrorToast(context, "Operation Failed!"); + // ToastHelper.showErrorToast(context, "Operation Failed!"); } } catch (error) { - ToastHelper.showErrorToast(context, "Error saving family members"); + // ToastHelper.showErrorToast(context, "Error saving family members"); } } @@ -701,14 +701,17 @@ class _MyAppState extends State { getEmpPolicyDetails(empPrimaryId); }); floaterData = []; - ToastHelper.showSuccessToast(context, "Saved successfully!"); + // ToastHelper.showSuccessToast(context, "Saved successfully!"); + print('Saved successfully!'); } } else { // Failed to save member - ToastHelper.showErrorToast(context, "Operation Failed!"); + // ToastHelper.showErrorToast(context, "Operation Failed!"); + print('Operation Failed!'); } } catch (error) { - ToastHelper.showErrorToast(context, "Error saving family members"); + print('Error saving family members'); + // ToastHelper.showErrorToast(context, "Error saving family members"); } } @@ -778,14 +781,16 @@ class _MyAppState extends State { setState(() { getEmpDetails(empCodeString); }); - ToastHelper.showSuccessToast(context, "Saved successfully!"); + // ToastHelper.showSuccessToast(context, "Saved successfully!"); + print('Saved successfully!'); } } else { + print('Operation Failed!'); // Failed to save member - ToastHelper.showErrorToast(context, "Operation Failed!"); + // ToastHelper.showErrorToast(context, "Operation Failed!"); } // } catch (error) { - // print(error); + print('Error saving family members'); // ToastHelper.showErrorToast(context, "Error saving family members"); // } } diff --git a/lib/hrHome.dart b/lib/hrHome.dart index ef02f82..07dfb9a 100644 --- a/lib/hrHome.dart +++ b/lib/hrHome.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:nhancepolicy/customAppBar/customAppBar.dart'; +import 'package:nhancepolicy/excel_verification.dart'; import 'package:nhancepolicy/models/environment.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:jwt_decode/jwt_decode.dart'; @@ -8,10 +9,12 @@ import 'dart:async'; import 'package:http/http.dart' as http; import 'package:file_picker/file_picker.dart'; import 'package:nhancepolicy/customAppBar/toastHelper.dart'; -import 'dart:html' as html; +// 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:excel/excel.dart'; class MyHrHome extends StatefulWidget { const MyHrHome({Key? key}) : super(key: key); @@ -22,6 +25,7 @@ class MyHrHome extends StatefulWidget { class _MyHrHomeState extends State with TickerProviderStateMixin { Uint8List? _fileBytes; + Uint8List? fileBytes; late String _token; List> getEmpDependenceByClintIdGMC = []; List> getEmpDependenceByClintIdGPA = []; @@ -49,7 +53,7 @@ class _MyHrHomeState extends State with TickerProviderStateMixin { Future _loadToken() async { final SharedPreferences prefs = await SharedPreferences.getInstance(); - final String? token = prefs.getString('token'); + final token = prefs.getString('token'); if (token != null) { setState(() { _token = token; @@ -58,6 +62,7 @@ class _MyHrHomeState extends State with TickerProviderStateMixin { clintID = decodedToken['client_id'].toString(); await getPolicyName(clintID); } else { + _token = 'null'; // Handle the case when token is not available } } @@ -270,26 +275,108 @@ class _MyHrHomeState extends State with TickerProviderStateMixin { // } // } - void _uploadFile(importPolicyName) async { - print('openFile1'); - final input = html.FileUploadInputElement(); - input.accept = '.xlsx,.xls'; // Specify accepted file types here - input.click(); - print('openFile2'); - input.onChange.listen((event) { - final file = input.files!.first; - final reader = html.FileReader(); - reader.readAsArrayBuffer(file); + // void _uploadFile(importPolicyName) async { + // if (kIsWeb) { + // print('WEB'); + // final input = html.FileUploadInputElement(); + // input.accept = '.xlsx,.xls'; // Specify accepted file types here + // input.click(); + // input.onChange.listen((event) { + // final file = input.files!.first; + // final reader = html.FileReader(); + // reader.readAsArrayBuffer(file); + // + // reader.onLoadEnd.listen((event) { + // setState(() { + // _fileBytes = reader.result as Uint8List?; + // _importFile(importPolicyName); + // }); + // }); + // }); + // } + // } - reader.onLoadEnd.listen((event) { - setState(() { - print('openFile3'); - _fileBytes = reader.result as Uint8List?; - print(_fileBytes); - _importFile(importPolicyName); + void _uploadFile(importPolicyName) async { + Navigator.pushNamed(context, 'excelVerify'); + 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 + _processExcelData(fileBytes); + } }); }); - }); + } + } + + void _processExcelData(Uint8List fileBytes) { + // Decode the Excel file and extract relevant data + // Assuming dataArray is your array containing Excel data + List> dataArray = decodeExcelData(fileBytes); + + // Extract Name, Age, and City from the array + List> extractedData = []; + for (int i = 1; i < dataArray.length; i++) { + Map dataMap = { + "SNo": dataArray[i][0].value, + "EmpCode": dataArray[i][1].value, + "Name": dataArray[i][2].value, + "DOJ": dataArray[i][3].value, + "Gender": dataArray[i][4].value, + "Relation": dataArray[i][5].value, + "DOB": dataArray[i][6].value, + "mail": dataArray[i][7].value, + "mobile": dataArray[i][8].value, + "SI": dataArray[i][9].value, + }; + extractedData.add(dataMap); + } + + // Do something with extracted data (e.g., display in UI) + print(extractedData); + } + + // Placeholder function for decoding Excel data + List> decodeExcelData(Uint8List fileBytes) { + // Implement your logic to decode Excel data here + // This function should return your array containing Excel data + // For example, you can use the excel package to decode the Excel file + // Import the excel package in your pubspec.yaml file: + // dependencies: + // excel: ^1.1.0 + // Then use the following code to decode the Excel file: + + // Import the necessary packages + // import 'package:excel/excel.dart'; + + // Create an Excel instance from the fileBytes + final excel = Excel.decodeBytes(fileBytes); + + // Assuming there's only one sheet in the Excel file + final sheet = excel.tables.keys.first; + final table = excel.tables[sheet]!; + + // Convert Excel table to a List> + // Convert Excel table to a List> + List> dataArray = []; + for (int rowIdx = 0; rowIdx < table.rows.length; rowIdx++) { + List rowData = []; + for (int colIdx = 0; colIdx < table.rows[rowIdx].length; colIdx++) { + var value = table.rows[rowIdx][colIdx]?.value; + rowData.add(Data(value, rowIdx, colIdx, sheet)); + } + dataArray.add(rowData); + } + return dataArray; } Future _importFile(importPolicyName) async { @@ -320,7 +407,8 @@ class _MyHrHomeState extends State with TickerProviderStateMixin { // Check the status code of the response if (response.statusCode == 200) { - ToastHelper.showSuccessToast(context, 'File uploaded successfully'); + // ToastHelper.showSuccessToast(context, 'File uploaded successfully'); + print('File uploaded successfully'); if (importPolicyName == 'GPA') { await getEmployeeAndDependenceGPA(clintID, getPolicyNo0); } else { @@ -328,8 +416,8 @@ class _MyHrHomeState extends State with TickerProviderStateMixin { } print('File uploaded successfully'); } else { - ToastHelper.showSuccessToast( - context, 'Failed to upload file: ${response.reasonPhrase}'); + // ToastHelper.showSuccessToast( + // context, 'Failed to upload file: ${response.reasonPhrase}'); print('Failed to upload file: ${response.reasonPhrase}'); } } @@ -436,16 +524,6 @@ class _MyHrHomeState extends State with TickerProviderStateMixin { // } // } -// Check if the code is running on web - bool get isWeb { - try { - // Check if the window object is accessible - return identical(0, 0.0); - } catch (_) { - return false; - } - } - @override Widget build(BuildContext context) { return Scaffold( @@ -458,10 +536,30 @@ class _MyHrHomeState extends State with TickerProviderStateMixin { child: Column( children: [ TabBar( + labelColor: Colors.white, // Selected tab color + unselectedLabelColor: Colors.grey, // Unselected tab color + indicator: BoxDecoration( + color: Colors.red, // Background color of selected tab + ), + indicatorSize: TabBarIndicatorSize.label, controller: _tabController, tabs: [ - Tab(text: 'GPA-' + getPolicyNameDetails0 ?? ''), - Tab(text: 'GMC-' + getPolicyNameDetails1 ?? ''), + 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( @@ -650,7 +748,7 @@ class _MyHrHomeState extends State with TickerProviderStateMixin { DataColumn(label: Text('Gender')), DataColumn(label: Text('Mobile No')), ], - source: _DependenceDataSource0(getEmpDependenceByClintIdGMC), + source: _DependenceDataSource1(getEmpDependenceByClintIdGMC), ), ); } @@ -710,3 +808,13 @@ class _DependenceDataSource1 extends DataTableSource { @override int get selectedRowCount => 0; } + +// 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); +} diff --git a/lib/hrLogin.dart b/lib/hrLogin.dart index 59bc852..dbae365 100644 --- a/lib/hrLogin.dart +++ b/lib/hrLogin.dart @@ -131,72 +131,132 @@ class _MyPhoneState extends State { children: [ Row( children: [ + if (_size.width > 1100) + Expanded( + flex: _size.width < 1100 ? 6 : 12, + child: LayoutBuilder( + builder: (BuildContext context, + BoxConstraints constraints) { + if (constraints.maxWidth > 600) { + return Image.asset( + 'assets/hrLogin.jpg', + height: _size.height, + fit: BoxFit.fill, + ); + } else { + return SizedBox(); + } + }, + ), + ), Expanded( flex: _size.width < 1100 ? 6 : 12, child: Container( margin: _size.width > 1100 - ? EdgeInsets.only(left: 150, right: 150) + ? EdgeInsets.only(left: 20, right: 20) : null, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Container( - child: InkWell( - onTap: - toggleLoginType, // Call the toggleLoginType function on tap - child: Container( - // Add your text here - child: Text( - 'Employee Login', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Color(0xFF00989E)), - ), - alignment: Alignment - .centerRight, // Add padding - ), - ), - ), - _size.width <= 1100 - ? Image.asset( - 'assets/Nhance-Logo-Final-mobile.png', - width: 150, - height: 150, - ) - : _size.width > 1100 - ? Image.asset( - 'assets/Nhance-Logo-Final 1.png', - width: 150, - height: 150, - ) - : Image.asset( - 'assets/Nhance-Logo-Final 1.png', - width: 150, - height: 150, + Row( + children: [ + Expanded( + flex: 6, + child: Align( + alignment: Alignment.centerLeft, + child: MouseRegion( + cursor: + SystemMouseCursors.click, + child: GestureDetector( + onTap: () { + // Add your navigation logic here + // For example, you can use Navigator.push to navigate to another page + Navigator.pushNamed( + context, 'phone'); + }, + child: Row( + children: [ + Icon( + Icons + .keyboard_backspace, // Icon for customer login + color: Colors + .black, // Adjust color as needed + ), + SizedBox( + width: + 5), // Add some space between icon and text + Text( + 'Customer Login', + style: TextStyle( + color: Color( + 0xFF000000), // Text color + // Add other text styles as needed + ), + ), + ], + ), + ), ), - SizedBox( - height: _size.width <= 1100 ? 50 : 0, - ), - Text( - "Welcome to Nhance HR Login", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), + )), + Expanded( + flex: 6, + child: Align( + alignment: Alignment + .centerRight, // Align to the start + child: _size.width <= 1100 + ? Image.asset( + 'assets/Nhance-Logo-Final-mobile.png', + width: 150, + height: 150, + ) + : _size.width > 1100 + ? Image.asset( + 'assets/Nhance-Logo-Final 1.png', + width: 150, + height: 150, + ) + : Image.asset( + 'assets/Nhance-Logo-Final 1.png', + width: 150, + height: 150, + ), + )), + ], ), SizedBox( - height: 10, - ), - Text( - "Have a Health Insurance Policy number, but never signed in? Don't worry, We got you covered", - style: TextStyle( - fontSize: 12, - color: Color(0xFF000000)), - textAlign: TextAlign.center, + height: + 20), // Add some space between rows + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Text( + "Welcome to Nhance", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], ), SizedBox( - height: 30, + height: 15, + ), + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Text( + "Have a Health Insurance Policy number, but never signed in? Don't worry, We got you covered", + style: TextStyle( + fontSize: 12, + color: Color(0xFF000000)), + textAlign: TextAlign.center, + ), + ], + ), + SizedBox( + height: 20, ), Container( height: 55, @@ -426,24 +486,6 @@ class _MyPhoneState extends State { ), ), ), - if (_size.width > 1100) - Expanded( - flex: _size.width < 1100 ? 6 : 12, - child: LayoutBuilder( - builder: (BuildContext context, - BoxConstraints constraints) { - if (constraints.maxWidth > 600) { - return Image.asset( - 'assets/login_web.jpg', - height: _size.height, - fit: BoxFit.fill, - ); - } else { - return SizedBox(); - } - }, - ), - ), ], ), ], diff --git a/lib/hrVerify.dart b/lib/hrVerify.dart index aa6ceca..e68ae4a 100644 --- a/lib/hrVerify.dart +++ b/lib/hrVerify.dart @@ -235,6 +235,28 @@ class _MyVerifyState extends State { key: _formKey, child: Column(children: [ Row(children: [ + if (_size.width > + 1100) // Render Expanded column only if screen width is greater than 600 (tablet or larger) + Expanded( + flex: _size.width < 1100 + ? 6 + : 12, // Take 6 parts out of 12 + child: LayoutBuilder( + builder: (BuildContext context, + BoxConstraints constraints) { + // Only show the image column if screen width is greater than 600 (tablet or larger) + if (constraints.maxWidth > 600) { + return Image.asset( + 'assets/hrLogin.jpg', + height: _size.height, + fit: BoxFit.fill, + ); + } else { + return SizedBox(); // If screen width is smaller, return an empty SizedBox + } + }, + ), + ), Expanded( flex: _size.width < 1100 ? 6 : 12, child: Container( @@ -291,7 +313,7 @@ class _MyVerifyState extends State { ..onTap = () { // Navigate to the page where the user can change the phone number Navigator.pushNamed( - context, 'phone'); + context, 'hrLogin'); }, ), ], @@ -510,28 +532,6 @@ class _MyVerifyState extends State { ], ), )), - if (_size.width > - 1100) // Render Expanded column only if screen width is greater than 600 (tablet or larger) - Expanded( - flex: _size.width < 1100 - ? 6 - : 12, // Take 6 parts out of 12 - child: LayoutBuilder( - builder: (BuildContext context, - BoxConstraints constraints) { - // Only show the image column if screen width is greater than 600 (tablet or larger) - if (constraints.maxWidth > 600) { - return Image.asset( - 'assets/login_web.jpg', - height: _size.height, - fit: BoxFit.fill, - ); - } else { - return SizedBox(); // If screen width is smaller, return an empty SizedBox - } - }, - ), - ), ]) ])))) ]), diff --git a/lib/main.dart b/lib/main.dart index 87ade9a..e867b68 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,8 @@ +import 'dart:js'; + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:nhancepolicy/excel_verification.dart'; import 'package:nhancepolicy/hrHome.dart'; import 'package:nhancepolicy/hrVerify.dart'; import 'package:nhancepolicy/models/environment.dart'; @@ -21,7 +24,8 @@ Future main() async { 'home': (context) => MyApp(), 'hrLogin': (context) => MyHrLogin(), 'hrVerify': (context) => MyHrVerify(), - 'hrHome': (context) => MyHrHome() + 'hrHome': (context) => MyHrHome(), + 'excelVerify': (context) => excelVerify(), }, )); } diff --git a/lib/phone.dart b/lib/phone.dart index de65ebd..40fbebe 100644 --- a/lib/phone.dart +++ b/lib/phone.dart @@ -63,7 +63,8 @@ class _MyPhoneState extends State { if (isValid) { Navigator.pushNamed(context, 'verify', arguments: enteredMobileNumber); } else { - ToastHelper.showErrorToast(context, 'Invalid mobile number'); + // ToastHelper.showErrorToast(context, 'Invalid mobile number'); + print('Invalid mobile number'); } } } @@ -131,68 +132,99 @@ class _MyPhoneState extends State { flex: _size.width < 1100 ? 6 : 12, child: Container( margin: _size.width > 1100 - ? EdgeInsets.only(left: 150, right: 150) + ? EdgeInsets.only(left: 20, right: 20) : null, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Container( - child: InkWell( - onTap: - toggleLoginType, // Call the toggleLoginType function on tap - child: Container( - // Add your text here - child: Text( - 'HR Login', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Color(0xFF00989E)), - ), - alignment: Alignment - .centerRight, // Add padding - ), - ), - ), - _size.width <= 1100 - ? Image.asset( - 'assets/Nhance-Logo-Final-mobile.png', - width: 150, - height: 150, - ) - : _size.width > 1100 - ? Image.asset( - 'assets/Nhance-Logo-Final 1.png', - width: 150, - height: 150, - ) - : Image.asset( - 'assets/Nhance-Logo-Final 1.png', - width: 150, - height: 150, + Row( + children: [ + Expanded( + flex: 6, + child: Align( + alignment: Alignment + .centerLeft, // Align to the start + child: _size.width <= 1100 + ? Image.asset( + 'assets/Nhance-Logo-Final-mobile.png', + width: 150, + height: 150, + ) + : _size.width > 1100 + ? Image.asset( + 'assets/Nhance-Logo-Final 1.png', + width: 150, + height: 150, + ) + : Image.asset( + 'assets/Nhance-Logo-Final 1.png', + width: 150, + height: 150, + ), + )), + Expanded( + flex: 6, + child: Align( + alignment: Alignment.centerRight, + child: ElevatedButton( + onPressed: () { + Navigator.pushNamed( + context, 'hrLogin'); + }, + child: Text( + 'HR login', + style: TextStyle( + color: Color(0xFF00989E)), + ), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular( + 5), + side: BorderSide( + color: Color( + 0xFF00989E)), // Add border + ), + ), ), - SizedBox( - height: _size.width <= 1100 ? 50 : 0, - ), - Text( - "Welcome to Nhance Employee Login", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), + )) + ], ), SizedBox( - height: 10, - ), - Text( - "Have a Health Insurance Policy number, but never signed in? Don't worry, We got you covered", - style: TextStyle( - fontSize: 12, - color: Color(0xFF000000)), - textAlign: TextAlign.center, + height: + 20), // Add some space between rows + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Text( + "Welcome to Nhance", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], ), SizedBox( - height: 30, + height: 15, + ), + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Text( + "Have a Health Insurance Policy number, but never signed in? Don't worry, We got you covered", + style: TextStyle( + fontSize: 12, + color: Color(0xFF000000)), + textAlign: TextAlign.center, + ), + ], + ), + SizedBox( + height: 20, ), Container( height: 55, diff --git a/lib/verify.dart b/lib/verify.dart index 03a6623..51442af 100644 --- a/lib/verify.dart +++ b/lib/verify.dart @@ -108,12 +108,14 @@ class _MyVerifyState extends State { // Store data in local storage (if needed) // SharedPreferences prefs = await SharedPreferences.getInstance(); // await prefs.setString('userData', json.encode(data['data'])); - ToastHelper.showSuccessToast(context, 'Successfully Login'); + // ToastHelper.showSuccessToast(context, 'Successfully Login'); + print('Successfully Login'); // Redirect to another page Navigator.pushNamed(context, 'home'); } else { // Show a Snackbar if the OTP is invalid - ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again'); + // ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again'); + print('Invalid OTP. Please try again'); } } else { throw Exception('Failed to verify OTP'); @@ -121,8 +123,9 @@ class _MyVerifyState extends State { } catch (e) { print('Error: $e'); // Show a Snackbar if there's an error while verifying OTP - ToastHelper.showErrorToast( - context, 'Failed to verify OTP. Please try again.'); + // ToastHelper.showErrorToast( + // context, 'Failed to verify OTP. Please try again.'); + print('Failed to verify OTP. Please try again.'); } } diff --git a/pubspec.yaml b/pubspec.yaml index af66138..1c9cd10 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,7 +46,8 @@ dependencies: file_picker: ^6.2.0 csv: ^6.0.0 data_tables: ^1.4.0 - fluttertoast: ^8.2.4 + universal_html: ^2.2.4 + excel: ^4.0.3 dev_dependencies: