enrollment-app/lib/excel_verification.dart
2024-06-04 08:28:14 +05:30

1203 lines
54 KiB
Dart

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:jwt_decode/jwt_decode.dart';
import 'package:nhancepolicy/customAppBar/customAppBar.dart';
import 'dart:convert';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:nhancepolicy/customAppBar/toastHelper.dart';
import 'package:nhancepolicy/models/environment.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:universal_html/html.dart' as html;
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:excel/excel.dart';
import 'dart:io';
import 'package:intl/intl.dart';
import 'package:csv/csv.dart';
import 'package:spreadsheet_decoder/spreadsheet_decoder.dart';
class excelVerify extends StatefulWidget {
const excelVerify({Key? key}) : super(key: key);
@override
State<excelVerify> createState() => _excelVerifyState();
}
class _excelVerifyState extends State<excelVerify> {
Uint8List? fileBytes;
Uint8List? fileBytes2;
late String _token;
dynamic getPolicyNo;
bool _isLoading = false;
dynamic getPolicyNameDetails;
dynamic clintID;
String? fileName;
int _currentStep = 0; // Step index tracker
List<dynamic> dataPolicy = [];
dynamic validationArray = [];
dynamic missingColumnErrorMsg = 0;
dynamic columnIndexMismatchCount = 0;
dynamic columnMissingCount = 0;
List<Map<String, dynamic>> extractedData = [];
dynamic argumentsData;
List<Map<String, dynamic>> originalData = []; // Original data source
List<Map<String, dynamic>> filteredData = []; // Filtered data source
dynamic policy_name;
dynamic clientPolicyId;
dynamic clientId;
dynamic policyType;
List<Map<String, dynamic>> nonExcelFilteredData = [];
dynamic invalidRelationships = 0;
dynamic dobAgeCheckCount = 0;
dynamic empRefId;
@override
void initState() {
super.initState();
_loadToken();
}
@override
void dispose() {
super.dispose();
html.window.localStorage.remove('fileBytes');
}
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();
empRefId = prefs.getString('empRefId');
await 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(() {
clientPolicyId = argumentsData['client_policy_id'];
clientId = argumentsData['client_id'];
policyType = argumentsData['type'];
policy_name = argumentsData['policy_name'];
});
}
// Future<void> _uploadFile1(importPolicyName) async {
// FilePickerResult? result = await FilePicker.platform.pickFiles(
// type: FileType.custom,
// allowedExtensions: ['xlsx', 'xls', 'csv'],
// );
//
// if (result != null) {
// PlatformFile file = result.files.first;
// Uint8List fileBytes = file.bytes!;
// // Use the fileBytes as needed
// print('File name: ${file.name}');
// print('File size: ${file.size}');
// print('File bytes: $fileBytes');
// _processExcelData(fileBytes);
// } else {
// // User canceled the picker
// }
// }
void _uploadFile(importPolicyName) async {
print('Test');
if (kIsWeb) {
print('kIsWeb');
final input = html.FileUploadInputElement();
input.accept = '.xlsx,.xls,.csv';
input.click();
input.onChange.listen((event) async {
final file = input.files!.first;
final reader = html.FileReader();
reader.readAsArrayBuffer(file);
await reader.onLoadEnd.first; // Wait for the file to be loaded
if (reader.readyState == html.FileReader.DONE) {
Uint8List? fileBytes = reader.result as Uint8List?;
if (fileBytes != null) {
setState(() {
fileName = file.name;
});
// Save fileBytes to local storage
final jsonString = json.encode(fileBytes);
html.window.localStorage['fileBytes'] = jsonString;
print('File Name: $fileName');
print('File Bytes: $fileBytes');
// Call the function to process Excel data here
_processExcelData(fileBytes, fileName);
}
}
});
} else {
// Handle non-web platforms here (e.g., show an error message)
print('File upload is only supported on web platforms.');
}
}
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
// Assuming dataArray is your array containing Excel data
// List<List<Data>> dataArray = decodeExcelData(fileBytes);
print(dataArray);
// print(dataArray[0].toString());
// Extract Name, Age, and City from the array
print(dataArray[0].length);
if (dataArray[0].length == 11) {
for (int i = 0; i < dataArray.length; i++) {
Map<String, dynamic> dataMap = {
"Sno": dataArray[i][0].value,
"Emp_Code": dataArray[i][1].value,
"Name": dataArray[i][2].value,
"DOJ": dataArray[i][3].value,
"Gender": dataArray[i][4].value,
"Relation": dataArray[i][5].value,
"DOB": dataArray[i][6].value,
"Mail": dataArray[i][7].value,
"Mobile": dataArray[i][8].value,
"SI": dataArray[i][9].value,
"Grade": dataArray[i][10].value,
};
if (i == 0) {
// print(dataMap);
validationArray.add(dataMap);
} else {
// print(dataMap);
extractedData.add(dataMap);
}
}
// Do something with extracted data (e.g., display in UI)
originalData = extractedData;
filteredData = List.from(originalData);
print('filteredData');
print(filteredData);
print(validationArray);
validationArray[0].forEach((key, value) {
print(key);
print(value);
if (key.toString().trim().toLowerCase() !=
value.toString().trim().toLowerCase()) {
// If key and value are not equal, increment mismatch count
columnIndexMismatchCount++;
print('columnIndexMismatchCount: $value');
}
if (value.toString() == 'null') {
// If value is null, increment missing count
columnMissingCount++;
print('Value: $value');
}
});
print('columnIndexMismatchCount: $columnIndexMismatchCount');
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 {
print('Some Column is Missing');
var columnMissingCount = 11 - dataArray[0].length;
missingColumnErrorMsg = columnMissingCount;
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
List<List<Data>> decodeExcelData(Uint8List fileBytes) {
print('decodeExcelData');
// Create an Excel instance from the fileBytes
final excel = Excel.decodeBytes(fileBytes);
print('decodeExcelData');
print(excel);
// Assuming there's only one sheet in the Excel file
final sheet = excel.tables.keys.first;
final table = excel.tables[sheet]!;
// Convert Excel table to a List<List<Data>>
// Convert Excel table to a List<List<Data>>
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>> 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 {
print('file');
print(file);
// Prepare form data
final formData = html.FormData();
formData.appendBlob('file', file);
// Send formData to API endpoint
final response = await html.HttpRequest.request(
'your_api_endpoint_here',
method: 'POST',
sendData: formData,
);
// Handle response as needed
print(response.responseText);
}
void _retrieveAndUploadFile() {
final jsonString = html.window.localStorage['fileBytes'];
if (jsonString != null) {
final decodedBytes = json.decode(jsonString);
if (decodedBytes is List<dynamic>) {
setState(() {
fileName = fileName ??
'Retrieved File'; // Provide a default name if fileName is null
});
sendExcelFIleTOAPI(
Uint8List.fromList(decodedBytes.cast<int>()),
fileName!,
);
}
}
}
Future<void> sendExcelFIleTOAPI(Uint8List fileBytes, String fileName) async {
print('submit');
print(fileBytes);
if (fileBytes == null) {
print('return');
return; // No file selected
} else {
print('else');
// // Prepare form data
// final formData = html.FormData();
// formData.appendBlob('file', html.Blob([fileBytes]), fileName);
// URL of the API where you want to send the file
final apiUrl = Environment.apiUrl + 'employeeUpload';
print('else');
// Create a multipart request
final request = http.MultipartRequest('POST', Uri.parse(apiUrl));
print('else');
// Attach the file to the request
// Set authorization token in headers
request.headers['Authorization'] = 'Bearer $_token';
// request.files.add(http.MultipartFile.fromBytes('file', fileBytes,
// filename: fileName));
print('Filename: $fileName');
request.files.add(http.MultipartFile.fromBytes(
'file',
fileBytes,
filename: fileName ?? 'default_filename.xlsx',
));
print('clintID: $clintID');
request.fields['client_id'] = clintID;
print('clientPolicyId: $clientPolicyId');
// if (policyFirstPart == 'GPA') {
request.fields['policy_id'] = clientPolicyId;
request.fields['client_branch_id'] = empRefId;
// } else {
// request.fields['policy_id'] = '3';
// }
print('request : $request');
// Send the request
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
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, 'Data Successfully Imported...');
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 {
// ToastHelper.showSuccessToast(
// context, 'Failed to upload file: ${response.reasonPhrase}');
ToastHelper.showSuccessToast(context, 'Something went wrong');
print('Failed to upload file: ${response.reasonPhrase}');
}
}
}
void search(String query) {
setState(() {
if (query.isEmpty) {
// If search query is empty, show all data
filteredData = List.from(originalData);
} else {
// Filter the data based on the search query
filteredData = originalData.where((item) {
// Implement your filter logic here, for example:
return item['Emp_Code'].toLowerCase().contains(query.toLowerCase());
}).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
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;
}
return Scaffold(
appBar: CustomAppBar(),
body: SafeArea(
child: Theme(
data: ThemeData(
canvasColor: Color(0xFFF4F7FE),
colorScheme: Theme.of(context).colorScheme.copyWith(
primary: Color(0xFFE26728),
background: Colors.red,
secondary: Color(0xFFE26728),
),
),
child: Container(
padding: const EdgeInsets.all(20),
color: Color(0xFFEFF3F6),
child: Card(
elevation: 0,
child: Column(
children: [
Expanded(
child: Stepper(
type: StepperType.horizontal,
currentStep: _currentStep,
controlsBuilder:
(BuildContext context, ControlsDetails controls) {
return Container(
alignment: Alignment.bottomCenter,
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
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)
ElevatedButton(
onPressed: () {
controls.onStepCancel!();
},
child: Text(
'Previous',
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 (_currentStep != 2)
ElevatedButton(
onPressed: _currentStep == 0
? (fileName != null
? controls.onStepContinue!
: null)
: (_currentStep == 1
? (missingColumnErrorMsg == 0 &&
columnIndexMismatchCount ==
0 &&
invalidRelationships == 0 &&
dobAgeCheckCount == 0
? controls.onStepContinue!
: null)
: null),
child: const Text(
'NEXT',
style: TextStyle(color: Colors.white),
),
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFFE26728),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
),
),
SizedBox(width: 10),
if (_currentStep == 2)
ElevatedButton(
onPressed: () {
_retrieveAndUploadFile();
},
child: Text(
'Submit',
style: TextStyle(color: Colors.white),
),
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFFE26728),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
),
),
],
),
);
},
onStepContinue: _currentStep == 2
? null
: () {
if (_currentStep == 0) {
// For the first step, allow continue if fileName is not null
if (fileName != null) {
setState(() {
_currentStep += 1;
});
}
} else if (_currentStep == 1) {
// For the second step, allow continue if both errors are 0
if (missingColumnErrorMsg == 0 &&
columnIndexMismatchCount == 0 &&
invalidRelationships == 0 &&
dobAgeCheckCount == 0) {
setState(() {
_currentStep += 1;
});
}
}
// setState(() {
// // Increment the current step when the user clicks continue
// if (_currentStep < 2) {
// _currentStep += 1;
// }
// });
},
onStepCancel: () {
setState(() {
// Decrement the current step when the user clicks cancel
if (_currentStep > 0) {
_currentStep -= 1;
}
});
},
steps: [
Step(
title: Container(
child: Text(
'Import Excel',
style: TextStyle(
color: Color(0xFFE26728),
),
),
),
content: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 12,
child: Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Expanded(
child: Text(
'$policy_name - ($policyType)',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight
.w600, // Adjust the font size as needed
color: Color(
0xFF181818), // Adjust the text color as needed
),
),
)
],
),
SizedBox(height: 20),
Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Expanded(
child: Container(
margin: EdgeInsets.symmetric(
horizontal: 150),
alignment: Alignment.center,
color: Colors.grey[200],
height:
250, // Adjust height as needed
child: DragTarget(
onAccept:
(html.File droppedFile) {
setState(() {
fileName = droppedFile.name;
});
_dragAndDropFile(droppedFile);
},
builder: (BuildContext context,
List<String?> candidateData,
List<dynamic>
rejectedData) {
return Container(
alignment: Alignment.center,
child: Column(
mainAxisAlignment:
MainAxisAlignment
.center,
children: [
// if (fileName == null)
// ElevatedButton(
// onPressed: () => {},
// child: Icon(
// Icons.download,
// color: Colors
// .grey), // You can replace the Icon with your custom button child
// style:
// ElevatedButton
// .styleFrom(
// shape:
// CircleBorder(), // Makes the button round
// padding:
// 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
? Column(
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(
fontSize:
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(
onPressed: () =>
_uploadFile(
'Policy Name'),
child: Text(
'Select File',
style: TextStyle(
color: Colors
.white),
),
style: ElevatedButton
.styleFrom(
backgroundColor:
Color(
0xFFE26728),
),
),
SizedBox(height: 20),
if (fileName == null)
Text(
'Supported Files : XLSX')
// Add more Text widgets for additional lines of text
],
),
);
},
),
),
),
],
),
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
),
),
),
)
]))
],
)
],
),
),
],
),
),
isActive: _currentStep == 0,
),
Step(
title: Text(
'Excel Validation',
style: TextStyle(color: Color(0xFFE26728)),
),
content: Padding(
padding: EdgeInsets.only(
top: 30,
bottom: 30,
left: 300,
right:
300), // Adjust the horizontal padding as needed
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_buildRowWithIcon(
missingColumnErrorMsg == 0
? Icons.check_circle
: Icons.error,
'No of column missing : $missingColumnErrorMsg Column',
iconColor: missingColumnErrorMsg == 0
? Colors.green
: Colors
.red, // Set color based on condition
),
if (missingColumnErrorMsg == 0)
_buildRowWithIcon(
columnIndexMismatchCount == 0
? Icons.check_circle
: Icons.error,
'Mismatch in Column Order : $columnIndexMismatchCount - Column',
iconColor: columnIndexMismatchCount == 0
? Colors.green
: Colors.red,
),
_buildRowWithIcon(
invalidRelationships == 0
? Icons.check_circle
: Icons.error,
'Invalid Relationships : $invalidRelationships - Rows',
iconColor: invalidRelationships == 0
? Colors.green
: Colors.red,
),
_buildRowWithIcon(
dobAgeCheckCount == 0
? Icons.check_circle
: Icons.error,
'Age Config - $dobAgeCheckCount - Rows',
iconColor: dobAgeCheckCount == 0
? Colors.green
: Colors.red,
),
],
),
),
isActive: _currentStep == 1,
),
Step(
title: Text(
'Preview',
style: TextStyle(color: Color(0xFFE26728)),
),
content: 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:
search, // Call the search method on text change
),
)),
),
],
),
SizedBox(height: 20),
Row(
children: [
Expanded(
child: SingleChildScrollView(
child: _buildDataTable(),
),
)
],
),
],
),
isActive: _currentStep == 2,
),
],
),
),
// SizedBox(height: 20),
// if (_currentStep == 2)
// Align(
// alignment: Alignment.bottomRight,
// child: ElevatedButton(
// onPressed: () {
// sendExcelFIleTOAPI();
// },
// child: Text(
// 'Complete',
// style: TextStyle(color: Colors.white),
// ),
// style: ElevatedButton.styleFrom(
// backgroundColor: Color(0xFFE26728),
// ),
// ),
// ),
// SizedBox(height: 20),
],
),
),
),
),
),
);
}
Widget _buildDataTable() {
if (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('S.No')),
DataColumn(label: Text('Employee ID')),
DataColumn(label: Text('Name')),
DataColumn(label: Text('Date of Joining')),
DataColumn(label: Text('Gender')),
DataColumn(label: Text('Relationship')),
DataColumn(label: Text('Date of Birth')),
DataColumn(label: Text('Mail')),
DataColumn(label: Text('Mobile No')),
DataColumn(label: Text('SI')),
DataColumn(label: Text('Grade')),
],
source: _DependenceDataSource0(filteredData),
),
);
}
}
Widget _buildRowWithIcon(IconData iconData, String text,
{Color iconColor = Colors.black}) {
return Row(
children: [
Icon(
iconData,
color: iconColor, // Set color based on the parameter
),
SizedBox(width: 8), // Add some space between icon and text
Text(text), // Text widget
],
);
}
}
class Data {
final dynamic value;
final int row;
final int column;
final String sheet;
Data(this.value, this.row, this.column, this.sheet);
}
class _DependenceDataSource0 extends DataTableSource {
final List<Map<String, dynamic>> _data;
_DependenceDataSource0(this._data);
@override
DataRow getRow(int index) {
final row = _data[index];
String dob = row['DOB'] != null ? formatDate(row['DOB']) : 'N/A';
String doj = row['DOJ'] != null ? formatDate(row['DOJ']) : 'N/A';
return DataRow(cells: [
DataCell(Text(row['Sno'].toString())),
DataCell(Text(row['Emp_Code'].toString())),
DataCell(Text(row['Name'].toString())),
DataCell(Text(doj)),
DataCell(Text(row['Gender']?.toString() ?? 'N/A')),
DataCell(Text(row['Relation']?.toString() ?? 'N/A')),
DataCell(Text(dob)),
DataCell(Text(row['Mail']?.toString() ?? 'N/A')),
DataCell(Text(row['Mobile']?.toString() ?? 'N/A')),
DataCell(Text(row['SI']?.toString() ?? 'N/A')),
DataCell(Text(row['Grade']?.toString() ?? 'N/A')),
]);
}
@override
bool get isRowCountApproximate => false;
@override
int get rowCount => _data.length;
@override
int get selectedRowCount => 0;
String formatDate(dynamic dateValue) {
if (dateValue is String) {
// If the date is already in string format
DateTime dateTime = DateTime.parse(dateValue);
return DateFormat('dd-MM-yyyy').format(dateTime);
} else if (dateValue is DateCellValue) {
// 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';
}
}
}