FULL FLOW CODE

This commit is contained in:
Venba 2024-05-28 08:48:53 +05:30
parent 20ae302ab8
commit 88cbcb4e96
56 changed files with 10325 additions and 4328 deletions

View File

@ -1,4 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application <application
android:label="nhancepolicy" android:label="nhancepolicy"
android:name="${applicationName}" android:name="${applicationName}"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 996 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

BIN
assets/Solid_gray.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 B

BIN
assets/Template_File.xlsx Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

After

Width:  |  Height:  |  Size: 146 KiB

BIN
assets/nhance-loader.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
if (token != null && token.isNotEmpty) { if (token != null && token.isNotEmpty) {
if (hrtoken != null && hrtoken.isNotEmpty) { if (hrtoken != null && hrtoken.isNotEmpty) {
prefs.remove('token'); prefs.remove('token');
Navigator.pushNamed(context, 'hrHome'); Navigator.pushNamed(context, 'hrDashboard');
} else { } else {
await prefs.clear(); await prefs.clear();
Navigator.pushNamed(context, 'phone'); Navigator.pushNamed(context, 'phone');
@ -99,11 +99,10 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
Navigator.pushNamed(context, "routeName"); Navigator.pushNamed(context, "routeName");
}, },
), ),
if (Responsive.isDesktop(context))
NavBarItem( NavBarItem(
text: "", text: "Inactive Policy",
onTap: () { onTap: () {
Navigator.pushNamed(context, "routeName"); Navigator.pushNamed(context, 'oldPolicy');
}, },
), ),
NavBarItem( NavBarItem(

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,9 @@ import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:excel/excel.dart'; import 'package:excel/excel.dart';
import 'dart:io'; import 'dart:io';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:csv/csv.dart';
import 'package:spreadsheet_decoder/spreadsheet_decoder.dart';
class excelVerify extends StatefulWidget { class excelVerify extends StatefulWidget {
const excelVerify({Key? key}) : super(key: key); const excelVerify({Key? key}) : super(key: key);
@ -37,13 +40,17 @@ class _excelVerifyState extends State<excelVerify> {
dynamic columnIndexMismatchCount = 0; dynamic columnIndexMismatchCount = 0;
dynamic columnMissingCount = 0; dynamic columnMissingCount = 0;
List<Map<String, dynamic>> extractedData = []; List<Map<String, dynamic>> extractedData = [];
dynamic policyName; dynamic argumentsData;
dynamic policyFirstPart;
List<Map<String, dynamic>> originalData = []; // Original data source List<Map<String, dynamic>> originalData = []; // Original data source
List<Map<String, dynamic>> filteredData = []; // Filtered data source List<Map<String, dynamic>> filteredData = []; // Filtered data source
dynamic client_policy_id;
dynamic policy_name;
dynamic policy_name;
dynamic clientPolicyId;
dynamic clientId;
dynamic policyType;
List<Map<String, dynamic>> nonExcelFilteredData = [];
dynamic invalidRelationships = 0;
dynamic dobAgeCheckCount = 0;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -53,6 +60,7 @@ class _excelVerifyState extends State<excelVerify> {
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();
html.window.localStorage.remove('fileBytes');
} }
Future<void> _loadToken() async { Future<void> _loadToken() async {
@ -64,7 +72,7 @@ class _excelVerifyState extends State<excelVerify> {
}); });
Map<String, dynamic>? decodedToken = Jwt.parseJwt(token); Map<String, dynamic>? decodedToken = Jwt.parseJwt(token);
clintID = decodedToken['client_id'].toString(); clintID = decodedToken['client_id'].toString();
await getPolicyName(clintID); await getPolicyDetails();
} else { } else {
// Token is empty or null, handle accordingly (e.g., navigate to login screen) // Token is empty or null, handle accordingly (e.g., navigate to login screen)
// For now, let's navigate to the login screen // For now, let's navigate to the login screen
@ -73,74 +81,40 @@ class _excelVerifyState extends State<excelVerify> {
} }
} }
Future<void> getPolicyName(String clintID) async { Future<void> getPolicyDetails() async {
setState(() { setState(() {
_isLoading = true; clientPolicyId = argumentsData['client_policy_id'];
clientId = argumentsData['client_id'];
policyType = argumentsData['type'];
policy_name = argumentsData['policy_name'];
}); });
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<String, dynamic> data = json.decode(response.body);
if (data['status'] == 'success') {
print(data);
setState(() {
dataPolicy = List<Map<String, dynamic>>.from(data['data']);
print(dataPolicy);
// Find the object where the 'type' matches the 'policyFirstPart' // Future<void> _uploadFile1(importPolicyName) async {
Map<String, dynamic> matchingPolicy = dataPolicy.firstWhere( // FilePickerResult? result = await FilePicker.platform.pickFiles(
(policy) => policy['type'] == policyFirstPart, // type: FileType.custom,
orElse: () => <String, // allowedExtensions: ['xlsx', 'xls', 'csv'],
dynamic>{} // Return an empty map if no matching policy is found // );
); //
print(matchingPolicy); // if (result != null) {
if (matchingPolicy != null) { // PlatformFile file = result.files.first;
// Matching policy found // Uint8List fileBytes = file.bytes!;
print('Matching Policy: $matchingPolicy'); // // Use the fileBytes as needed
client_policy_id = matchingPolicy['client_policy_id']; // print('File name: ${file.name}');
policy_name = matchingPolicy['policy_name']; // print('File size: ${file.size}');
} else { // print('File bytes: $fileBytes');
// No matching policy found // _processExcelData(fileBytes);
print('No matching policy found for $policyFirstPart'); // } else {
} // // User canceled the picker
// getPolicyNameDetails = dataPolicy[0]['policy_name']; // }
// print(getPolicyNameDetails); // }
// getPolicyNo = dataPolicy[0]['client_policy_id'];
});
print('Successfully Sent');
} else {
ToastHelper.showErrorToast(
context, 'API request failed with status: ${data['status']}');
print('API request failed with status: ${data['status']}');
}
} else {
ToastHelper.showErrorToast(
context, 'Request failed with status: ${response.statusCode}');
print('Request failed with status: ${response.statusCode}');
}
} catch (e) {
print('Exception occurred: $e');
} finally {
setState(() {
_isLoading = false;
});
}
}
void _uploadFile(importPolicyName) async { void _uploadFile(importPolicyName) async {
print('Test'); print('Test');
if (kIsWeb) { if (kIsWeb) {
print('kIsWeb'); print('kIsWeb');
final input = html.FileUploadInputElement(); final input = html.FileUploadInputElement();
input.accept = '.xlsx'; input.accept = '.xlsx,.xls,.csv';
input.click(); input.click();
input.onChange.listen((event) async { input.onChange.listen((event) async {
final file = input.files!.first; final file = input.files!.first;
@ -159,7 +133,7 @@ class _excelVerifyState extends State<excelVerify> {
print('File Name: $fileName'); print('File Name: $fileName');
print('File Bytes: $fileBytes'); print('File Bytes: $fileBytes');
// Call the function to process Excel data here // Call the function to process Excel data here
_processExcelData(fileBytes); _processExcelData(fileBytes, fileName);
} }
} }
}); });
@ -169,20 +143,33 @@ class _excelVerifyState extends State<excelVerify> {
} }
} }
void _processExcelData(Uint8List fileBytes) { void _processExcelData(Uint8List fileBytes, fileName) {
List<List<Data>> dataArray;
if (fileName.endsWith('.xlsx')) {
dataArray = decodeExcelData(fileBytes);
} else if (fileName.endsWith('.xls')) {
dataArray = decodeXLSData(fileBytes);
} else if (fileName.endsWith('.csv')) {
print('csv');
dataArray = decodeCSVData(fileBytes);
} else {
throw UnsupportedError('Unsupported file format: $fileName');
}
print('_processExcelData');
// Decode the Excel file and extract relevant data // Decode the Excel file and extract relevant data
// Assuming dataArray is your array containing Excel data // Assuming dataArray is your array containing Excel data
List<List<Data>> dataArray = decodeExcelData(fileBytes); // List<List<Data>> dataArray = decodeExcelData(fileBytes);
print(dataArray);
// print(dataArray[0].toString()); // print(dataArray[0].toString());
// Extract Name, Age, and City from the array // Extract Name, Age, and City from the array
print(dataArray[0].length); print(dataArray[0].length);
if (dataArray[0].length == 10) { if (dataArray[0].length == 11) {
for (int i = 0; i < dataArray.length; i++) { for (int i = 0; i < dataArray.length; i++) {
Map<String, dynamic> dataMap = { Map<String, dynamic> dataMap = {
"Sno": dataArray[i][0].value, "Sno": dataArray[i][0].value,
"emp_code": dataArray[i][1].value, "Emp_Code": dataArray[i][1].value,
"Name": dataArray[i][2].value, "Name": dataArray[i][2].value,
"DOJ": dataArray[i][3].value, "DOJ": dataArray[i][3].value,
"Gender": dataArray[i][4].value, "Gender": dataArray[i][4].value,
@ -191,6 +178,7 @@ class _excelVerifyState extends State<excelVerify> {
"Mail": dataArray[i][7].value, "Mail": dataArray[i][7].value,
"Mobile": dataArray[i][8].value, "Mobile": dataArray[i][8].value,
"SI": dataArray[i][9].value, "SI": dataArray[i][9].value,
"Grade": dataArray[i][10].value,
}; };
if (i == 0) { if (i == 0) {
// print(dataMap); // print(dataMap);
@ -203,47 +191,79 @@ class _excelVerifyState extends State<excelVerify> {
// Do something with extracted data (e.g., display in UI) // Do something with extracted data (e.g., display in UI)
originalData = extractedData; originalData = extractedData;
filteredData = List.from(originalData); filteredData = List.from(originalData);
print('filteredData');
print(filteredData); print(filteredData);
print(validationArray); print(validationArray);
validationArray[0].forEach((key, value) { validationArray[0].forEach((key, value) {
print(key); print(key);
print(value); print(value);
if (key.toString() != value.toString()) { if (key.toString().trim().toLowerCase() !=
value.toString().trim().toLowerCase()) {
// If key and value are not equal, increment mismatch count // If key and value are not equal, increment mismatch count
columnIndexMismatchCount++; columnIndexMismatchCount++;
print('columnIndexMismatchCount: $value');
} }
if (value.toString() == 'null') { if (value.toString() == 'null') {
// If value is null, increment missing count // If value is null, increment missing count
columnMissingCount++; columnMissingCount++;
print('Value: $value');
} }
}); });
print('columnIndexMismatchCount: $columnIndexMismatchCount'); print('columnIndexMismatchCount: $columnIndexMismatchCount');
print('columnMissingCount: $columnMissingCount'); print('columnMissingCount: $columnMissingCount');
nonExcelFilteredData = filteredData.where((item) {
final relation = item['Relation'];
return relation != null &&
relation.toString().trim().toLowerCase() != 'self';
}).toList();
print('nonExcelFilteredData');
print(nonExcelFilteredData);
print(nonExcelFilteredData.length);
if (argumentsData['type'] == 'GPA') {
if (nonExcelFilteredData.length > 0) {
print('nonSelf');
invalidRelationships = nonExcelFilteredData.length;
} else {
print('Self');
invalidRelationships = nonExcelFilteredData.length;
}
print('invalidRelationships: $invalidRelationships');
} else {
invalidRelationships = 0;
}
int invalidDobCount = countInvalidDobs(filteredData);
print('Number of invalid DOBs: $invalidDobCount');
dobAgeCheckCount = invalidDobCount;
} else { } else {
print('Some Column is Missing'); print('Some Column is Missing');
var columnMissingCount = 10 - dataArray[0].length; var columnMissingCount = 11 - dataArray[0].length;
missingColumnErrorMsg = columnMissingCount; missingColumnErrorMsg = columnMissingCount;
print(missingColumnErrorMsg); print(missingColumnErrorMsg);
} }
} }
// bool checkAllSelf(List<Map<String, dynamic>> dataList) {
// // Check if any value of 'Relation' key is not 'Self'
// bool allSelf = dataList.every((data) => data['Relation'] == 'Self');
// // If all values are 'Self', return true; otherwise, return false
// return allSelf;
// }
// Placeholder function for decoding Excel data // Placeholder function for decoding Excel data
List<List<Data>> decodeExcelData(Uint8List fileBytes) { List<List<Data>> decodeExcelData(Uint8List fileBytes) {
// Implement your logic to decode Excel data here print('decodeExcelData');
// 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 // Create an Excel instance from the fileBytes
final excel = Excel.decodeBytes(fileBytes); final excel = Excel.decodeBytes(fileBytes);
print('decodeExcelData');
print(excel);
// Assuming there's only one sheet in the Excel file // Assuming there's only one sheet in the Excel file
final sheet = excel.tables.keys.first; final sheet = excel.tables.keys.first;
@ -263,6 +283,72 @@ class _excelVerifyState extends State<excelVerify> {
return dataArray; return dataArray;
} }
List<List<Data>> decodeXLSData(Uint8List fileBytes) {
final Excel excelData = Excel.decodeBytes(fileBytes);
final sheet = excelData.tables.keys.first;
final table = excelData.tables[sheet]!;
List<List<Data>> dataArray = [];
for (int rowIdx = 0; rowIdx < table.rows.length; rowIdx++) {
List<Data> 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;
}
List<List<Data>> decodeCSVData(Uint8List fileBytes) {
String csvString = utf8.decode(fileBytes);
List<List<dynamic>> csvData = const CsvToListConverter().convert(csvString);
List<List<Data>> dataArray = [];
// Skip the header row (if it exists) and start from index 1
for (int i = 1; i < csvData.length; i++) {
List<Data> rowData = [];
for (int j = 0; j < csvData[i].length; j++) {
// Assuming the CSV data is of type String
rowData.add(Data(csvData[i][j].toString(), i, j, 'Sheet1'));
}
dataArray.add(rowData);
}
return dataArray;
}
int countInvalidDobs(List<Map<String, dynamic>> data) {
int invalidCount = 0;
for (var entry in data) {
DateTime dob;
// if (entry['DOB'] is String) {
dob = DateTime.parse(entry['DOB'].toString());
// } else if (entry['DOB'] is DateTime) {
// dob = entry['DOB'];
// } else {
// // Invalid DOB format, skip this entry
// continue;
// }
print(entry['Relation']);
if ((entry['Relation'].toString() == 'Son' ||
entry['Relation'].toString() == 'Daughter')) {
if (DateTime.now().difference(dob).inDays > 25 * 365) {
print('child $dob');
invalidCount++;
}
} else if ((entry['Relation'] != 'Son' &&
entry['Relation'] != 'Daughter')) {
if (DateTime.now().difference(dob).inDays < 18 * 365) {
print('others $dob');
invalidCount++;
}
}
}
return invalidCount;
}
void _dragAndDropFile(html.File file) async { void _dragAndDropFile(html.File file) async {
print('file'); print('file');
print(file); print(file);
@ -287,10 +373,13 @@ class _excelVerifyState extends State<excelVerify> {
final decodedBytes = json.decode(jsonString); final decodedBytes = json.decode(jsonString);
if (decodedBytes is List<dynamic>) { if (decodedBytes is List<dynamic>) {
setState(() { setState(() {
fileName = 'Retrieved File'; // Provide a default name fileName = fileName ??
'Retrieved File'; // Provide a default name if fileName is null
}); });
sendExcelFIleTOAPI( sendExcelFIleTOAPI(
Uint8List.fromList(decodedBytes.cast<int>()), fileName!); Uint8List.fromList(decodedBytes.cast<int>()),
fileName!,
);
} }
} }
} }
@ -301,46 +390,68 @@ class _excelVerifyState extends State<excelVerify> {
if (fileBytes == null) { if (fileBytes == null) {
print('return'); print('return');
return; // No file selected return; // No file selected
} } else {
print('else');
// // Prepare form data // // Prepare form data
// final formData = html.FormData(); // final formData = html.FormData();
// formData.appendBlob('file', html.Blob([fileBytes]), fileName); // formData.appendBlob('file', html.Blob([fileBytes]), fileName);
// URL of the API where you want to send the file // URL of the API where you want to send the file
final apiUrl = Environment.apiUrl + 'employeeUpload'; final apiUrl = Environment.apiUrl + 'employeeUpload';
print('else');
// Create a multipart request // Create a multipart request
final request = http.MultipartRequest('POST', Uri.parse(apiUrl)); final request = http.MultipartRequest('POST', Uri.parse(apiUrl));
print('else');
// Attach the file to the request // Attach the file to the request
// Set authorization token in headers // Set authorization token in headers
request.headers['Authorization'] = 'Bearer $_token'; request.headers['Authorization'] = 'Bearer $_token';
request.files.add(http.MultipartFile.fromBytes('file', fileBytes, // request.files.add(http.MultipartFile.fromBytes('file', fileBytes,
filename: fileName)); // Specify filename here // filename: fileName));
print('Filename: $fileName');
request.files.add(http.MultipartFile.fromBytes(
'file',
fileBytes,
filename: fileName ?? 'default_filename.xlsx',
));
print('clintID: $clintID');
request.fields['client_id'] = clintID; request.fields['client_id'] = clintID;
print('clientPolicyId: $clientPolicyId');
// if (policyFirstPart == 'GPA') { // if (policyFirstPart == 'GPA') {
request.fields['policy_id'] = client_policy_id; request.fields['policy_id'] = clientPolicyId;
// } else { // } else {
// request.fields['policy_id'] = '3'; // request.fields['policy_id'] = '3';
// } // }
print('request : $request');
// Send the request // Send the request
final response = await request.send(); final response = await request.send();
print('else');
// Read response stream as a string
final responseString = await response.stream.bytesToString();
print('else');
// Check the status code of the response // Check the status code of the response
if (response.statusCode == 200) { if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(responseString);
if (data['status'] == 'success') {
html.window.localStorage.remove('fileBytes');
// ToastHelper.showSuccessToast(context, 'File uploaded successfully'); // ToastHelper.showSuccessToast(context, 'File uploaded successfully');
ToastHelper.showSuccessToast(context, 'Data Successfully Send...'); ToastHelper.showSuccessToast(
print('File uploaded successfully'); context, 'Data Successfully Imported...');
Navigator.pushNamed(context, 'hrHome'); print('Data Successfully Imported');
Navigator.pushNamed(context, 'hrPolicyDetails',
arguments: argumentsData);
} else {
// ToastHelper.showSuccessToast(context, 'File uploaded successfully');
ToastHelper.showErrorToast(context, 'Failed to Imported...');
// Navigator.pushNamed(context, 'hrHome');
}
} else { } else {
// ToastHelper.showSuccessToast( // ToastHelper.showSuccessToast(
// context, 'Failed to upload file: ${response.reasonPhrase}'); // context, 'Failed to upload file: ${response.reasonPhrase}');
ToastHelper.showSuccessToast( ToastHelper.showSuccessToast(context, 'Something went wrong');
context, 'Failed to send data: ${response.reasonPhrase}');
print('Failed to upload file: ${response.reasonPhrase}'); print('Failed to upload file: ${response.reasonPhrase}');
} }
} }
}
void search(String query) { void search(String query) {
setState(() { setState(() {
@ -351,20 +462,54 @@ class _excelVerifyState extends State<excelVerify> {
// Filter the data based on the search query // Filter the data based on the search query
filteredData = originalData.where((item) { filteredData = originalData.where((item) {
// Implement your filter logic here, for example: // Implement your filter logic here, for example:
return item['emp_code'].toLowerCase().contains(query.toLowerCase()); return item['Emp_Code'].toLowerCase().contains(query.toLowerCase());
}).toList(); }).toList();
} }
}); });
} }
downloadSampleFile() {
final anchor = html.AnchorElement(href: 'assets/assets/Template_File.xlsx');
anchor.download = 'Template_File.xlsx'; // Set the filename
anchor.click(); // Trigger a click on the anchor element
}
resetErrorCount() {
setState(() {
fileBytes = null;
fileName = null;
_currentStep = 0;
extractedData = [];
originalData = [];
filteredData = [];
validationArray = [];
nonExcelFilteredData = [];
print('filteredData');
print(filteredData);
print(validationArray);
missingColumnErrorMsg = 0;
print(missingColumnErrorMsg);
columnMissingCount = 0;
print(columnMissingCount);
columnIndexMismatchCount = 0;
print(columnIndexMismatchCount);
invalidRelationships = 0;
dobAgeCheckCount = 0;
html.window.localStorage.remove('fileBytes');
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// Retrieve the passed argument dynamic arguments = ModalRoute.of(context)!.settings.arguments;
dynamic importPolicyName = print('arguments');
ModalRoute.of(context)!.settings.arguments as String?; print(arguments);
if (arguments != null && arguments is Map<String, dynamic>) {
// List<String> parts = importPolicyName.split(" - "); argumentsData = arguments;
policyFirstPart = importPolicyName; }
return Scaffold( return Scaffold(
appBar: CustomAppBar(), appBar: CustomAppBar(),
@ -395,16 +540,73 @@ class _excelVerifyState extends State<excelVerify> {
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: <Widget>[
ElevatedButton(
onPressed: () {
html.window.localStorage.remove('fileBytes');
fileBytes = null;
fileName = null;
_currentStep = 0;
missingColumnErrorMsg = 0;
columnIndexMismatchCount = 0;
columnMissingCount = 0;
invalidRelationships = 0;
dobAgeCheckCount = 0;
nonExcelFilteredData = [];
Navigator.pushNamed(
context, 'hrPolicyDetails',
arguments: argumentsData);
},
child: Text(
'Close',
style: TextStyle(color: Color(0xFFE26728)),
),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
side: BorderSide(color: Color(0xFFE26728)),
),
),
),
// SizedBox(width: 10),
// if (fileName != null)
// ElevatedButton(
// onPressed: () {
// // Reset localStorage and fileBytes
// setState(() {
// html.window.localStorage
// .remove('fileBytes');
// fileBytes = null;
// fileName = null;
// _currentStep = 0;
// });
// },
// child: Text(
// 'Reselect File',
// style: TextStyle(color: Color(0xFFE26728)),
// ),
// style: ElevatedButton.styleFrom(
// backgroundColor: Colors.white,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(5),
// side:
// BorderSide(color: Color(0xFFE26728)),
// ),
// ),
// ),
Spacer(),
SizedBox(
width:
10), // This pushes the buttons to the right
if (_currentStep != 0) if (_currentStep != 0)
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
controls controls.onStepCancel!();
.onStepCancel!(); // Call onStepCancel function
}, },
child: Text( child: Text(
'Cancel', 'Previous',
style: TextStyle(color: Color(0xFFE26728)), style: TextStyle(color: Color(0xFFE26728)),
), ),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
@ -419,10 +621,19 @@ class _excelVerifyState extends State<excelVerify> {
SizedBox(width: 10), SizedBox(width: 10),
if (_currentStep != 2) if (_currentStep != 2)
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: _currentStep == 0
controls ? (fileName != null
.onStepContinue!(); // Call onStepContinue function ? controls.onStepContinue!
}, : null)
: (_currentStep == 1
? (missingColumnErrorMsg == 0 &&
columnIndexMismatchCount ==
0 &&
invalidRelationships == 0 &&
dobAgeCheckCount == 0
? controls.onStepContinue!
: null)
: null),
child: const Text( child: const Text(
'NEXT', 'NEXT',
style: TextStyle(color: Colors.white), style: TextStyle(color: Colors.white),
@ -468,7 +679,9 @@ class _excelVerifyState extends State<excelVerify> {
} else if (_currentStep == 1) { } else if (_currentStep == 1) {
// For the second step, allow continue if both errors are 0 // For the second step, allow continue if both errors are 0
if (missingColumnErrorMsg == 0 && if (missingColumnErrorMsg == 0 &&
columnIndexMismatchCount == 0) { columnIndexMismatchCount == 0 &&
invalidRelationships == 0 &&
dobAgeCheckCount == 0) {
setState(() { setState(() {
_currentStep += 1; _currentStep += 1;
}); });
@ -513,7 +726,7 @@ class _excelVerifyState extends State<excelVerify> {
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
policy_name ?? '', '$policy_name - ($policyType)',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 20,
@ -558,26 +771,92 @@ class _excelVerifyState extends State<excelVerify> {
MainAxisAlignment MainAxisAlignment
.center, .center,
children: [ children: [
if (fileName == null) // if (fileName == null)
Text( // ElevatedButton(
'Drop files here to start uploading', // onPressed: () => {},
style: TextStyle( // child: Icon(
fontSize: 16), // Icons.download,
), // color: Colors
SizedBox(height: 20), // .grey), // You can replace the Icon with your custom button child
if (fileName == null) // style:
Text( // ElevatedButton
'OR', // .styleFrom(
style: TextStyle( // shape:
fontSize: 16), // CircleBorder(), // Makes the button round
), // Add spacing between texts // padding:
SizedBox(height: 20), // EdgeInsets.all(
// 18), // Change the button color as needed
// ),
// ),
// SizedBox(height: 20),
// if (fileName == null)
// Text(
// 'Drag and drop file to import',
// style: TextStyle(
// fontSize: 16,
// fontWeight:
// FontWeight
// .w600),
// ), // Add spacing between texts
// SizedBox(height: 20),
fileName != null fileName != null
? Text( ? Column(
'File Uploaded: $fileName', mainAxisAlignment:
MainAxisAlignment
.center,
children: [
Icon(
Icons
.upload_file, // Choose the appropriate icon
size: 35,
color: Color(
0xFFE26728), // Adjust the size as needed
),
SizedBox(
height:
15), // Add some space between the icon and text
Text(
'$fileName',
style: TextStyle( style: TextStyle(
fontSize: fontSize:
16), 16),
),
SizedBox(
height:
25), // Add some space between the icon and text
MouseRegion(
cursor: SystemMouseCursors
.click, // Set cursor to pointer on hover
child:
GestureDetector(
onTap:
() {
resetErrorCount();
},
child:
Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Icon(
Icons.delete_forever, // Choose the remove icon
size:
20, // Adjust the size as needed
color:
Colors.red, // Set the color of the remove icon
),
SizedBox(
width: 1), // Add some space between the icon and text
Text(
'Remove',
style:
TextStyle(fontSize: 13, color: Color(0xFF727272)),
),
],
),
),
)
],
) )
: ElevatedButton( : ElevatedButton(
onPressed: () => onPressed: () =>
@ -596,6 +875,10 @@ class _excelVerifyState extends State<excelVerify> {
0xFFE26728), 0xFFE26728),
), ),
), ),
SizedBox(height: 20),
if (fileName == null)
Text(
'Supported Files : XLSX')
// Add more Text widgets for additional lines of text // Add more Text widgets for additional lines of text
], ],
), ),
@ -606,6 +889,43 @@ class _excelVerifyState extends State<excelVerify> {
), ),
], ],
), ),
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(
'Ensure that the import file is in the correct format by comparing it with our template file.',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontWeight:
FontWeight.w400,
)),
MouseRegion(
cursor:
SystemMouseCursors.click,
child: GestureDetector(
onTap: () {
downloadSampleFile();
},
child: Text(
'Template File',
style: TextStyle(
fontSize: 15,
color: Color(
0xFFE26728), // Add underline decoration
),
),
),
)
]))
],
)
], ],
), ),
), ),
@ -634,7 +954,7 @@ class _excelVerifyState extends State<excelVerify> {
missingColumnErrorMsg == 0 missingColumnErrorMsg == 0
? Icons.check_circle ? Icons.check_circle
: Icons.error, : Icons.error,
'No of column missing - $missingColumnErrorMsg', 'No of column missing : $missingColumnErrorMsg Column',
iconColor: missingColumnErrorMsg == 0 iconColor: missingColumnErrorMsg == 0
? Colors.green ? Colors.green
: Colors : Colors
@ -645,20 +965,29 @@ class _excelVerifyState extends State<excelVerify> {
columnIndexMismatchCount == 0 columnIndexMismatchCount == 0
? Icons.check_circle ? Icons.check_circle
: Icons.error, : Icons.error,
'Column Index is Missmatching - $columnIndexMismatchCount', 'Mismatch in Column Order : $columnIndexMismatchCount - Column',
iconColor: columnIndexMismatchCount == 0 iconColor: columnIndexMismatchCount == 0
? Colors.green ? Colors.green
: Colors.red, : Colors.red,
), ),
// _buildRowWithIcon( _buildRowWithIcon(
// columnMissingCount == 0 invalidRelationships == 0
// ? Icons.check_circle ? Icons.check_circle
// : Icons.error, : Icons.error,
// 'Column Missing - $columnMissingCount', 'Invalid Relationships : $invalidRelationships - Rows',
// iconColor: columnMissingCount == 0 iconColor: invalidRelationships == 0
// ? Colors.green ? Colors.green
// : Colors.red, : Colors.red,
// ), ),
_buildRowWithIcon(
dobAgeCheckCount == 0
? Icons.check_circle
: Icons.error,
'Age Config - $dobAgeCheckCount - Rows',
iconColor: dobAgeCheckCount == 0
? Colors.green
: Colors.red,
),
], ],
), ),
), ),
@ -773,7 +1102,7 @@ class _excelVerifyState extends State<excelVerify> {
return Card( return Card(
elevation: 0, // Set elevation to 0 for no shadow elevation: 0, // Set elevation to 0 for no shadow
child: PaginatedDataTable( child: PaginatedDataTable(
rowsPerPage: 10, // Adjust rows per page as needed rowsPerPage: 25, // Adjust rows per page as needed
columns: [ columns: [
DataColumn(label: Text('S.No')), DataColumn(label: Text('S.No')),
DataColumn(label: Text('Employee ID')), DataColumn(label: Text('Employee ID')),
@ -785,6 +1114,7 @@ class _excelVerifyState extends State<excelVerify> {
DataColumn(label: Text('Mail')), DataColumn(label: Text('Mail')),
DataColumn(label: Text('Mobile No')), DataColumn(label: Text('Mobile No')),
DataColumn(label: Text('SI')), DataColumn(label: Text('SI')),
DataColumn(label: Text('Grade')),
], ],
source: _DependenceDataSource0(filteredData), source: _DependenceDataSource0(filteredData),
), ),
@ -824,20 +1154,21 @@ class _DependenceDataSource0 extends DataTableSource {
DataRow getRow(int index) { DataRow getRow(int index) {
final row = _data[index]; final row = _data[index];
// Format date of birth to "July 10, 1996" String dob = row['DOB'] != null ? formatDate(row['DOB']) : 'N/A';
String dob = row['dob'] != null ? formatDateString(row['dob']) : 'N/A'; String doj = row['DOJ'] != null ? formatDate(row['DOJ']) : 'N/A';
return DataRow(cells: [ return DataRow(cells: [
DataCell(Text(row['Sno'].toString())), DataCell(Text(row['Sno'].toString())),
DataCell(Text(row['emp_code'].toString())), DataCell(Text(row['Emp_Code'].toString())),
DataCell(Text(row['Name'].toString())), DataCell(Text(row['Name'].toString())),
DataCell(Text(row['DOJ']?.toString() ?? 'N/A')), DataCell(Text(doj)),
DataCell(Text(row['Gender']?.toString() ?? 'N/A')), DataCell(Text(row['Gender']?.toString() ?? 'N/A')),
DataCell(Text(row['Relation']?.toString() ?? 'N/A')), DataCell(Text(row['Relation']?.toString() ?? 'N/A')),
DataCell(Text(dob)), DataCell(Text(dob)),
DataCell(Text(row['Mail']?.toString() ?? 'N/A')), DataCell(Text(row['Mail']?.toString() ?? 'N/A')),
DataCell(Text(row['Mobile']?.toString() ?? 'N/A')), DataCell(Text(row['Mobile']?.toString() ?? 'N/A')),
DataCell(Text(row['SI']?.toString() ?? 'N/A')), DataCell(Text(row['SI']?.toString() ?? 'N/A')),
DataCell(Text(row['Grade']?.toString() ?? 'N/A')),
]); ]);
} }
@ -850,12 +1181,18 @@ class _DependenceDataSource0 extends DataTableSource {
@override @override
int get selectedRowCount => 0; int get selectedRowCount => 0;
String formatDateString(String dateString) { String formatDate(dynamic dateValue) {
// Parse the date string to DateTime object if (dateValue is String) {
DateTime dateTime = DateTime.parse(dateString); // If the date is already in string format
// Format the DateTime object to "July 03, 2024" DateTime dateTime = DateTime.parse(dateValue);
String formattedDate = DateFormat.yMMMMd().format(dateTime); return DateFormat('dd-MM-yyyy').format(dateTime);
} else if (dateValue is DateCellValue) {
return formattedDate; // If dateValue is an instance of DateCellValue
return DateFormat('dd-MM-yyyy')
.format(DateTime.parse(dateValue.toString()));
} else {
// Handle other cases or null values
return 'N/A';
}
} }
} }

845
lib/hrDashboard.dart Normal file
View File

@ -0,0 +1,845 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:jwt_decode/jwt_decode.dart';
import 'package:nhancepolicy/models/environment.dart';
import 'package:nhancepolicy/responsive.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import 'customAppBar/customAppBar.dart';
import 'customAppBar/toastHelper.dart';
import 'package:universal_html/html.dart' as html;
import 'package:intl/intl.dart';
class hrDashboard extends StatefulWidget {
const hrDashboard({Key? key}) : super(key: key);
@override
State<hrDashboard> createState() => _hrDashboardState();
}
class _hrDashboardState extends State<hrDashboard> {
bool isLoading = true;
late String _token;
dynamic getPolicyNo;
bool _isLoading = false;
dynamic getPolicyNameDetails;
dynamic clintID;
dynamic policy_name;
dynamic getCardArrays = [];
dynamic clientName;
dynamic clientLogo;
final List<Color> cardColors = [
Color(0xFFFFE3D9),
Color(0xFFFFD9EE),
Color(0xFFDBFFDE),
Color(0xFFE4DFFF),
];
@override
void initState() {
super.initState();
_loadToken();
Future.delayed(Duration(seconds: 3), () {
setState(() {
isLoading = false;
});
});
}
@override
void dispose() {
super.dispose();
}
Future<void> _loadToken() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final token = prefs.getString('hrtoken');
if (token != null && token.isNotEmpty) {
setState(() {
_token = token;
});
Map<String, dynamic>? decodedToken = Jwt.parseJwt(token);
clintID = decodedToken['client_id'].toString();
print(clintID);
if (prefs.containsKey('clientLogo') && prefs.containsKey('clientName')) {
clientLogo = prefs.getString('clientLogo');
clientName = prefs.getString('clientName');
} else {
getClientLogoAndDetails();
}
await getCashDepositDetails(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<void> getClientLogoAndDetails() async {
var url =
Uri.parse(Environment.apiUrl + 'getClientDetails?client_id=$clintID');
try {
var response = await http.get(
url,
headers: {
'Authorization':
'Bearer $_token', // Add token to the Authorization header
},
);
if (response.statusCode == 200) {
print('response.statusCode == 200');
Map<String, dynamic> data = json.decode(response.body);
print(data);
if (data.containsKey('data')) {
dynamic clientDetails = data['data'];
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('clientLogo', clientDetails['client']['client_logo']);
prefs.setString('clientName', clientDetails['client']['client_name']);
setState(() {
// dynamic clientDetails = data['data'];
// print(clientDetails);
clientName = clientDetails['client']['client_name'];
print(clientName);
clientLogo = clientDetails['client']['client_logo'];
print(clientLogo);
});
} else {
// Handle other status messages if needed
// ToastHelper.showErrorToast(
// context, 'API request failed with status: ${data['status']}');
print('API request failed with status: ${data['status']}');
}
} else {
// Handle other status codes
// ToastHelper.showErrorToast(
// context, 'Request failed with status: ${response.statusCode}');
print('Request failed with status: ${response.statusCode}');
}
} catch (e) {
// Handle exceptions
print('Exception occurred: $e');
}
}
Future<void> getCashDepositDetails(String clintID) async {
setState(() {
_isLoading = true;
});
var url = Uri.parse(
Environment.apiUrl + 'getCashDepositData?client_id=' + clintID);
try {
var response = await http.get(
url,
headers: {
'Authorization': 'Bearer $_token',
},
);
if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body);
if (data['status'] == 'success') {
setState(() {
getCardArrays = List<Map<String, dynamic>>.from(data['data']);
print(getCardArrays);
});
} else {
// No matching policy found
print('No matching policy found for');
}
} else {
print('API request failed with status');
}
} catch (e) {
print('Exception occurred: $e');
}
}
Future<void> downloadExcel(clintId, clintIdclintId, insurerName) async {
// API endpoint to download the Excel file
// Send GET request to the API
var url = Uri.parse(Environment.apiUrl +
'exportCashDepositData?client_id=$clintId&insurer_id=$clintIdclintId');
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', '$insurerName.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) {
if (getCardArrays == []) {
return Scaffold(
appBar: CustomAppBar(),
body: SingleChildScrollView(
child: Container(
color: Color(0xFFEFF3F6),
child: Column(
children: [
Center(
child: Text('No Data Available'),
)
],
),
),
));
} else {
int numCards = getCardArrays.length;
int numExpanded = numCards < 4 ? numCards : 4;
double cardHeight = MediaQuery.of(context).size.height / 4.5;
double policyHeight = MediaQuery.of(context).size.height / 4.5;
double cardWidth = MediaQuery.of(context).size.width / 6;
return Scaffold(
appBar: CustomAppBar(),
body: Stack(children: [
SingleChildScrollView(
child: Container(
padding:
EdgeInsets.only(top: 30, bottom: 30, left: 50, right: 50),
color: Color(0xFFEFF3F6),
child: Column(
children: [
Card(
elevation: 0,
child: Container(
width: double.infinity,
height: 75,
padding: Responsive.isDesktop(context)
? EdgeInsets.only(
top: 10, bottom: 10, left: 20, right: 20)
: EdgeInsets.only(
top: 12,
bottom: 12,
left: 10,
right: 10), // Add padding to the container
child: Row(
children: [
Expanded(
flex: 6,
child: Container(
width: 150,
height: 150,
alignment: Alignment.centerLeft,
child: Image.network(
clientLogo ?? '',
width: 80, // Set the width here
height: 80, // Set the height here
loadingBuilder: (BuildContext context,
Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) return child;
return Center(
child: CircularProgressIndicator(
value: loadingProgress
.expectedTotalBytes !=
null
? loadingProgress
.cumulativeBytesLoaded /
loadingProgress
.expectedTotalBytes!
: null,
),
);
},
errorBuilder: (BuildContext context,
Object error, StackTrace? stackTrace) {
return Image.asset(
'assets/Solid_gray.png', // Replace 'default_image.png' with your default image asset path
width: 80,
height: 80,
fit: BoxFit.cover,
);
},
),
),
),
Expanded(
flex: 9,
child: Text(
clientName ?? '',
textAlign: TextAlign.right,
style: GoogleFonts.poppins(
fontSize:
Responsive.isDesktop(context) ? 20 : 18,
fontWeight: FontWeight.w600,
),
),
)
],
),
),
),
SizedBox(height: 16),
Card(
elevation: 0,
child: Container(
width: double.infinity,
padding: Responsive.isDesktop(context)
? EdgeInsets.all(20)
: EdgeInsets.all(
10), // Add padding to the container
child: Column(children: [
Row(children: [
Text(
'Cash Transaction',
style: GoogleFonts.poppins(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Colors.black,
),
)
]),
SizedBox(height: 8),
Row(
children: [
// Create an Expanded widget with flex of 4 for each card
for (var cardData in getCardArrays)
Container(
width:
300, // Set a fixed width for the card
height: cardHeight,
child: Card(
elevation: 3,
color: cardColors[
getCardArrays.indexOf(cardData) %
cardColors.length],
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
ListTile(
title: SizedBox(
height: 50,
child: Text(
cardData['insurerName'],
style: GoogleFonts.poppins(
fontSize: 18,
fontWeight: FontWeight.w500,
color: Color(0xFF000000),
height: 1.5,
),
),
),
subtitle: Text(
'Balance: ₹ ${cardData['balance']}',
style: GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
height: 1.5,
),
),
),
SizedBox(height: 10),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 15),
child: GestureDetector(
onTap: () {
openForm(
cardData['depositData'],
cardData['insurerName'],
cardData['clientId'],
cardData['insurerId'],
cardColors[getCardArrays
.indexOf(cardData) %
cardColors.length],
);
},
child: MouseRegion(
cursor:
SystemMouseCursors.click,
child: Align(
alignment:
Alignment.centerRight,
child: Text(
'View Details',
style: GoogleFonts.poppins(
color: Color(0xFF000000),
fontSize: 14,
fontWeight:
FontWeight.w300,
height: 1.5,
),
),
),
),
),
),
],
),
),
),
],
),
])),
),
SizedBox(height: 16),
Card(
elevation: 0,
child: Padding(
padding: Responsive.isDesktop(context)
? EdgeInsets.all(20)
: EdgeInsets.all(10),
child: Column(
children: [
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: List.generate(
numExpanded,
(index) {
var insurerName = getCardArrays[index]
['insurerName'];
var policyDetails =
getCardArrays[index]
['policyDetails'];
// Determine the color for the policyDetails based on the index of the card in getCardArrays
var cardColorIndex =
getCardArrays.indexOf(
getCardArrays[index]) %
cardColors.length;
var cardColor =
cardColors[cardColorIndex];
return Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
insurerName,
style: GoogleFonts.poppins(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Colors.black,
),
),
SizedBox(height: 8),
Row(
children: List.generate(
policyDetails.length,
(index) => Container(
width: 300,
height: policyHeight,
child: GestureDetector(
onTap: () {
Navigator.pushNamed(
context,
'hrPolicyDetails',
arguments:
policyDetails[
index]);
},
child: MouseRegion(
cursor:
SystemMouseCursors
.click,
child: Card(
elevation: 3,
color:
cardColor, // Use the determined color
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
ListTile(
title: SizedBox(
height: 50,
child: Text(
'${policyDetails[index]['policy_name']} - (${policyDetails[index]['type']})',
style: GoogleFonts
.poppins(
fontSize:
16,
fontWeight:
FontWeight
.w500,
color: Color(
0xFF000000),
height:
1.5,
),
softWrap:
true, // Allow text to wrap to the next line if needed
),
),
),
SizedBox(
height: 8),
Padding(
padding: EdgeInsets
.only(
left:
15,
right:
15),
child: Row(
children: [
Expanded(
flex: 4,
child:
Column(
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Text(
'Draft',
style:
GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Color(0xFF000000),
height: 1.5,
),
),
Text(
policyDetails[index]['membersCountOfDraft'].toString(),
style:
GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
height: 1.5,
),
),
],
),
),
Expanded(
flex: 4,
child:
Column(
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Text(
'Enrolled',
style:
GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Color(0xFF000000),
height: 1.5,
),
),
Text(
policyDetails[index]['membersCountOfEnrolled'].toString(),
style:
GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
height: 1.5,
),
),
],
),
),
Expanded(
flex: 4,
child:
Column(
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Text(
'Total',
style:
GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Color(0xFF000000),
height: 1.5,
),
),
Text(
policyDetails[index]['totalMembersCount'].toString(),
style:
GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
height: 1.5,
),
),
],
),
),
],
), // Adjust the horizontal padding as needed
)
],
),
),
),
),
),
),
),
SizedBox(height: 20),
],
);
},
),
),
),
],
)
],
),
))
],
),
),
),
if (isLoading)
Container(
color: Color(0xFFFFFCE5), // 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
),
),
]));
}
}
void openForm(dynamic floaterData, dynamic insurerName, dynamic clintId,
dynamic insurerId, dynamic cardColors) {
print(clintId);
print(insurerId);
print(floaterData);
print(floaterData);
print('test');
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 0,
backgroundColor: Colors.transparent,
content: SizedBox(
width: 1000,
child: SingleChildScrollView(
child: Card(
elevation: 0,
child: Column(
children: [
Container(
child: Column(
children: [
Container(
padding:
EdgeInsets.all(10), // Set your desired padding
color:
cardColors, // Set your desired background color
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 10,
child: Container(
alignment: Alignment.centerLeft,
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Text(insurerName ?? '',
style: GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.black,
)),
],
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment
.centerRight, // Align text to the center
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: () {
downloadExcel(
clintId, insurerId, insurerName);
},
child: Icon(
Icons
.download, // Replace with your desired icon
color: Colors
.black, // Replace with your desired icon color
),
),
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment
.centerRight, // Align text to the center
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: () {
Navigator.of(context).pop();
},
child: Icon(
Icons
.close, // Replace with your desired icon
color: Colors
.black, // Replace with your desired icon color
),
),
),
),
),
],
),
),
SizedBox(height: 15),
Row(
children: [
Expanded(
child: SingleChildScrollView(
child: _buildDataTable(context, floaterData),
),
)
],
),
],
),
),
],
),
),
),
),
);
},
);
}
Widget _buildDataTable(BuildContext context, dynamic tableData) {
print('tableData');
print(tableData);
// Check if tableData is a list
if (tableData is List) {
// If tableData is a list and not empty
if (tableData.isNotEmpty && tableData[0] is Map<String, dynamic>) {
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('Date')),
DataColumn(label: Text('Description')),
DataColumn(label: Text('Transaction Type')),
DataColumn(label: Text('Amount')),
DataColumn(label: Text('Balance')),
],
source: _DependenceDataSource(context, tableData),
),
);
} else {
// If tableData is empty or not in the expected format
return Text('No Data Available', textAlign: TextAlign.center);
}
} else {
// If tableData is not a list, return a message indicating invalid data
return Text('Invalid Data Format', textAlign: TextAlign.center);
}
}
}
class _DependenceDataSource extends DataTableSource {
final List<Map<String, dynamic>> _data;
final BuildContext context;
_DependenceDataSource(this.context, List<dynamic> tableData)
: _data = tableData.map((e) => e as Map<String, dynamic>).toList();
@override
DataRow getRow(int index) {
final row = _data[index];
// Format date of birth to "July 10, 1996"
String created_Date =
row['created_at'] != null ? formatDateString(row['created_at']) : 'N/A';
return DataRow(
// Setting row background color
cells: [
DataCell(Text(created_Date)),
DataCell(Text(row['description'] ?? 'N/A')),
DataCell(Text(row['transaction_type'].toString() ?? '')),
DataCell(Text(row['amount'] ?? 'N/A')),
DataCell(Text(row['balance'] ?? 'N/A')),
],
);
}
@override
bool get isRowCountApproximate => false;
@override
int get rowCount => _data.length;
@override
int get selectedRowCount => 0;
String formatDateString(String dateString) {
// Parse the input date string
DateTime inputDate = DateTime.parse(dateString);
// Format the date as DD-MM-YYYY HH:mm A
String formattedDate = DateFormat('dd-MM-yyyy hh:mm a').format(inputDate);
return formattedDate;
}
}

View File

@ -13,8 +13,10 @@ import 'package:universal_html/html.dart' as html;
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:excel/excel.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:excel/excel.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
class MyHrHome extends StatefulWidget { class MyHrHome extends StatefulWidget {
const MyHrHome({Key? key}) : super(key: key); const MyHrHome({Key? key}) : super(key: key);
@ -28,7 +30,8 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
late String _token; late String _token;
List<Map<String, dynamic>> getEmpDependenceByClintIdGMC = []; List<Map<String, dynamic>> getEmpDependenceByClintIdGMC = [];
List<Map<String, dynamic>> getEmpDependenceByClintIdGPA = []; List<Map<String, dynamic>> getEmpDependenceByClintIdGPA = [];
List<Map<String, dynamic>> getEmpDependenceByClintIdAddOns = []; List<Map<String, dynamic>> getEmpDependenceByClintIdAddOnsSi = [];
List<Map<String, dynamic>> getEmpDependenceByClintIdAddOnsDependent = [];
dynamic getPolicyNameDetails0; dynamic getPolicyNameDetails0;
dynamic getPolicyNameDetails1; dynamic getPolicyNameDetails1;
dynamic getPolicyNameDetails2; dynamic getPolicyNameDetails2;
@ -44,13 +47,16 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
List<Map<String, dynamic>> filteredDataGpa = []; // Filtered data source List<Map<String, dynamic>> filteredDataGpa = []; // Filtered data source
List<Map<String, dynamic>> originalDataGmc = []; // Original data source List<Map<String, dynamic>> originalDataGmc = []; // Original data source
List<Map<String, dynamic>> filteredDataGmc = []; // Filtered data source List<Map<String, dynamic>> filteredDataGmc = []; // Filtered data source
List<Map<String, dynamic>> originalDataAddOns = []; // Original data source List<Map<String, dynamic>> originalDataAddOnsSi = []; // Original data source
List<Map<String, dynamic>> filteredDataAddOns = []; List<Map<String, dynamic>> filteredDataAddOnsSi = [];
List<Map<String, dynamic>> originalDataAddOnsDependent =
[]; // Original data source
List<Map<String, dynamic>> filteredDataAddOnsDependent = [];
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_tabController = TabController(length: 3, vsync: this); _tabController = TabController(length: 4, vsync: this);
_loadToken(); _loadToken();
} }
@ -98,7 +104,7 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
setState(() { setState(() {
dataPolicy = List<Map<String, dynamic>>.from(data['data']); dataPolicy = List<Map<String, dynamic>>.from(data['data']);
print(dataPolicy); print(dataPolicy);
reversedDataPolicy = dataPolicy.reversed.toList(); // reversedDataPolicy = dataPolicy.reversed.toList();
// getPolicyNameDetails0 = dataPolicy[0]['policy_name']; // getPolicyNameDetails0 = dataPolicy[0]['policy_name'];
// print(getPolicyNameDetails0); // print(getPolicyNameDetails0);
// getPolicyNameDetails1 = dataPolicy[1]['policy_name']; // getPolicyNameDetails1 = dataPolicy[1]['policy_name'];
@ -113,7 +119,7 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
// print(getPolicyNameDetails2); // print(getPolicyNameDetails2);
}); });
// Code to execute periodically every 2 seconds // Code to execute periodically every 2 seconds
reversedDataPolicy.forEach((policy) { dataPolicy.forEach((policy) {
if (policy['type'] == 'GPA') { if (policy['type'] == 'GPA') {
String clientPolicyId = policy['client_policy_id']; String clientPolicyId = policy['client_policy_id'];
String clientId = policy['client_id']; String clientId = policy['client_id'];
@ -122,11 +128,11 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
String clientPolicyId = policy['client_policy_id']; String clientPolicyId = policy['client_policy_id'];
String clientId = policy['client_id']; String clientId = policy['client_id'];
getEmployeeAndDependenceGMC(clientId, clientPolicyId); getEmployeeAndDependenceGMC(clientId, clientPolicyId);
} else if (policy['type'] == 'AddOn') { } else if (policy['type'] == 'SI TopUp') {
String clientPolicyId = policy['client_policy_id']; String clientPolicyId = policy['client_policy_id'];
String clientId = policy['client_id']; String clientId = policy['client_id'];
getEmployeeAndDependenceAddOnsSi(clientId, clientPolicyId); getEmployeeAndDependenceAddOnsSi(clientId, clientPolicyId);
} else if (policy['type'] == 'AddOn-DEPENDENT') { } else if (policy['type'] == 'Dependent AddOn') {
String clientPolicyId = policy['client_policy_id']; String clientPolicyId = policy['client_policy_id'];
String clientId = policy['client_id']; String clientId = policy['client_id'];
getEmployeeAndDependenceAddOnsDependent(clientId, clientPolicyId); getEmployeeAndDependenceAddOnsDependent(clientId, clientPolicyId);
@ -176,6 +182,8 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
List<Map<String, dynamic>>.from(data['data']); List<Map<String, dynamic>>.from(data['data']);
originalDataGpa = getEmpDependenceByClintIdGPA; originalDataGpa = getEmpDependenceByClintIdGPA;
filteredDataGpa = List.from(originalDataGpa); filteredDataGpa = List.from(originalDataGpa);
print('filteredDataGpa');
print(filteredDataGpa);
}); });
} else { } else {
ToastHelper.showWarningToast( ToastHelper.showWarningToast(
@ -254,10 +262,10 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
Map<String, dynamic> data = json.decode(response.body); Map<String, dynamic> data = json.decode(response.body);
if (data['status'] == 'success') { if (data['status'] == 'success') {
setState(() { setState(() {
getEmpDependenceByClintIdAddOns = getEmpDependenceByClintIdAddOnsSi =
List<Map<String, dynamic>>.from(data['data']); List<Map<String, dynamic>>.from(data['data']);
originalDataAddOns = getEmpDependenceByClintIdAddOns; originalDataAddOnsSi = getEmpDependenceByClintIdAddOnsSi;
filteredDataAddOns = List.from(originalDataAddOns); filteredDataAddOnsSi = List.from(originalDataAddOnsSi);
}); });
} else { } else {
ToastHelper.showErrorToast( ToastHelper.showErrorToast(
@ -296,10 +304,12 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
Map<String, dynamic> data = json.decode(response.body); Map<String, dynamic> data = json.decode(response.body);
if (data['status'] == 'success') { if (data['status'] == 'success') {
setState(() { setState(() {
getEmpDependenceByClintIdAddOns = getEmpDependenceByClintIdAddOnsDependent =
List<Map<String, dynamic>>.from(data['data']); List<Map<String, dynamic>>.from(data['data']);
originalDataAddOns = getEmpDependenceByClintIdAddOns; originalDataAddOnsDependent =
filteredDataAddOns = List.from(originalDataAddOns); getEmpDependenceByClintIdAddOnsDependent;
filteredDataAddOnsDependent =
List.from(originalDataAddOnsDependent);
}); });
} else { } else {
ToastHelper.showErrorToast( ToastHelper.showErrorToast(
@ -328,10 +338,14 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
} else if (importPolicyName == 'GMC') { } else if (importPolicyName == 'GMC') {
// argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails1; // argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails1;
argumentDetails = 'GMC'; argumentDetails = 'GMC';
} else {
// argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails0;
argumentDetails = 'ADDONS';
} }
// 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: argumentDetails); Navigator.pushNamed(context, 'excelVerify', arguments: argumentDetails);
return; return;
@ -383,14 +397,14 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
}); });
} }
void searchAddOns(String query) { void searchAddOnsSi(String query) {
setState(() { setState(() {
if (query.isEmpty) { if (query.isEmpty) {
// If search query is empty, show all data // If search query is empty, show all data
filteredDataAddOns = List.from(originalDataAddOns); filteredDataAddOnsSi = List.from(originalDataAddOnsSi);
} else { } else {
// Filter the data based on the search query // Filter the data based on the search query
filteredDataAddOns = originalDataAddOns.where((item) { filteredDataAddOnsSi = originalDataAddOnsSi.where((item) {
// Implement your filter logic here, for example: // Implement your filter logic here, for example:
return item['emp_code'].toLowerCase().contains(query.toLowerCase()); return item['emp_code'].toLowerCase().contains(query.toLowerCase());
}).toList(); }).toList();
@ -398,6 +412,58 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
}); });
} }
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<void> 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: {
'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
print('Failed to download Excel file: ${response.statusCode}');
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (dataPolicy == []) { if (dataPolicy == []) {
@ -434,16 +500,15 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
), ),
indicatorSize: TabBarIndicatorSize.label, indicatorSize: TabBarIndicatorSize.label,
controller: _tabController, controller: _tabController,
tabs: reversedDataPolicy != null && tabs: dataPolicy != null && dataPolicy.isNotEmpty
reversedDataPolicy.isNotEmpty ? dataPolicy.map((policy) {
? reversedDataPolicy.map((policy) {
return Tab( return Tab(
child: Container( child: Container(
width: double.infinity, width: double.infinity,
alignment: Alignment.center, alignment: Alignment.center,
padding: EdgeInsets.symmetric(vertical: 0), padding: EdgeInsets.symmetric(vertical: 0),
child: Text( child: Text(
'${policy['type']}-${policy['policy_name']}'), '${policy['type']} : ${policy['policy_name']}'),
), ),
); );
}).toList() }).toList()
@ -478,14 +543,17 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
child: _isLoading child: _isLoading
? Center(child: CircularProgressIndicator()) ? Center(child: CircularProgressIndicator())
: Column( : filteredDataGpa.isNotEmpty
? SingleChildScrollView(
child: Column(
children: [ children: [
Row( Row(
children: [ children: [
Expanded( Expanded(
flex: 10, flex: 8,
child: Container( child: Container(
alignment: Alignment.centerLeft, alignment:
Alignment.centerLeft,
child: Container( child: Container(
width: width:
350, // Set your desired width here 350, // Set your desired width here
@ -508,19 +576,23 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
), ),
], ],
borderRadius: borderRadius:
BorderRadius.circular(5), BorderRadius.circular(
5),
), ),
child: TextField( child: TextField(
textAlignVertical: textAlignVertical:
TextAlignVertical TextAlignVertical
.center, // Center the text vertically .center, // Center the text vertically
decoration: InputDecoration( decoration:
InputDecoration(
hintText: 'Search', hintText: 'Search',
suffixIcon: suffixIcon:
Icon(Icons.search), Icon(Icons.search),
contentPadding: EdgeInsets.all( contentPadding:
EdgeInsets.all(
10), // Adjust the horizontal padding 10), // Adjust the horizontal padding
border: OutlineInputBorder( border:
OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: Color( color: Color(
0xFFf5f5f7)), // Set border color to gray 0xFFf5f5f7)), // Set border color to gray
@ -534,7 +606,46 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
Expanded( Expanded(
flex: 2, flex: 2,
child: Container( child: Container(
alignment: Alignment.centerRight, 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( child: Row(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.center, MainAxisAlignment.center,
@ -546,7 +657,8 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
child: Text( child: Text(
'Import Data', 'Import Data',
style: TextStyle( style: TextStyle(
color: Colors.white), color:
Colors.white),
), ),
style: ElevatedButton style: ElevatedButton
.styleFrom( .styleFrom(
@ -556,7 +668,8 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
RoundedRectangleBorder( RoundedRectangleBorder(
borderRadius: borderRadius:
BorderRadius BorderRadius
.circular(5), .circular(
5),
), ),
), ),
), ),
@ -572,12 +685,42 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
child: _buildDataTableGPA(context), 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),
),
),
),
)
],
),
), ),
), ),
), ),
@ -586,14 +729,17 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
child: _isLoading child: _isLoading
? Center(child: CircularProgressIndicator()) ? Center(child: CircularProgressIndicator())
: Column( : filteredDataGmc.isNotEmpty
? SingleChildScrollView(
child: Column(
children: [ children: [
Row( Row(
children: [ children: [
Expanded( Expanded(
flex: 10, flex: 10,
child: Container( child: Container(
alignment: Alignment.centerLeft, alignment:
Alignment.centerLeft,
child: Container( child: Container(
width: width:
350, // Set your desired width here 350, // Set your desired width here
@ -616,19 +762,23 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
), ),
], ],
borderRadius: borderRadius:
BorderRadius.circular(5), BorderRadius
.circular(5),
), ),
child: TextField( child: TextField(
textAlignVertical: textAlignVertical:
TextAlignVertical TextAlignVertical
.center, // Center the text vertically .center, // Center the text vertically
decoration: InputDecoration( decoration:
InputDecoration(
hintText: 'Search', hintText: 'Search',
suffixIcon: suffixIcon: Icon(
Icon(Icons.search), Icons.search),
contentPadding: EdgeInsets.all( contentPadding:
EdgeInsets.all(
10), // Adjust the horizontal padding 10), // Adjust the horizontal padding
border: OutlineInputBorder( border:
OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: Color( color: Color(
0xFFf5f5f7)), // Set border color to gray 0xFFf5f5f7)), // Set border color to gray
@ -642,29 +792,35 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
Expanded( Expanded(
flex: 2, flex: 2,
child: Container( child: Container(
alignment: Alignment.centerRight, alignment:
Alignment.centerRight,
child: Row( child: Row(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.spaceEvenly, MainAxisAlignment
.spaceEvenly,
children: [ children: [
Expanded( Expanded(
child: ElevatedButton( child: ElevatedButton(
onPressed: () => onPressed: () =>
_uploadFile('GMC'), _uploadFile(
'GMC'),
child: Text( child: Text(
'Import', 'Import',
style: TextStyle( style: TextStyle(
color: Colors.white), color: Colors
.white),
), ),
style: ElevatedButton style: ElevatedButton
.styleFrom( .styleFrom(
backgroundColor: backgroundColor:
Color(0xFFE26728), Color(
0xFFE26728),
shape: shape:
RoundedRectangleBorder( RoundedRectangleBorder(
borderRadius: borderRadius:
BorderRadius BorderRadius
.circular(5), .circular(
5),
), ),
), ),
), ),
@ -680,13 +836,44 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
child: _buildDataTableGMC(context), 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( Center(
@ -694,14 +881,17 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
child: _isLoading child: _isLoading
? Center(child: CircularProgressIndicator()) ? Center(child: CircularProgressIndicator())
: Column( : filteredDataAddOnsSi.isNotEmpty
? SingleChildScrollView(
child: Column(
children: [ children: [
Row( Row(
children: [ children: [
Expanded( Expanded(
flex: 10, flex: 10,
child: Container( child: Container(
alignment: Alignment.centerLeft, alignment:
Alignment.centerLeft,
child: Container( child: Container(
width: width:
350, // Set your desired width here 350, // Set your desired width here
@ -724,26 +914,30 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
), ),
], ],
borderRadius: borderRadius:
BorderRadius.circular(5), BorderRadius
.circular(5),
), ),
child: TextField( child: TextField(
textAlignVertical: textAlignVertical:
TextAlignVertical TextAlignVertical
.center, // Center the text vertically .center, // Center the text vertically
decoration: InputDecoration( decoration:
InputDecoration(
hintText: 'Search', hintText: 'Search',
suffixIcon: suffixIcon: Icon(
Icon(Icons.search), Icons.search),
contentPadding: EdgeInsets.all( contentPadding:
EdgeInsets.all(
10), // Adjust the horizontal padding 10), // Adjust the horizontal padding
border: OutlineInputBorder( border:
OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: Color( color: Color(
0xFFf5f5f7)), // Set border color to gray 0xFFf5f5f7)), // Set border color to gray
), ),
), ),
onChanged: onChanged:
searchAddOns, // Call the search method on text change searchAddOnsSi, // Call the search method on text change
), ),
)), )),
), ),
@ -789,13 +983,167 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
child: child:
_buildDataTableAddOns(context), _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),
),
)
],
),
),
), ),
), ),
], ],
@ -817,7 +1165,7 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
return Card( return Card(
elevation: 0, // Set elevation to 0 for no shadow elevation: 0, // Set elevation to 0 for no shadow
child: PaginatedDataTable( child: PaginatedDataTable(
rowsPerPage: 5, // Adjust rows per page as needed rowsPerPage: 25, // Adjust rows per page as needed
columns: [ columns: [
DataColumn(label: Text('Employee ID')), DataColumn(label: Text('Employee ID')),
DataColumn(label: Text('Name')), DataColumn(label: Text('Name')),
@ -840,7 +1188,7 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
return Card( return Card(
elevation: 0, // Set elevation to 0 for no shadow elevation: 0, // Set elevation to 0 for no shadow
child: PaginatedDataTable( child: PaginatedDataTable(
rowsPerPage: 5, // Adjust rows per page as needed rowsPerPage: 25, // Adjust rows per page as needed
columns: [ columns: [
DataColumn(label: Text('Employee ID')), DataColumn(label: Text('Employee ID')),
DataColumn(label: Text('Name')), DataColumn(label: Text('Name')),
@ -855,15 +1203,15 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
} }
} }
Widget _buildDataTableAddOns(context) { Widget _buildDataTableAddOnsSi(context) {
if (filteredDataAddOns.isEmpty) { if (filteredDataAddOnsSi.isEmpty) {
SizedBox(height: 25); SizedBox(height: 25);
return Text('No available data'); return Text('No available data');
} else { } else {
return Card( return Card(
elevation: 0, // Set elevation to 0 for no shadow elevation: 0, // Set elevation to 0 for no shadow
child: PaginatedDataTable( child: PaginatedDataTable(
rowsPerPage: 5, // Adjust rows per page as needed rowsPerPage: 25, // Adjust rows per page as needed
columns: [ columns: [
DataColumn(label: Text('Employee ID')), DataColumn(label: Text('Employee ID')),
DataColumn(label: Text('Name')), DataColumn(label: Text('Name')),
@ -872,7 +1220,30 @@ class _MyHrHomeState extends State<MyHrHome> with TickerProviderStateMixin {
DataColumn(label: Text('Gender')), DataColumn(label: Text('Gender')),
DataColumn(label: Text('Mobile No')), DataColumn(label: Text('Mobile No')),
], ],
source: _DependenceDataSource2(filteredDataAddOns, context), 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),
), ),
); );
} }
@ -897,7 +1268,7 @@ class _DependenceDataSource0 extends DataTableSource {
isClickable = true; // Making 'Self' rows clickable isClickable = true; // Making 'Self' rows clickable
} }
// Format date of birth to "July 10, 1996" // Format date of birth to "July 10, 1996"
String dob = row['dob'] != null ? _formatDate(row['dob']) : 'N/A'; String dob = row['dob'] != null ? formatDateString(row['dob']) : 'N/A';
return DataRow( return DataRow(
color: MaterialStateColor.resolveWith( color: MaterialStateColor.resolveWith(
@ -934,9 +1305,11 @@ class _DependenceDataSource0 extends DataTableSource {
arguments: {'mobile': row['mobile']}); arguments: {'mobile': row['mobile']});
} }
String _formatDate(String date) { String formatDateString(String dateString) {
DateTime parsedDate = DateTime.parse(date); // Parse the date string to DateTime object
String formattedDate = DateFormat.yMMMMd().format(parsedDate); DateTime dateTime = DateTime.parse(dateString);
// Format the DateTime object to "dd-mm-yyyy"
String formattedDate = DateFormat('dd-MM-yyyy').format(dateTime);
return formattedDate; return formattedDate;
} }
} }
@ -960,7 +1333,7 @@ class _DependenceDataSource1 extends DataTableSource {
} }
// Format date of birth to "July 10, 1996" // Format date of birth to "July 10, 1996"
String dob = row['dob'] != null ? _formatDate(row['dob']) : 'N/A'; String dob = row['dob'] != null ? formatDateString(row['dob']) : 'N/A';
return DataRow( return DataRow(
color: MaterialStateColor.resolveWith((states) => rowColor), color: MaterialStateColor.resolveWith((states) => rowColor),
@ -994,9 +1367,12 @@ class _DependenceDataSource1 extends DataTableSource {
arguments: {'mobile': row['mobile']}); arguments: {'mobile': row['mobile']});
} }
String _formatDate(String date) { String formatDateString(String dateString) {
DateTime parsedDate = DateTime.parse(date); // Parse the date string to DateTime object
String formattedDate = DateFormat.yMMMMd().format(parsedDate); DateTime dateTime = DateTime.parse(dateString);
// Format the DateTime object to "dd-mm-yyyy"
String formattedDate = DateFormat('dd-MM-yyyy').format(dateTime);
return formattedDate; return formattedDate;
} }
} }
@ -1020,7 +1396,7 @@ class _DependenceDataSource2 extends DataTableSource {
} }
// Format date of birth to "July 10, 1996" // Format date of birth to "July 10, 1996"
String dob = row['dob'] != null ? _formatDate(row['dob']) : 'N/A'; String dob = row['dob'] != null ? formatDateString(row['dob']) : 'N/A';
return DataRow( return DataRow(
color: MaterialStateColor.resolveWith((states) => rowColor), color: MaterialStateColor.resolveWith((states) => rowColor),
@ -1054,9 +1430,75 @@ class _DependenceDataSource2 extends DataTableSource {
arguments: {'mobile': row['mobile']}); arguments: {'mobile': row['mobile']});
} }
String _formatDate(String date) { String formatDateString(String dateString) {
DateTime parsedDate = DateTime.parse(date); // Parse the date string to DateTime object
String formattedDate = DateFormat.yMMMMd().format(parsedDate); 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<Map<String, dynamic>> _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) {
print(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; return formattedDate;
} }
} }

View File

@ -7,6 +7,9 @@ import 'package:nhancepolicy/models/environment.dart';
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:nhancepolicy/responsive.dart'; import 'package:nhancepolicy/responsive.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:flutter_animated_button/flutter_animated_button.dart';
class MyHrLogin extends StatefulWidget { class MyHrLogin extends StatefulWidget {
const MyHrLogin({Key? key}); const MyHrLogin({Key? key});
@ -24,17 +27,30 @@ class _MyPhoneState extends State<MyHrLogin> {
void initState() { void initState() {
countryController.text = "+91"; countryController.text = "+91";
super.initState(); super.initState();
checkTokenAvailability();
}
Future<void> checkTokenAvailability() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String? hrtoken = prefs.getString('hrtoken');
if (hrtoken != null && hrtoken.isNotEmpty) {
// Token available, navigate to home page
Navigator.pushReplacementNamed(context, 'hrDashboard',
arguments: {'mobile': ''});
}
} }
void toggleLoginType() { void toggleLoginType() {
Navigator.pushNamed(context, 'phone'); // Navigate to another page Navigator.pushNamed(context, 'phone'); // Navigate to another page
} }
Future<bool> verifyMobileNumber(String mobileNumber) async { Future<void> verifyMobileNumber() async {
try { try {
var enteredMobileNumber = mobileController.text;
final response = await http.post( final response = await http.post(
Uri.parse(Environment.apiUrl + 'verifyHrWithMobileNumber'), Uri.parse(Environment.apiUrl + 'verifyHrWithMobileNumber'),
body: json.encode({'mobile_number': mobileNumber}), body: json.encode({'mobile_number': enteredMobileNumber}),
headers: { headers: {
HttpHeaders.contentTypeHeader: 'application/json', HttpHeaders.contentTypeHeader: 'application/json',
}, },
@ -43,34 +59,41 @@ class _MyPhoneState extends State<MyHrLogin> {
if (response.statusCode == 200) { if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body); Map<String, dynamic> data = json.decode(response.body);
bool userVerification = data['data']['user_verification']; bool userVerification = data['data']['user_verification'];
return userVerification; String message = data['data']['message'];
if (userVerification) {
ToastHelper.showSuccessToast(context, message);
Navigator.pushNamed(context, 'hrVerify',
arguments: enteredMobileNumber);
} else {
ToastHelper.showErrorToast(context, message);
print('Invalid mobile number');
}
} else { } else {
ToastHelper.showErrorToast(context, 'Failed to verify mobile number'); ToastHelper.showErrorToast(context, 'Failed to verify mobile number');
throw Exception('Failed to verify mobile number'); throw Exception('Failed to verify mobile number');
} }
} catch (e) { } catch (e) {
print('Error: $e'); print('Error: $e');
ToastHelper.showErrorToast(context, 'Error: $e'); ToastHelper.showErrorToast(context, 'Something went wrong');
return false;
} }
} }
void handleSubmit() async { // void handleSubmit() async {
if (_formKey.currentState!.validate()) { // if (_formKey.currentState!.validate()) {
// var enteredMobileNumber = countryController.text + mobileController.text; // // var enteredMobileNumber = countryController.text + mobileController.text;
var enteredMobileNumber = mobileController.text; // var enteredMobileNumber = mobileController.text;
//
bool isValid = await verifyMobileNumber(enteredMobileNumber); // bool isValid = await verifyMobileNumber(enteredMobileNumber);
//
if (isValid) { // if (isValid) {
ToastHelper.showSuccessToast(context, 'Mobile No Verified...'); // ToastHelper.showSuccessToast(context, 'Mobile No Verified...');
Navigator.pushNamed(context, 'hrVerify', // Navigator.pushNamed(context, 'hrVerify',
arguments: enteredMobileNumber); // arguments: enteredMobileNumber);
} else { // } else {
ToastHelper.showErrorToast(context, 'Invalid mobile number'); // ToastHelper.showErrorToast(context, 'Invalid mobile number');
} // }
} // }
} // }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -142,7 +165,7 @@ class _MyPhoneState extends State<MyHrLogin> {
), ),
SizedBox(width: 5), SizedBox(width: 5),
Text( Text(
'Customer Login', 'Member Login',
style: TextStyle( style: TextStyle(
color: Color(0xFF000000), // Text color color: Color(0xFF000000), // Text color
// Add other text styles as needed // Add other text styles as needed
@ -269,36 +292,35 @@ class _MyPhoneState extends State<MyHrLogin> {
flex: 4, flex: 4,
child: Align( child: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: MouseRegion( child: AnimatedButton(
cursor: animatedOn:
SystemMouseCursors.click, AnimatedOn.onHover,
child: GestureDetector( onPress: () {
onTap: () {
// Add your navigation logic here
// For example, you can use Navigator.push to navigate to another page
Navigator.pushNamed( Navigator.pushNamed(
context, 'phone'); context, 'phone');
}, },
child: Row( onChanges: (change) {},
children: [ height: 30,
Icon( width: 150,
Icons text: 'Member Login',
.west, // Icon for customer login isReverse: true,
color: Colors selectedTextColor:
.black, // Adjust color as needed Colors.black,
), transitionType: TransitionType
SizedBox(width: 5), .RIGHT_CENTER_ROUNDER,
Text( textStyle:
'Customer Login', GoogleFonts.poppins(
style: TextStyle( fontSize: 16,
color: Color( letterSpacing: 0,
0xFF000000), // Text color color: Color(0xFF00989E),
// Add other text styles as needed fontWeight: FontWeight.w300,
),
),
],
),
), ),
backgroundColor: Colors.white,
selectedBackgroundColor:
Color(0xFF00989E),
borderColor:
Color(0xFF00989E),
borderWidth: 1,
), ),
)), )),
Expanded( Expanded(
@ -360,7 +382,7 @@ class _MyPhoneState extends State<MyHrLogin> {
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
"Have a Health Insurance Policy number, but never signed in? Don't worry, We got you covered", "Login to manage the employee enrollment and overall health insurance programme of your organisation",
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: Color(0xFF000000)), color: Color(0xFF000000)),
@ -460,7 +482,7 @@ class _MyPhoneState extends State<MyHrLogin> {
BorderRadius.circular(10), BorderRadius.circular(10),
), ),
), ),
onPressed: handleSubmit, onPressed: verifyMobileNumber,
child: Text( child: Text(
"Login With OTP", "Login With OTP",
style: TextStyle( style: TextStyle(

746
lib/hrPolicyDetails.dart Normal file
View File

@ -0,0 +1,746 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.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';
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;
class hrPolicyDetails extends StatefulWidget {
const hrPolicyDetails({Key? key}) : super(key: key);
@override
State<hrPolicyDetails> createState() => _HrPolicyDetailsState();
}
class _HrPolicyDetailsState extends State<hrPolicyDetails>
with TickerProviderStateMixin {
Uint8List? fileBytes;
late String _token;
List<Map<String, dynamic>> getEmpDependenceByClintId = [];
bool _isLoading = false;
// dynamic clintID;
late TabController _tabController;
// List<dynamic> dataPolicy = [];
List<dynamic> reversedDataPolicy = [];
List<Map<String, dynamic>> originalData = []; // Original data source
List<Map<String, dynamic>> filteredData = []; // Filtered data source
dynamic argumentsData;
dynamic policyType;
dynamic policyName;
dynamic clientPolicyId;
dynamic clientId;
int inceptionType = 0;
TextEditingController searchController = TextEditingController();
@override
void initState() {
super.initState();
_tabController = TabController(length: 4, vsync: this);
_loadToken();
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
Future<void> _loadToken() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final token = prefs.getString('hrtoken');
if (token != null && token.isNotEmpty) {
setState(() {
_token = token;
});
Map<String, dynamic>? decodedToken = Jwt.parseJwt(token);
// 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<void> getPolicyDetails() async {
setState(() {
_isLoading = true;
});
try {
setState(() {
if (argumentsData != null && argumentsData is Map<String, dynamic>) {
if (argumentsData['type'] == 'GPA') {
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') {
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'] == 'SI TopUp') {
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'] == 'Dependent AddOn') {
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) {
print('Exception occurred: $e');
} finally {
setState(() {
_isLoading = false;
});
}
}
Future<void> getEmployeeAndDependence(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',
},
);
if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body);
if (data['status'] == 'success') {
setState(() {
getEmpDependenceByClintId =
List<Map<String, dynamic>>.from(data['data']);
originalData = getEmpDependenceByClintId;
filteredData = List.from(originalData);
print('filteredData');
print(filteredData);
});
} else {
// ToastHelper.showWarningToast(
// context, 'API request failed with status: ${data['status']}');
print('API request failed with status: ${data['status']}');
}
} else {
// ToastHelper.showWarningToast(
// context, 'Request failed with status: ${response.statusCode}');
print('Request failed with status: ${response.statusCode}');
}
} catch (e) {
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<void> 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');
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<String, dynamic>) {
argumentsData = arguments;
}
if (filteredData == []) {
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: 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: () {
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') &&
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,
),
),
)
],
),
),
),
),
],
),
)),
),
);
}
}
Widget _buildDataTableGPA(context) {
if (filteredData.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(filteredData, context),
),
);
}
}
}
class _DependenceDataSource0 extends DataTableSource {
final List<Map<String, dynamic>> _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) {
print(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;
}
}
// 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);
}

View File

@ -24,10 +24,18 @@ class _MyVerifyState extends State<MyHrVerify> {
late Timer _timer; late Timer _timer;
int _secondsRemaining = 30; int _secondsRemaining = 30;
bool _isTimerRunning = false; bool _isTimerRunning = false;
dynamic _token;
dynamic empCodeString;
dynamic empPrimaryId;
dynamic gpaEmpName;
dynamic client_id;
dynamic clientName;
dynamic clientLogo;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
checkTokenAvailability();
// Start the timer when the widget is initialized // Start the timer when the widget is initialized
startTimer(); startTimer();
} }
@ -52,6 +60,16 @@ class _MyVerifyState extends State<MyHrVerify> {
}); });
} }
Future<void> checkTokenAvailability() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String? hrtoken = prefs.getString('hrtoken');
if (hrtoken != null && hrtoken.isNotEmpty) {
// Token available, navigate to home page
Navigator.pushReplacementNamed(context, 'hrDashboard');
}
}
Future<void> resendOTP(String mobileNumber) async { Future<void> resendOTP(String mobileNumber) async {
print(mobileNumber); print(mobileNumber);
// Update the UI as needed // Update the UI as needed
@ -85,8 +103,7 @@ class _MyVerifyState extends State<MyHrVerify> {
} catch (e) { } catch (e) {
// Handle API call errors // Handle API call errors
print('Error: $e'); print('Error: $e');
ToastHelper.showErrorToast( ToastHelper.showErrorToast(context, 'Something went wrong');
context, 'Failed to resend OTP. Please try again.');
// ScaffoldMessenger.of(context).showSnackBar( // ScaffoldMessenger.of(context).showSnackBar(
// SnackBar( // SnackBar(
// content: Text('Failed to resend OTP. Please try again.'), // content: Text('Failed to resend OTP. Please try again.'),
@ -110,16 +127,32 @@ class _MyVerifyState extends State<MyHrVerify> {
if (response.statusCode == 200) { if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body); Map<String, dynamic> data = json.decode(response.body);
_token = data['data'];
print(data); print(data);
String status = data['status']; String status = data['status'];
print(status); print(status);
if (status == 'success') { if (status == 'success') {
final SharedPreferences prefs = await SharedPreferences.getInstance(); final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('hrtoken', data['data']); prefs.setString('hrtoken', data['data']);
// Decode the JWT token received from the API response
Map<String, dynamic>? decodedToken = Jwt.parseJwt(data['data']);
print(decodedToken);
empCodeString = decodedToken['emp_code'].toString();
prefs.setString('empCode', empCodeString);
empPrimaryId = decodedToken['id'];
prefs.setString('empPrimaryId', empPrimaryId);
gpaEmpName = decodedToken['name'].toString();
prefs.setString('gpaEmpName', gpaEmpName);
client_id = decodedToken['client_id'];
prefs.setString('client_id', client_id);
getClientLogoAndDetails();
print('Successfully Login');
final hrtoken = prefs.getString('hrtoken'); final hrtoken = prefs.getString('hrtoken');
if (hrtoken != null && hrtoken.isNotEmpty) { if (hrtoken != null && hrtoken.isNotEmpty) {
ToastHelper.showSuccessToast(context, 'Successfully Login'); ToastHelper.showSuccessToast(context, 'Successfully Login');
Navigator.pushNamed(context, 'hrHome'); Navigator.pushNamed(context, 'hrDashboard');
} else { } else {
// Token is empty or null, handle accordingly (e.g., navigate to login screen) // Token is empty or null, handle accordingly (e.g., navigate to login screen)
// For now, let's navigate to the login screen // For now, let's navigate to the login screen
@ -153,6 +186,53 @@ class _MyVerifyState extends State<MyHrVerify> {
} }
} }
Future<void> getClientLogoAndDetails() async {
var url = Uri.parse(Environment.apiUrl +
'getClientDetails?client_id=$client_id&emp_code=$empCodeString');
try {
var response = await http.get(
url,
headers: {
'Authorization':
'Bearer $_token', // Add token to the Authorization header
},
);
if (response.statusCode == 200) {
// print('response.statusCode == 200');
Map<String, dynamic> data = json.decode(response.body);
// print(data);
if (data.containsKey('data')) {
dynamic clientDetails = data['data'];
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('clientLogo', clientDetails['client']['client_logo']);
prefs.setString('clientName', clientDetails['client']['client_name']);
setState(() {
// dynamic clientDetails = data['data'];
// print(clientDetails);
clientName = clientDetails['client']['client_name'];
print(clientName);
clientLogo = clientDetails['client']['client_logo'];
print(clientLogo);
});
} else {
// Handle other status messages if needed
// ToastHelper.showErrorToast(
// context, 'API request failed with status: ${data['status']}');
print('API request failed with status: ${data['status']}');
}
} else {
// Handle other status codes
// ToastHelper.showErrorToast(
// context, 'Request failed with status: ${response.statusCode}');
print('Request failed with status: ${response.statusCode}');
}
} catch (e) {
// Handle exceptions
print('Exception occurred: $e');
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// Retrieve the passed mobile number value // Retrieve the passed mobile number value

View File

@ -9,8 +9,11 @@ import 'package:nhancepolicy/models/environment.dart';
import 'package:nhancepolicy/phone.dart'; import 'package:nhancepolicy/phone.dart';
import 'package:nhancepolicy/verify.dart'; import 'package:nhancepolicy/verify.dart';
import 'package:nhancepolicy/home.dart'; import 'package:nhancepolicy/home.dart';
import 'package:nhancepolicy/hrDashboard.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:nhancepolicy/hrLogin.dart'; import 'package:nhancepolicy/hrLogin.dart';
import 'package:nhancepolicy/hrPolicyDetails.dart';
import 'package:nhancepolicy/oldPolicy.dart';
Future<void> main() async { Future<void> main() async {
await dotenv.load(fileName: Environment.fileName); await dotenv.load(fileName: Environment.fileName);
@ -29,6 +32,9 @@ Future<void> main() async {
'empDetails': (context) => empDetails(), 'empDetails': (context) => empDetails(),
'addOnsDetails': (context) => addOnsDetails(), 'addOnsDetails': (context) => addOnsDetails(),
'empReviewDetails': (context) => empReviewDetails(), 'empReviewDetails': (context) => empReviewDetails(),
'hrDashboard': (context) => hrDashboard(),
'hrPolicyDetails': (context) => hrPolicyDetails(),
'oldPolicy': (context) => oldPolicy(),
}, },
)); ));
} }

385
lib/oldPolicy.dart Normal file
View File

@ -0,0 +1,385 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:jwt_decode/jwt_decode.dart';
import 'package:nhancepolicy/models/environment.dart';
import 'package:nhancepolicy/responsive.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import 'customAppBar/customAppBar.dart';
import 'customAppBar/toastHelper.dart';
class oldPolicy extends StatefulWidget {
const oldPolicy({Key? key}) : super(key: key);
@override
State<oldPolicy> createState() => _oldPolicyState();
}
class _oldPolicyState extends State<oldPolicy> {
dynamic _token;
dynamic empCodeString;
dynamic empPrimaryId;
dynamic client_id;
dynamic gpaEmpName;
dynamic oldPolicyList;
dynamic oldPolicyName;
dynamic oldPolicyClientId;
dynamic oldPolicyClientPolicyId;
dynamic oldPolicySiGstValue;
dynamic oldPolicySiPremiumValue;
dynamic oldPolicySiValue;
dynamic oldPolicyType;
dynamic oldPolicyEmployeePolicy;
dynamic oldPolicyDataIsEmpty = 1;
dynamic oldPolicyTypeHeading;
dynamic oldPolicyFloaterTextHeading;
dynamic oldPolicyStartDate;
dynamic oldPolicyEndDate;
@override
void initState() {
super.initState();
_loadToken();
}
@override
void dispose() {
super.dispose();
}
Future<void> _loadToken() async {
print('_loadToken');
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('token');
if (token != null && token.isNotEmpty) {
setState(() {
_token = token;
});
// Decode the JWT token received from the API response
Map<String, dynamic>? decodedToken = Jwt.parseJwt(token);
print(decodedToken);
empCodeString = prefs.getString('empCode');
print(empCodeString); // Check if emp_code is correct
empPrimaryId = prefs.getString('empPrimaryId');
gpaEmpName = prefs.getString('gpaEmpName');
client_id = prefs.getString('client_id');
print(client_id);
getOldPolicyDetails();
} 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, 'phone');
}
}
Future<void> getOldPolicyDetails() async {
var url = Uri.parse(Environment.apiUrl +
'getEmployeeActiveOrInactivePolicy?client_id=$client_id&emp_code=$empCodeString&type=Inactive');
try {
var response = await http.get(
url,
headers: {
'Authorization':
'Bearer $_token', // Add token to the Authorization header
},
);
if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body);
if (data['status'] == 'success') {
setState(() {
oldPolicyList = data['data'];
print('gmcPolicies');
});
// Assuming data is a List
print(oldPolicyList);
} else {
setState(() {
oldPolicyDataIsEmpty = 0;
});
// Handle other status messages if needed
// ToastHelper.showErrorToast(
// context, 'API request failed with status: ${data['status']}');
print('API request failed with status: ${data['status']}');
}
} else {
setState(() {
oldPolicyDataIsEmpty = 0;
});
// Handle other status codes
// ToastHelper.showErrorToast(
// context, 'Request failed with status: ${response.statusCode}');
print('Request failed with status: ${response.statusCode}');
}
} catch (e) {
// Handle exceptions
print('Exception occurred: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(),
body: _buildBody(),
);
}
Widget _buildBody() {
if (oldPolicyList == null) {
return Center(child: _buildNoDataWidget());
} else if (oldPolicyList!.isEmpty) {
return Center(child: _buildNoDataWidget());
} else {
return _buildPolicyListWidget();
}
}
Widget _buildNoDataWidget() {
return SingleChildScrollView(
child: Container(
color: Color(0xFFEFF3F6),
child: Column(
children: [
Center(
child: Text('No Data Available'),
)
],
),
),
);
}
Widget _buildPolicyListWidget() {
return Stack(
children: [
SingleChildScrollView(
child: Container(
padding: Responsive.isDesktop(context)
? EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width *
0.2, // 30% of screen width as horizontal padding
vertical: MediaQuery.of(context).size.height *
0.03, // 5% of screen height as vertical padding
)
: EdgeInsets.all(10),
color: Color(0xFFEFF3F6),
child: Column(
children: [
if (oldPolicyDataIsEmpty == 1)
...generateGmcCards(oldPolicyList),
],
),
),
)
],
);
}
List<Widget> generateGmcCards(List<dynamic> data) {
List<Widget> cards = [];
print('data');
print(data);
for (var item in data) {
setState(() {
oldPolicyName = item['policy_name'];
oldPolicyTypeHeading = item['heading'];
oldPolicyFloaterTextHeading = item['floter_text_heading'];
oldPolicyClientId = item['client_id'];
oldPolicyClientPolicyId = item['client_policy_id'];
oldPolicySiGstValue = item['si_gst_value'];
oldPolicySiPremiumValue = item['si_premium_value'];
oldPolicySiValue = item['si_value'];
oldPolicyType = item['policy_type'];
oldPolicyStartDate = item['policy_start_date'];
oldPolicyEndDate = item['policy_end_date'];
oldPolicyEmployeePolicy = item['EmployeePolicy'];
});
Widget card = Card(
elevation: 0,
child: Padding(
padding: Responsive.isDesktop(context)
? EdgeInsets.all(20)
: EdgeInsets.all(10),
child: Column(
children: [
Container(
decoration: BoxDecoration(
color: Color(
0xFFFFF1DD), // Set background color for the container
borderRadius: BorderRadius.circular(
5), // Set border radius for the container
),
padding: Responsive.isDesktop(context)
? EdgeInsets.only(
top: 15, bottom: 15, left: 25, right: 25)
: EdgeInsets.only(
top: 10, bottom: 10, left: 10, right: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 8,
child: Container(
alignment: Alignment.centerLeft,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
oldPolicyName ?? '',
textAlign: TextAlign.left,
style: GoogleFonts.poppins(
fontSize: Responsive.isDesktop(context)
? 18
: 14,
),
),
Text(
oldPolicyTypeHeading ?? '',
textAlign: TextAlign.left,
style: GoogleFonts.poppins(
fontSize: Responsive.isDesktop(context)
? 20
: 16,
fontWeight: FontWeight.w600,
),
),
],
))),
Expanded(
flex: 4,
child: Container(
alignment: Alignment.centerRight,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
oldPolicyFloaterTextHeading ?? '',
textAlign: TextAlign.right,
style: GoogleFonts.poppins(
fontSize: Responsive.isDesktop(context)
? 18
: 14,
),
),
Text(
'${oldPolicySiValue != null ? oldPolicySiValue : 'NA'}',
textAlign: TextAlign.right,
style: GoogleFonts.poppins(
fontSize: Responsive.isDesktop(context)
? 20
: 16,
fontWeight: FontWeight.w600,
),
),
],
))),
],
),
),
SizedBox(height: 15),
Container(
padding: Responsive.isDesktop(context)
? EdgeInsets.only(top: 0, bottom: 0, left: 15, right: 15)
: EdgeInsets.only(top: 0, bottom: 0, left: 5, right: 5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: oldPolicyEmployeePolicy.map<Widget>((data) {
String formattedDate = formatDate(data['dob']);
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.arrow_right,
color: Color(0xFFE26728)), // Arrow icon
SizedBox(
width: Responsive.isDesktop(context)
? 10
: 5), // Space between icon and text
Expanded(
child: Text(
'${data['name']} ~ ${data['relationship']} ~ DOB : $formattedDate',
style: GoogleFonts.poppins(
fontSize:
Responsive.isDesktop(context) ? 18 : 16,
color: Color(0xFF232526),
),
),
),
],
);
}).toList(),
),
),
SizedBox(height: 15),
Container(
padding: Responsive.isDesktop(context)
? EdgeInsets.only(top: 0, bottom: 0, left: 25, right: 25)
: EdgeInsets.only(top: 0, bottom: 0, left: 10, right: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 12,
child: Container(
alignment: Alignment.centerLeft,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(
text: TextSpan(
text: 'Policy Period : ',
style: GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Color(0xFF232526),
),
children: <TextSpan>[
TextSpan(
text:
'$oldPolicyStartDate To $oldPolicyEndDate',
style: GoogleFonts.poppins(
fontSize: 14,
color: Color(0xFF232526),
),
),
],
),
),
],
),
),
),
],
),
),
],
),
));
cards.add(card);
cards.add(SizedBox(height: 10));
}
return cards;
}
String formatDate(String inputDate) {
// Parse the input date string
DateTime dateTime = DateTime.parse(inputDate);
// Format the date to 'dd MMMM yyyy'
String formattedDate = DateFormat('dd MMMM yyyy').format(dateTime);
return formattedDate;
}
}

View File

@ -7,6 +7,9 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:nhancepolicy/responsive.dart'; import 'package:nhancepolicy/responsive.dart';
import 'package:nhancepolicy/customAppBar/toastHelper.dart'; import 'package:nhancepolicy/customAppBar/toastHelper.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_animated_button/flutter_animated_button.dart';
import 'package:google_fonts/google_fonts.dart';
class MyPhone extends StatefulWidget { class MyPhone extends StatefulWidget {
const MyPhone({Key? key}); const MyPhone({Key? key});
@ -24,17 +27,32 @@ class _MyPhoneState extends State<MyPhone> {
void initState() { void initState() {
countryController.text = "+91"; countryController.text = "+91";
super.initState(); super.initState();
checkTokenAvailability();
}
Future<void> checkTokenAvailability() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('token');
if (token != null && token.isNotEmpty) {
// Token available, navigate to home page
Navigator.pushReplacementNamed(context, 'empDetails',
arguments: {'mobile': ''});
}
} }
void toggleLoginType() { void toggleLoginType() {
Navigator.pushNamed(context, 'hrLogin'); // Navigate to another page Navigator.pushNamed(context, 'hrLogin'); // Navigate to another page
} }
Future<bool> verifyMobileNumber(String mobileNumber) async { Future<void> verifyMobileNumber() async {
try { try {
if (_formKey.currentState!.validate()) {
// var enteredMobileNumber = countryController.text + mobileController.text;
var enteredMobileNumber = mobileController.text;
final response = await http.post( final response = await http.post(
Uri.parse(Environment.apiUrl + 'verifyEmployeeNumber'), Uri.parse(Environment.apiUrl + 'verifyEmployeeNumber'),
body: json.encode({'mobile_number': mobileNumber}), body: json.encode({'mobile_number': enteredMobileNumber}),
headers: { headers: {
HttpHeaders.contentTypeHeader: 'application/json', HttpHeaders.contentTypeHeader: 'application/json',
}, },
@ -43,34 +61,42 @@ class _MyPhoneState extends State<MyPhone> {
if (response.statusCode == 200) { if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body); Map<String, dynamic> data = json.decode(response.body);
bool userVerification = data['data']['user_verification']; bool userVerification = data['data']['user_verification'];
return userVerification; String message = data['data']['message'];
if (userVerification) {
ToastHelper.showSuccessToast(context, message);
Navigator.pushNamed(context, 'verify',
arguments: enteredMobileNumber);
} else { } else {
ToastHelper.showErrorToast(context, 'Failed to verify mobile number'); ToastHelper.showErrorToast(context, message);
throw Exception('Failed to verify mobile number');
}
} catch (e) {
ToastHelper.showErrorToast(context, '$e');
print('Error: $e');
return false;
}
}
void handleSubmit() async {
if (_formKey.currentState!.validate()) {
// var enteredMobileNumber = countryController.text + mobileController.text;
var enteredMobileNumber = mobileController.text;
bool isValid = await verifyMobileNumber(enteredMobileNumber);
if (isValid) {
ToastHelper.showSuccessToast(context, 'Mobile No Verified..');
Navigator.pushNamed(context, 'verify', arguments: enteredMobileNumber);
} else {
ToastHelper.showErrorToast(context, 'Invalid mobile number..');
print('Invalid mobile number'); print('Invalid mobile number');
} }
} else {
ToastHelper.showErrorToast(context, 'Something went wrong');
throw Exception('Failed to verify mobile number');
} }
} }
} catch (e) {
ToastHelper.showErrorToast(context, 'Something went wrong');
print('Error: $e');
}
}
// void handleSubmit() async {
// if (_formKey.currentState!.validate()) {
// // var enteredMobileNumber = countryController.text + mobileController.text;
// var enteredMobileNumber = mobileController.text;
//
// bool isValid = await verifyMobileNumber(enteredMobileNumber);
//
// if (isValid) {
// ToastHelper.showSuccessToast(context, 'Mobile No Verified..');
// Navigator.pushNamed(context, 'verify', arguments: enteredMobileNumber);
// } else {
// ToastHelper.showErrorToast(context, 'Invalid mobile number..');
// print('Invalid mobile number');
// }
// }
// }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -155,7 +181,7 @@ class _MyPhoneState extends State<MyPhone> {
children: [ children: [
SizedBox( SizedBox(
height: _size.height / height: _size.height /
6.4), // Adjust the spacing between the rows 8.0), // Adjust the spacing between the rows
Row( Row(
mainAxisAlignment: MainAxisAlignment mainAxisAlignment: MainAxisAlignment
.center, // Align to the center .center, // Align to the center
@ -167,9 +193,7 @@ class _MyPhoneState extends State<MyPhone> {
? Alignment.centerLeft ? Alignment.centerLeft
: Alignment.bottomCenter, : Alignment.bottomCenter,
child: Image.asset( child: Image.asset(
_size.width <= 1100 'assets/mobileViewLogo.png',
? 'assets/mobileViewLogo.png'
: 'assets/Nhance-Logo-Final 1.png',
width: 150, width: 150,
height: 150, height: 150,
), ),
@ -273,43 +297,41 @@ class _MyPhoneState extends State<MyPhone> {
Expanded( Expanded(
flex: 2, flex: 2,
child: Align( child: Align(
alignment: alignment: Alignment.centerLeft,
Alignment.centerRight, child: AnimatedButton(
child: MouseRegion( animatedOn:
cursor: AnimatedOn.onHover,
SystemMouseCursors.click, onPress: () {
child: GestureDetector(
onTap: () {
// Add your navigation logic here
// For example, you can use Navigator.push to navigate to another page
Navigator.pushNamed( Navigator.pushNamed(
context, 'hrLogin'); context, 'hrLogin');
}, },
child: Row( onChanges: (change) {},
children: [ height: 30,
Text( width: 150,
'HR Login', text: 'HR Login',
style: TextStyle( isReverse: true,
color: Color( selectedTextColor:
0xFF000000), // Text color Colors.black,
// Add other text styles as needed transitionType: TransitionType
), .LEFT_CENTER_ROUNDER,
), textStyle:
SizedBox(width: 5), GoogleFonts.poppins(
Icon( fontSize: 16,
Icons letterSpacing: 0,
.east, // Icon for customer login color: Color(0xFF00989E),
color: Colors fontWeight: FontWeight.w300,
.black, // Adjust color as needed
),
],
),
), ),
backgroundColor: Colors.white,
selectedBackgroundColor:
Color(0xFF00989E),
borderColor:
Color(0xFF00989E),
borderWidth: 1,
), ),
)), )),
], ],
), ),
SizedBox(height: 15), SizedBox(height: 10),
Container( Container(
margin: Responsive.isDesktop(context) margin: Responsive.isDesktop(context)
? EdgeInsets.symmetric( ? EdgeInsets.symmetric(
@ -321,7 +343,7 @@ class _MyPhoneState extends State<MyPhone> {
children: [ children: [
Text( Text(
"Welcome to Nhance", "Welcome to Nhance",
style: TextStyle( style: GoogleFonts.poppins(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@ -330,7 +352,7 @@ class _MyPhoneState extends State<MyPhone> {
), ),
), ),
SizedBox( SizedBox(
height: 15, height: 10,
), ),
Container( Container(
margin: Responsive.isDesktop(context) margin: Responsive.isDesktop(context)
@ -343,8 +365,8 @@ class _MyPhoneState extends State<MyPhone> {
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
"Have a Health Insurance Policy number, but never signed in? Don't worry, We got you covered", "Login with your mobile number and OTP to review and enroll for exciting health benefits for you and your family",
style: TextStyle( style: GoogleFonts.poppins(
fontSize: 12, fontSize: 12,
color: Color(0xFF000000)), color: Color(0xFF000000)),
textAlign: TextAlign.center, textAlign: TextAlign.center,
@ -443,10 +465,10 @@ class _MyPhoneState extends State<MyPhone> {
BorderRadius.circular(10), BorderRadius.circular(10),
), ),
), ),
onPressed: handleSubmit, onPressed: verifyMobileNumber,
child: Text( child: Text(
"Login With OTP", "Login With OTP",
style: TextStyle( style: GoogleFonts.poppins(
color: Color(0xFFFFFFFF)), color: Color(0xFFFFFFFF)),
), ),
), ),
@ -464,7 +486,7 @@ class _MyPhoneState extends State<MyPhone> {
SizedBox(height: 30), SizedBox(height: 30),
Text( Text(
"Benefits of Login", "Benefits of Login",
style: TextStyle( style: GoogleFonts.poppins(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@ -568,28 +590,28 @@ class _MyPhoneState extends State<MyPhone> {
text: TextSpan( text: TextSpan(
text: text:
'By continuing, you agree with our ', 'By continuing, you agree with our ',
style: TextStyle( style: GoogleFonts.poppins(
color: Colors.black, color: Colors.black,
fontSize: 9, fontSize: 9,
), ),
children: <TextSpan>[ children: <TextSpan>[
TextSpan( TextSpan(
text: 'privacy policy ', text: 'privacy policy ',
style: TextStyle( style: GoogleFonts.poppins(
color: Color(0xFF00989E), color: Color(0xFF00989E),
fontSize: 9, fontSize: 9,
), ),
), ),
TextSpan( TextSpan(
text: 'and ', text: 'and ',
style: TextStyle( style: GoogleFonts.poppins(
color: Colors.black, color: Colors.black,
fontSize: 9, fontSize: 9,
), ),
), ),
TextSpan( TextSpan(
text: 'terms of use', text: 'terms of use',
style: TextStyle( style: GoogleFonts.poppins(
color: Color(0xFF00989E), color: Color(0xFF00989E),
fontSize: 9, fontSize: 9,
), ),
@ -612,7 +634,7 @@ class _MyPhoneState extends State<MyPhone> {
return Image.asset( return Image.asset(
'assets/login_web.jpg', 'assets/login_web.jpg',
height: _size.height, height: _size.height,
fit: BoxFit.fill, fit: BoxFit.cover,
); );
} else { } else {
return SizedBox(); return SizedBox();

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:nhancepolicy/models/environment.dart'; import 'package:nhancepolicy/models/environment.dart';
import 'package:pinput/pinput.dart'; import 'package:pinput/pinput.dart';
import 'dart:async'; import 'dart:async';
@ -28,10 +29,14 @@ class _MyVerifyState extends State<MyVerify> {
dynamic empPrimaryId; dynamic empPrimaryId;
dynamic gpaEmpName; dynamic gpaEmpName;
dynamic client_id; dynamic client_id;
dynamic _token;
dynamic clientName;
dynamic clientLogo;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
checkTokenAvailability();
// Start the timer when the widget is initialized // Start the timer when the widget is initialized
startTimer(); startTimer();
} }
@ -56,6 +61,17 @@ class _MyVerifyState extends State<MyVerify> {
}); });
} }
Future<void> checkTokenAvailability() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('token');
if (token != null && token.isNotEmpty) {
// Token available, navigate to home page
Navigator.pushReplacementNamed(context, 'empDetails',
arguments: {'mobile': ''});
}
}
Future<void> resendOTP(String mobileNumber) async { Future<void> resendOTP(String mobileNumber) async {
print(mobileNumber); print(mobileNumber);
// Update the UI as needed // Update the UI as needed
@ -105,6 +121,7 @@ class _MyVerifyState extends State<MyVerify> {
if (response.statusCode == 200) { if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body); Map<String, dynamic> data = json.decode(response.body);
print(data); print(data);
_token = data['data'];
String status = data['status']; String status = data['status'];
print(status); print(status);
if (status == 'success') { if (status == 'success') {
@ -122,6 +139,7 @@ class _MyVerifyState extends State<MyVerify> {
prefs.setString('gpaEmpName', gpaEmpName); prefs.setString('gpaEmpName', gpaEmpName);
client_id = decodedToken['client_id']; client_id = decodedToken['client_id'];
prefs.setString('client_id', client_id); prefs.setString('client_id', client_id);
getClientLogoAndDetails();
print('Successfully Login'); print('Successfully Login');
@ -144,13 +162,12 @@ class _MyVerifyState extends State<MyVerify> {
print('Invalid OTP. Please try again'); print('Invalid OTP. Please try again');
} }
} else { } else {
ToastHelper.showErrorToast(context, 'Failed to verify OTP'); ToastHelper.showWarningToast(context, 'Something went wrong');
throw Exception('Failed to verify OTP'); throw Exception('Failed to verify OTP');
} }
} catch (e) { } catch (e) {
print('Error: $e'); print('Error: $e');
ToastHelper.showErrorToast( ToastHelper.showWarningToast(context, 'Something went wrong');
context, 'Failed to verify OTP. Please try again.');
// Show a Snackbar if there's an error while verifying OTP // Show a Snackbar if there's an error while verifying OTP
// ToastHelper.showErrorToast( // ToastHelper.showErrorToast(
// context, 'Failed to verify OTP. Please try again.'); // context, 'Failed to verify OTP. Please try again.');
@ -158,6 +175,53 @@ class _MyVerifyState extends State<MyVerify> {
} }
} }
Future<void> getClientLogoAndDetails() async {
var url = Uri.parse(Environment.apiUrl +
'getClientDetails?client_id=$client_id&emp_code=$empCodeString');
try {
var response = await http.get(
url,
headers: {
'Authorization':
'Bearer $_token', // Add token to the Authorization header
},
);
if (response.statusCode == 200) {
// print('response.statusCode == 200');
Map<String, dynamic> data = json.decode(response.body);
// print(data);
if (data.containsKey('data')) {
dynamic clientDetails = data['data'];
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('clientLogo', clientDetails['client']['client_logo']);
prefs.setString('clientName', clientDetails['client']['client_name']);
setState(() {
// dynamic clientDetails = data['data'];
// print(clientDetails);
clientName = clientDetails['client']['client_name'];
print(clientName);
clientLogo = clientDetails['client']['client_logo'];
print(clientLogo);
});
} else {
// Handle other status messages if needed
// ToastHelper.showErrorToast(
// context, 'API request failed with status: ${data['status']}');
print('API request failed with status: ${data['status']}');
}
} else {
// Handle other status codes
// ToastHelper.showErrorToast(
// context, 'Request failed with status: ${response.statusCode}');
print('Request failed with status: ${response.statusCode}');
}
} catch (e) {
// Handle exceptions
print('Exception occurred: $e');
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// Retrieve the passed mobile number value // Retrieve the passed mobile number value
@ -237,7 +301,7 @@ class _MyVerifyState extends State<MyVerify> {
children: [ children: [
SizedBox( SizedBox(
height: _size.height / height: _size.height /
6.4), // Adjust the spacing between the rows 8.0), // Adjust the spacing between the rows
Row( Row(
mainAxisAlignment: MainAxisAlignment mainAxisAlignment: MainAxisAlignment
.center, // Align to the center .center, // Align to the center
@ -249,9 +313,7 @@ class _MyVerifyState extends State<MyVerify> {
? Alignment.centerLeft ? Alignment.centerLeft
: Alignment.bottomCenter, : Alignment.bottomCenter,
child: Image.asset( child: Image.asset(
_size.width <= 1100 'assets/mobileViewLogo.png',
? 'assets/mobileViewLogo.png'
: 'assets/Nhance-Logo-Final 1.png',
width: 150, width: 150,
height: 150, height: 150,
), ),
@ -276,7 +338,7 @@ class _MyVerifyState extends State<MyVerify> {
children: [ children: [
Text( Text(
'HR Login', 'HR Login',
style: TextStyle( style: GoogleFonts.poppins(
color: Color( color: Color(
0xFF000000), // Text color 0xFF000000), // Text color
// Add other text styles as needed // Add other text styles as needed
@ -366,7 +428,7 @@ class _MyVerifyState extends State<MyVerify> {
children: [ children: [
Text( Text(
"Welcome to Nhance", "Welcome to Nhance",
style: TextStyle( style: GoogleFonts.poppins(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@ -435,7 +497,7 @@ class _MyVerifyState extends State<MyVerify> {
_isTimerRunning _isTimerRunning
? Text( ? Text(
"Resend OTP in $_secondsRemaining seconds", "Resend OTP in $_secondsRemaining seconds",
style: TextStyle( style: GoogleFonts.poppins(
color: Colors.black), color: Colors.black),
) )
: InkWell( : InkWell(
@ -444,7 +506,7 @@ class _MyVerifyState extends State<MyVerify> {
}, },
child: Text( child: Text(
"Resend OTP", "Resend OTP",
style: TextStyle( style: GoogleFonts.poppins(
color: Colors.blue), color: Colors.blue),
), ),
), ),
@ -478,7 +540,7 @@ class _MyVerifyState extends State<MyVerify> {
}, },
child: Text( child: Text(
"Submit", "Submit",
style: TextStyle( style: GoogleFonts.poppins(
color: Color(0xFFFFFFFF)), color: Color(0xFFFFFFFF)),
), ),
), ),
@ -490,10 +552,10 @@ class _MyVerifyState extends State<MyVerify> {
horizontal: 150), horizontal: 150),
child: Column( child: Column(
children: [ children: [
SizedBox(height: 30), SizedBox(height: 20),
Text( Text(
"Benefits of Login", "Benefits of Login",
style: TextStyle( style: GoogleFonts.poppins(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@ -548,7 +610,9 @@ class _MyVerifyState extends State<MyVerify> {
SizedBox( SizedBox(
height: 10), height: 10),
Text( Text(
"View Policy"), "View Policy",
style: GoogleFonts
.poppins()),
], ],
), ),
), ),
@ -567,7 +631,9 @@ class _MyVerifyState extends State<MyVerify> {
SizedBox( SizedBox(
height: 10), height: 10),
Text( Text(
"Manage Claims"), "Manage Claims",
style: GoogleFonts
.poppins()),
], ],
), ),
), ),
@ -597,28 +663,28 @@ class _MyVerifyState extends State<MyVerify> {
text: TextSpan( text: TextSpan(
text: text:
'By continuing, you agree with our ', 'By continuing, you agree with our ',
style: TextStyle( style: GoogleFonts.poppins(
color: Colors.black, color: Colors.black,
fontSize: 9, fontSize: 9,
), ),
children: <TextSpan>[ children: <TextSpan>[
TextSpan( TextSpan(
text: 'privacy policy ', text: 'privacy policy ',
style: TextStyle( style: GoogleFonts.poppins(
color: Color(0xFF00989E), color: Color(0xFF00989E),
fontSize: 9, fontSize: 9,
), ),
), ),
TextSpan( TextSpan(
text: 'and ', text: 'and ',
style: TextStyle( style: GoogleFonts.poppins(
color: Colors.black, color: Colors.black,
fontSize: 9, fontSize: 9,
), ),
), ),
TextSpan( TextSpan(
text: 'terms of use', text: 'terms of use',
style: TextStyle( style: GoogleFonts.poppins(
color: Color(0xFF00989E), color: Color(0xFF00989E),
fontSize: 9, fontSize: 9,
), ),
@ -641,7 +707,7 @@ class _MyVerifyState extends State<MyVerify> {
return Image.asset( return Image.asset(
'assets/login_web.jpg', 'assets/login_web.jpg',
height: _size.height, height: _size.height,
fit: BoxFit.fill, fit: BoxFit.cover,
); );
} else { } else {
return SizedBox(); return SizedBox();

View File

@ -7,9 +7,13 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <smart_auth/smart_auth_plugin.h> #include <smart_auth/smart_auth_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) smart_auth_registrar = g_autoptr(FlPluginRegistrar) smart_auth_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "SmartAuthPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "SmartAuthPlugin");
smart_auth_plugin_register_with_registrar(smart_auth_registrar); smart_auth_plugin_register_with_registrar(smart_auth_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
} }

View File

@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
smart_auth smart_auth
url_launcher_linux
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST

View File

@ -8,9 +8,11 @@ import Foundation
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
import smart_auth import smart_auth
import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SmartAuthPlugin.register(with: registry.registrar(forPlugin: "SmartAuthPlugin")) SmartAuthPlugin.register(with: registry.registrar(forPlugin: "SmartAuthPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
} }

View File

@ -43,13 +43,16 @@ dependencies:
adaptive_navbar: ^0.0.3 adaptive_navbar: ^0.0.3
jwt_decode: ^0.3.1 jwt_decode: ^0.3.1
google_fonts: ^6.2.1 google_fonts: ^6.2.1
file_picker: ^6.2.0 file_picker: ^8.0.3
csv: ^6.0.0 csv: ^6.0.0
data_tables: ^1.4.0 data_tables: ^1.4.0
universal_html: ^2.2.4 universal_html: ^2.2.4
excel: ^4.0.3 excel: ^4.0.3
intl: ^0.19.0 intl: ^0.19.0
toastification: ^1.2.1 toastification: ^1.2.1
flutter_animated_button: ^2.0.3
spreadsheet_decoder: ^2.2.0
url_launcher: ^6.2.6
dev_dependencies: dev_dependencies:

BIN
web/assets/Sample.xlsx Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -95,7 +95,7 @@
if(loadingIndicator){ if(loadingIndicator){
loadingIndicator.remove(); loadingIndicator.remove();
} }
},10000); },5000);
}; };
</script> </script>
</body> </body>

View File

@ -7,8 +7,11 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <smart_auth/smart_auth_plugin.h> #include <smart_auth/smart_auth_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
SmartAuthPluginRegisterWithRegistrar( SmartAuthPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SmartAuthPlugin")); registry->GetRegistrarForPlugin("SmartAuthPlugin"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

View File

@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
smart_auth smart_auth
url_launcher_windows
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST