added loading for regularization tab

This commit is contained in:
Vaibhav Surve 2025-05-06 17:53:57 +05:30
parent defd753ab0
commit 488a921f45

View File

@ -860,103 +860,108 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
} }
Widget regularizationTab(BuildContext context) { Widget regularizationTab(BuildContext context) {
final attendanceController = Get.find<AttendanceController>(); final attendanceController = Get.find<AttendanceController>();
final columns = [ final columns = [
DataColumn(label: MyText.labelLarge('Name', color: contentTheme.primary)), DataColumn(label: MyText.labelLarge('Name', color: contentTheme.primary)),
DataColumn( DataColumn(
label: MyText.labelLarge('Check-In', color: contentTheme.primary)), label: MyText.labelLarge('Check-In', color: contentTheme.primary)),
DataColumn( DataColumn(
label: MyText.labelLarge('Check-Out', color: contentTheme.primary)), label: MyText.labelLarge('Check-Out', color: contentTheme.primary)),
DataColumn( DataColumn(
label: MyText.labelLarge('Action', color: contentTheme.primary)), label: MyText.labelLarge('Action', color: contentTheme.primary)),
]; ];
final rows = attendanceController.regularizationLogs final rows = attendanceController.regularizationLogs
.mapIndexed((index, log) => DataRow(cells: [ .mapIndexed((index, log) {
DataCell( final uniqueLogKey = '${log.id}-${log.employeeId}'; // Unique key for each log
Column( final isUploading = attendanceController.uploadingStates[uniqueLogKey]?.value ?? false; // Check the upload state
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, return DataRow(cells: [
children: [ DataCell(
MyText.bodyMedium(log.name, fontWeight: 600), Column(
SizedBox(height: 2), crossAxisAlignment: CrossAxisAlignment.start,
MyText.bodySmall(log.role, color: Colors.grey), mainAxisAlignment: MainAxisAlignment.center,
], children: [
MyText.bodyMedium(log.name, fontWeight: 600),
SizedBox(height: 2),
MyText.bodySmall(log.role, color: Colors.grey),
],
),
),
DataCell(
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(
log.checkIn != null
? DateFormat('dd/MMM/yyyy').format(log.checkIn!)
: '-',
fontWeight: 600,
), ),
), MyText.bodyMedium(
DataCell( log.checkIn != null
Column( ? DateFormat('hh:mm a').format(log.checkIn!)
mainAxisAlignment: MainAxisAlignment.center, : '',
crossAxisAlignment: CrossAxisAlignment.start, fontWeight: 600,
children: [
MyText.bodyMedium(
log.checkIn != null
? DateFormat('dd/MMM/yyyy').format(log.checkIn!)
: '-',
fontWeight: 600,
),
MyText.bodyMedium(
log.checkIn != null
? DateFormat('hh:mm a').format(log.checkIn!)
: '',
fontWeight: 600,
),
],
), ),
), ],
DataCell( ),
Column( ),
mainAxisAlignment: MainAxisAlignment.center, DataCell(
crossAxisAlignment: CrossAxisAlignment.start, Column(
children: [ mainAxisAlignment: MainAxisAlignment.center,
MyText.bodyMedium( crossAxisAlignment: CrossAxisAlignment.start,
log.checkOut != null children: [
? DateFormat('dd MMM yyyy').format(log.checkOut!) MyText.bodyMedium(
: '-', log.checkOut != null
fontWeight: 600, ? DateFormat('dd MMM yyyy').format(log.checkOut!)
), : '-',
MyText.bodyMedium( fontWeight: 600,
log.checkOut != null
? DateFormat('hh:mm a').format(log.checkOut!)
: '',
fontWeight: 600,
),
],
), ),
), MyText.bodyMedium(
DataCell( log.checkOut != null
Row( ? DateFormat('hh:mm a').format(log.checkOut!)
children: [ : '',
// Approve Button fontWeight: 600,
ElevatedButton( ),
onPressed: () async { ],
if (attendanceController.selectedProjectId == null) { ),
ScaffoldMessenger.of(context).showSnackBar( ),
const SnackBar( DataCell(
content: Text("Please select a project first")), Row(
children: [
// Approve Button
ElevatedButton(
onPressed: isUploading // Disable button if uploading
? null
: () async {
if (attendanceController.selectedProjectId == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Please select a project first")),
);
return;
}
attendanceController.uploadingStates[uniqueLogKey]?.value = true; // Start loading
final success = await attendanceController.captureAndUploadAttendance(
log.id,
log.employeeId,
attendanceController.selectedProjectId!,
comment: "Accepted",
action: 4, // Approve action
imageCapture: false,
); );
return;
}
final success = await attendanceController ScaffoldMessenger.of(context).showSnackBar(
.captureAndUploadAttendance(
log.id,
log.employeeId,
attendanceController.selectedProjectId!,
comment: "Accepted",
action: 4, // Approve action
imageCapture: false,
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text(success content: Text(success
? 'Approval marked successfully!' ? 'Approval marked successfully!'
: 'Failed to mark approval.')), : 'Failed to mark approval.')),
); );
if (success) { if (success) {
attendanceController.fetchEmployeesByProject( attendanceController.fetchEmployeesByProject(
attendanceController.selectedProjectId!); attendanceController.selectedProjectId!);
attendanceController.fetchAttendanceLogs( attendanceController.fetchAttendanceLogs(
@ -965,51 +970,57 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
attendanceController.selectedProjectId!); attendanceController.selectedProjectId!);
await attendanceController.fetchProjectData( await attendanceController.fetchProjectData(
attendanceController.selectedProjectId!); attendanceController.selectedProjectId!);
} }
},
style: ElevatedButton.styleFrom( attendanceController.uploadingStates[uniqueLogKey]?.value = false; // End loading
},
style: ElevatedButton.styleFrom(
backgroundColor: AttendanceActionColors backgroundColor: AttendanceActionColors
.colors[ButtonActions.approve], .colors[ButtonActions.approve],
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
vertical: 4, horizontal: 6), vertical: 4, horizontal: 6),
minimumSize: const Size(60, 20), minimumSize: const Size(60, 20),
textStyle: const TextStyle(fontSize: 12), textStyle: const TextStyle(fontSize: 12),
), ),
child: const Text("Approve"), child: isUploading
), ? const CircularProgressIndicator(strokeWidth: 2) // Show loading indicator while uploading
: const Text("Approve"),
),
// Space between buttons // Space between buttons
const SizedBox(width: 8), const SizedBox(width: 8),
// Reject Button // Reject Button
ElevatedButton( ElevatedButton(
onPressed: () async { onPressed: isUploading // Disable button if uploading
if (attendanceController.selectedProjectId == null) { ? null
ScaffoldMessenger.of(context).showSnackBar( : () async {
const SnackBar( if (attendanceController.selectedProjectId == null) {
content: Text("Please select a project first")), ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Please select a project first")),
);
return;
}
attendanceController.uploadingStates[uniqueLogKey]?.value = true; // Start loading
final success = await attendanceController.captureAndUploadAttendance(
log.id,
log.employeeId,
attendanceController.selectedProjectId!,
comment: "Rejected",
action: 5, // Reject action
imageCapture: false,
); );
return;
}
final success = await attendanceController ScaffoldMessenger.of(context).showSnackBar(
.captureAndUploadAttendance(
log.id,
log.employeeId,
attendanceController.selectedProjectId!,
comment: "Rejected",
action: 5, // Reject action
imageCapture: false,
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text(success content: Text(success
? 'Attendance marked as Rejected!' ? 'Attendance marked as Rejected!'
: 'Failed to mark attendance.')), : 'Failed to mark attendance.')),
); );
if (success) { if (success) {
attendanceController.fetchEmployeesByProject( attendanceController.fetchEmployeesByProject(
attendanceController.selectedProjectId!); attendanceController.selectedProjectId!);
attendanceController.fetchAttendanceLogs( attendanceController.fetchAttendanceLogs(
@ -1018,48 +1029,53 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
attendanceController.selectedProjectId!); attendanceController.selectedProjectId!);
await attendanceController.fetchProjectData( await attendanceController.fetchProjectData(
attendanceController.selectedProjectId!); attendanceController.selectedProjectId!);
} }
},
style: ElevatedButton.styleFrom( attendanceController.uploadingStates[uniqueLogKey]?.value = false; // End loading
},
style: ElevatedButton.styleFrom(
backgroundColor: backgroundColor:
AttendanceActionColors.colors[ButtonActions.reject], AttendanceActionColors.colors[ButtonActions.reject],
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
vertical: 4, horizontal: 6), vertical: 4, horizontal: 6),
minimumSize: const Size(60, 20), minimumSize: const Size(60, 20),
textStyle: const TextStyle(fontSize: 12), textStyle: const TextStyle(fontSize: 12),
), ),
child: const Text("Reject"), child: isUploading
), ? const CircularProgressIndicator(strokeWidth: 2) // Show loading indicator while uploading
], : const Text("Reject"),
), ),
), ],
])) ),
.toList(); ),
]);
})
.toList();
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
), ),
if (attendanceController.regularizationLogs.isEmpty) if (attendanceController.regularizationLogs.isEmpty)
Expanded( Expanded(
child: Center( child: Center(
child: MyText.bodySmall("No Regularization Records Found", child: MyText.bodySmall("No Regularization Records Found",
fontWeight: 600), fontWeight: 600),
), ),
) )
else else
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
child: MyPaginatedTable( child: MyPaginatedTable(
columns: columns, columns: columns,
rows: rows, rows: rows,
columnSpacing: 15.0, columnSpacing: 15.0,
),
), ),
), ),
], ),
); ],
} );
}
} }