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