Refactor attendance button UI and improve feedback messages
This commit is contained in:
parent
5462f0aa24
commit
932cfe81e7
@ -279,75 +279,86 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
|
|||||||
.uploadingStates[employee.employeeId]?.value ??
|
.uploadingStates[employee.employeeId]?.value ??
|
||||||
false;
|
false;
|
||||||
final controller = attendanceController;
|
final controller = attendanceController;
|
||||||
return SizedBox(
|
return ConstrainedBox(
|
||||||
width: 90,
|
constraints: const BoxConstraints(minWidth: 100, maxWidth: 140),
|
||||||
height: 25,
|
child: SizedBox(
|
||||||
child: ElevatedButton(
|
height: 30,
|
||||||
onPressed: isUploading
|
child: ElevatedButton(
|
||||||
? null
|
onPressed: isUploading
|
||||||
: () async {
|
? null
|
||||||
controller.uploadingStates[employee.employeeId] =
|
: () async {
|
||||||
RxBool(true);
|
controller.uploadingStates[employee.employeeId] =
|
||||||
if (controller.selectedProjectId == null) {
|
RxBool(true);
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
if (controller.selectedProjectId == null) {
|
||||||
const SnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
content: Text("Please select a project first")),
|
const SnackBar(
|
||||||
|
content:
|
||||||
|
Text("Please select a project first")),
|
||||||
|
);
|
||||||
|
controller.uploadingStates[employee.employeeId] =
|
||||||
|
RxBool(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final updatedAction =
|
||||||
|
(activity == 0 || activity == 4) ? 0 : 1;
|
||||||
|
final actionText = (updatedAction == 0)
|
||||||
|
? ButtonActions.checkIn
|
||||||
|
: ButtonActions.checkOut;
|
||||||
|
final success =
|
||||||
|
await controller.captureAndUploadAttendance(
|
||||||
|
employee.id,
|
||||||
|
employee.employeeId,
|
||||||
|
controller.selectedProjectId!,
|
||||||
|
comment: actionText,
|
||||||
|
action: updatedAction,
|
||||||
);
|
);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(success
|
||||||
|
? 'Attendance marked successfully!'
|
||||||
|
: 'Image upload failed.'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
controller.uploadingStates[employee.employeeId] =
|
controller.uploadingStates[employee.employeeId] =
|
||||||
RxBool(false);
|
RxBool(false);
|
||||||
return;
|
|
||||||
}
|
if (success) {
|
||||||
final updatedAction =
|
await Future.wait([
|
||||||
(activity == 0 || activity == 4) ? 0 : 1;
|
controller.fetchEmployeesByProject(
|
||||||
final actionText = (updatedAction == 0)
|
controller.selectedProjectId!),
|
||||||
? ButtonActions.checkIn
|
controller.fetchAttendanceLogs(
|
||||||
: ButtonActions.checkOut;
|
controller.selectedProjectId!),
|
||||||
final success =
|
controller.fetchProjectData(
|
||||||
await controller.captureAndUploadAttendance(
|
controller.selectedProjectId!),
|
||||||
employee.id,
|
]);
|
||||||
employee.employeeId,
|
controller.update();
|
||||||
controller.selectedProjectId!,
|
}
|
||||||
comment: actionText,
|
},
|
||||||
action: updatedAction,
|
style: ElevatedButton.styleFrom(
|
||||||
);
|
backgroundColor: AttendanceActionColors.colors[buttonText],
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
textStyle: const TextStyle(fontSize: 12),
|
||||||
SnackBar(
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
content: Text(success
|
),
|
||||||
? 'Attendance marked successfully!'
|
child: isUploading
|
||||||
: 'Image upload failed.'),
|
? const SizedBox(
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
valueColor:
|
||||||
|
AlwaysStoppedAnimation<Color>(Colors.white),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: Text(
|
||||||
|
buttonText,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
);
|
|
||||||
|
|
||||||
controller.uploadingStates[employee.employeeId] =
|
|
||||||
RxBool(false);
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
await Future.wait([
|
|
||||||
controller.fetchEmployeesByProject(
|
|
||||||
controller.selectedProjectId!),
|
|
||||||
controller.fetchAttendanceLogs(
|
|
||||||
controller.selectedProjectId!),
|
|
||||||
controller.fetchProjectData(
|
|
||||||
controller.selectedProjectId!),
|
|
||||||
]);
|
|
||||||
controller.update();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: AttendanceActionColors.colors[buttonText],
|
|
||||||
textStyle: const TextStyle(fontSize: 12),
|
|
||||||
),
|
|
||||||
child: isUploading
|
|
||||||
? const SizedBox(
|
|
||||||
width: 16,
|
|
||||||
height: 16,
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor:
|
|
||||||
AlwaysStoppedAnimation<Color>(Colors.white),
|
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
: Text(buttonText),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
@ -645,77 +656,100 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
|
|||||||
isApprovedButNotToday: isApprovedButNotToday,
|
isApprovedButNotToday: isApprovedButNotToday,
|
||||||
);
|
);
|
||||||
|
|
||||||
return SizedBox(
|
return ConstrainedBox(
|
||||||
width: 90,
|
constraints: const BoxConstraints(minWidth: 100, maxWidth: 150),
|
||||||
height: 25,
|
child: SizedBox(
|
||||||
child: ElevatedButton(
|
height: 30,
|
||||||
onPressed: isButtonDisabled
|
child: ElevatedButton(
|
||||||
? null
|
onPressed: isButtonDisabled
|
||||||
: () async {
|
? null
|
||||||
attendanceController.uploadingStates[uniqueLogKey] =
|
: () async {
|
||||||
RxBool(true);
|
|
||||||
|
|
||||||
if (attendanceController.selectedProjectId == null) {
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
const SnackBar(
|
|
||||||
content:
|
|
||||||
Text("Please select a project first")),
|
|
||||||
);
|
|
||||||
attendanceController.uploadingStates[uniqueLogKey] =
|
attendanceController.uploadingStates[uniqueLogKey] =
|
||||||
RxBool(false);
|
RxBool(true);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int updatedAction;
|
if (attendanceController.selectedProjectId ==
|
||||||
String actionText;
|
null) {
|
||||||
bool imageCapture = true;
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content:
|
||||||
|
Text("Please select a project first"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
attendanceController
|
||||||
|
.uploadingStates[uniqueLogKey] =
|
||||||
|
RxBool(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (log.activity) {
|
int updatedAction;
|
||||||
case 0:
|
String actionText;
|
||||||
updatedAction = 0;
|
bool imageCapture = true;
|
||||||
actionText = ButtonActions.checkIn;
|
|
||||||
break;
|
switch (log.activity) {
|
||||||
case 1:
|
case 0:
|
||||||
if (log.checkOut == null &&
|
updatedAction = 0;
|
||||||
AttendanceButtonHelper.isOlderThanDays(
|
actionText = ButtonActions.checkIn;
|
||||||
log.checkIn, 2)) {
|
break;
|
||||||
|
case 1:
|
||||||
|
if (log.checkOut == null &&
|
||||||
|
AttendanceButtonHelper.isOlderThanDays(
|
||||||
|
log.checkIn, 2)) {
|
||||||
|
updatedAction = 2;
|
||||||
|
actionText = ButtonActions.requestRegularize;
|
||||||
|
imageCapture = false;
|
||||||
|
} else if (log.checkOut != null &&
|
||||||
|
AttendanceButtonHelper.isOlderThanDays(
|
||||||
|
log.checkOut, 2)) {
|
||||||
|
updatedAction = 2;
|
||||||
|
actionText = ButtonActions.requestRegularize;
|
||||||
|
} else {
|
||||||
|
updatedAction = 1;
|
||||||
|
actionText = ButtonActions.checkOut;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
updatedAction = 2;
|
updatedAction = 2;
|
||||||
actionText = ButtonActions.requestRegularize;
|
actionText = ButtonActions.requestRegularize;
|
||||||
imageCapture = false;
|
break;
|
||||||
} else if (log.checkOut != null &&
|
case 4:
|
||||||
AttendanceButtonHelper.isOlderThanDays(
|
updatedAction = isTodayApproved ? 0 : 0;
|
||||||
log.checkOut, 2)) {
|
actionText = ButtonActions.checkIn;
|
||||||
updatedAction = 2;
|
break;
|
||||||
actionText = ButtonActions.requestRegularize;
|
default:
|
||||||
} else {
|
updatedAction = 0;
|
||||||
updatedAction = 1;
|
actionText = "Unknown Action";
|
||||||
actionText = ButtonActions.checkOut;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
if (actionText == ButtonActions.requestRegularize) {
|
||||||
|
final selectedTime =
|
||||||
|
await showTimePickerForRegularization(
|
||||||
|
context: context,
|
||||||
|
checkInTime: log.checkIn!,
|
||||||
|
);
|
||||||
|
if (selectedTime != null) {
|
||||||
|
final formattedSelectedTime =
|
||||||
|
DateFormat("hh:mm a").format(selectedTime);
|
||||||
|
success = await attendanceController
|
||||||
|
.captureAndUploadAttendance(
|
||||||
|
log.id,
|
||||||
|
log.employeeId,
|
||||||
|
attendanceController.selectedProjectId!,
|
||||||
|
comment: actionText,
|
||||||
|
action: updatedAction,
|
||||||
|
imageCapture: imageCapture,
|
||||||
|
markTime: formattedSelectedTime,
|
||||||
|
);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(success
|
||||||
|
? '${actionText.toLowerCase()} marked successfully!'
|
||||||
|
: 'Failed to ${actionText.toLowerCase()}'),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
case 2:
|
|
||||||
updatedAction = 2;
|
|
||||||
actionText = ButtonActions.requestRegularize;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
updatedAction = isTodayApproved ? 0 : 0;
|
|
||||||
actionText = ButtonActions.checkIn;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
updatedAction = 0;
|
|
||||||
actionText = "Unknown Action";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
if (actionText == ButtonActions.requestRegularize) {
|
|
||||||
final selectedTime =
|
|
||||||
await showTimePickerForRegularization(
|
|
||||||
context: context,
|
|
||||||
checkInTime: log.checkIn!,
|
|
||||||
);
|
|
||||||
if (selectedTime != null) {
|
|
||||||
final formattedSelectedTime =
|
|
||||||
DateFormat("hh:mm a").format(selectedTime);
|
|
||||||
success = await attendanceController
|
success = await attendanceController
|
||||||
.captureAndUploadAttendance(
|
.captureAndUploadAttendance(
|
||||||
log.id,
|
log.id,
|
||||||
@ -724,82 +758,70 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
|
|||||||
comment: actionText,
|
comment: actionText,
|
||||||
action: updatedAction,
|
action: updatedAction,
|
||||||
imageCapture: imageCapture,
|
imageCapture: imageCapture,
|
||||||
markTime: formattedSelectedTime,
|
|
||||||
);
|
);
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(success
|
content: Text(success
|
||||||
? '${actionText.toLowerCase()} marked successfully!'
|
? '${actionText.toLowerCase()} marked successfully!'
|
||||||
: 'Failed to ${actionText.toLowerCase()}.'),
|
: 'Failed to ${actionText.toLowerCase()}'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
success = await attendanceController
|
|
||||||
.captureAndUploadAttendance(
|
|
||||||
log.id,
|
|
||||||
log.employeeId,
|
|
||||||
attendanceController.selectedProjectId!,
|
|
||||||
comment: actionText,
|
|
||||||
action: updatedAction,
|
|
||||||
imageCapture: imageCapture,
|
|
||||||
);
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content: Text(success
|
|
||||||
? '${actionText.toLowerCase()} marked successfully!'
|
|
||||||
: 'Failed to ${actionText.toLowerCase()}.'),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
attendanceController.uploadingStates[uniqueLogKey] =
|
attendanceController.uploadingStates[uniqueLogKey] =
|
||||||
RxBool(false);
|
RxBool(false);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
attendanceController.fetchEmployeesByProject(
|
attendanceController.fetchEmployeesByProject(
|
||||||
attendanceController.selectedProjectId!);
|
attendanceController.selectedProjectId!);
|
||||||
attendanceController.fetchAttendanceLogs(
|
attendanceController.fetchAttendanceLogs(
|
||||||
attendanceController.selectedProjectId!);
|
attendanceController.selectedProjectId!);
|
||||||
await attendanceController.fetchRegularizationLogs(
|
await attendanceController
|
||||||
attendanceController.selectedProjectId!);
|
.fetchRegularizationLogs(
|
||||||
await attendanceController.fetchProjectData(
|
attendanceController.selectedProjectId!);
|
||||||
attendanceController.selectedProjectId!);
|
await attendanceController.fetchProjectData(
|
||||||
attendanceController.update();
|
attendanceController.selectedProjectId!);
|
||||||
}
|
attendanceController.update();
|
||||||
},
|
}
|
||||||
style: ElevatedButton.styleFrom(
|
},
|
||||||
backgroundColor: AttendanceButtonHelper.getButtonColor(
|
style: ElevatedButton.styleFrom(
|
||||||
isYesterday: isYesterday,
|
backgroundColor: AttendanceButtonHelper.getButtonColor(
|
||||||
isTodayApproved: isTodayApproved,
|
isYesterday: isYesterday,
|
||||||
activity: log.activity,
|
isTodayApproved: isTodayApproved,
|
||||||
|
activity: log.activity,
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 4, horizontal: 6),
|
||||||
|
textStyle: const TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
padding:
|
child: isUploading
|
||||||
const EdgeInsets.symmetric(vertical: 4, horizontal: 6),
|
? const SizedBox(
|
||||||
textStyle: const TextStyle(fontSize: 12),
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
valueColor:
|
||||||
|
AlwaysStoppedAnimation<Color>(Colors.white),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: Text(
|
||||||
|
AttendanceButtonHelper.getButtonText(
|
||||||
|
activity: log.activity,
|
||||||
|
checkIn: log.checkIn,
|
||||||
|
checkOut: log.checkOut,
|
||||||
|
isTodayApproved: isTodayApproved,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: isUploading
|
|
||||||
? const SizedBox(
|
|
||||||
width: 16,
|
|
||||||
height: 16,
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor:
|
|
||||||
AlwaysStoppedAnimation<Color>(Colors.white),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Text(
|
|
||||||
AttendanceButtonHelper.getButtonText(
|
|
||||||
activity: log.activity,
|
|
||||||
checkIn: log.checkIn,
|
|
||||||
checkOut: log.checkOut,
|
|
||||||
isTodayApproved: isTodayApproved,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
)
|
),
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -917,129 +939,165 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
// Approve Button
|
// Approve Button
|
||||||
ElevatedButton(
|
ConstrainedBox(
|
||||||
onPressed: isUploading // Disable button if uploading
|
constraints: const BoxConstraints(minWidth: 70, maxWidth: 120),
|
||||||
? null
|
child: SizedBox(
|
||||||
: () async {
|
height: 30,
|
||||||
if (attendanceController.selectedProjectId == null) {
|
child: ElevatedButton(
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
onPressed: isUploading
|
||||||
const SnackBar(
|
? null
|
||||||
content: Text("Please select a project first")),
|
: () async {
|
||||||
);
|
if (attendanceController.selectedProjectId ==
|
||||||
return;
|
null) {
|
||||||
}
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content:
|
||||||
|
Text("Please select a project first")),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
attendanceController.uploadingStates[uniqueLogKey]
|
attendanceController
|
||||||
?.value = true; // Start loading
|
.uploadingStates[uniqueLogKey]?.value = true;
|
||||||
final success = await attendanceController
|
|
||||||
.captureAndUploadAttendance(
|
|
||||||
log.id,
|
|
||||||
log.employeeId,
|
|
||||||
attendanceController.selectedProjectId!,
|
|
||||||
comment: "Accepted",
|
|
||||||
action: 4, // Approve action
|
|
||||||
imageCapture: false,
|
|
||||||
);
|
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
final success = await attendanceController
|
||||||
SnackBar(
|
.captureAndUploadAttendance(
|
||||||
content: Text(success
|
log.id,
|
||||||
? 'Approval marked successfully!'
|
log.employeeId,
|
||||||
: 'Failed to mark approval.')),
|
attendanceController.selectedProjectId!,
|
||||||
);
|
comment: "Accepted",
|
||||||
|
action: 4,
|
||||||
|
imageCapture: false,
|
||||||
|
);
|
||||||
|
|
||||||
if (success) {
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
attendanceController.fetchEmployeesByProject(
|
SnackBar(
|
||||||
attendanceController.selectedProjectId!);
|
content: Text(success
|
||||||
attendanceController.fetchAttendanceLogs(
|
? 'Approval marked successfully!'
|
||||||
attendanceController.selectedProjectId!);
|
: 'Failed to mark approval.'),
|
||||||
await attendanceController.fetchRegularizationLogs(
|
),
|
||||||
attendanceController.selectedProjectId!);
|
);
|
||||||
await attendanceController.fetchProjectData(
|
|
||||||
attendanceController.selectedProjectId!);
|
|
||||||
}
|
|
||||||
|
|
||||||
attendanceController.uploadingStates[uniqueLogKey]
|
if (success) {
|
||||||
?.value = false; // End loading
|
attendanceController.fetchEmployeesByProject(
|
||||||
},
|
attendanceController.selectedProjectId!);
|
||||||
style: ElevatedButton.styleFrom(
|
attendanceController.fetchAttendanceLogs(
|
||||||
backgroundColor:
|
attendanceController.selectedProjectId!);
|
||||||
AttendanceActionColors.colors[ButtonActions.approve],
|
await attendanceController
|
||||||
padding:
|
.fetchRegularizationLogs(
|
||||||
const EdgeInsets.symmetric(vertical: 4, horizontal: 6),
|
attendanceController.selectedProjectId!);
|
||||||
minimumSize: const Size(60, 20),
|
await attendanceController.fetchProjectData(
|
||||||
textStyle: const TextStyle(fontSize: 12),
|
attendanceController.selectedProjectId!);
|
||||||
|
}
|
||||||
|
|
||||||
|
attendanceController
|
||||||
|
.uploadingStates[uniqueLogKey]?.value = false;
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor:
|
||||||
|
AttendanceActionColors.colors[ButtonActions.approve],
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 4, horizontal: 6),
|
||||||
|
minimumSize: const Size(60, 20),
|
||||||
|
textStyle: const TextStyle(fontSize: 12),
|
||||||
|
),
|
||||||
|
child: isUploading
|
||||||
|
? const SizedBox(
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
child: CircularProgressIndicator(strokeWidth: 2),
|
||||||
|
)
|
||||||
|
: FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: const Text(
|
||||||
|
"Approve",
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: isUploading
|
|
||||||
? const CircularProgressIndicator(
|
|
||||||
strokeWidth:
|
|
||||||
2) // Show loading indicator while uploading
|
|
||||||
: const Text("Approve"),
|
|
||||||
),
|
),
|
||||||
|
|
||||||
// Space between buttons
|
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
|
|
||||||
// Reject Button
|
// Reject Button
|
||||||
ElevatedButton(
|
ConstrainedBox(
|
||||||
onPressed: isUploading // Disable button if uploading
|
constraints: const BoxConstraints(minWidth: 70, maxWidth: 120),
|
||||||
? null
|
child: SizedBox(
|
||||||
: () async {
|
height: 30,
|
||||||
if (attendanceController.selectedProjectId == null) {
|
child: ElevatedButton(
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
onPressed: isUploading
|
||||||
const SnackBar(
|
? null
|
||||||
content: Text("Please select a project first")),
|
: () async {
|
||||||
);
|
if (attendanceController.selectedProjectId ==
|
||||||
return;
|
null) {
|
||||||
}
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content:
|
||||||
|
Text("Please select a project first")),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
attendanceController.uploadingStates[uniqueLogKey]
|
attendanceController
|
||||||
?.value = true; // Start loading
|
.uploadingStates[uniqueLogKey]?.value = true;
|
||||||
|
|
||||||
final success = await attendanceController
|
final success = await attendanceController
|
||||||
.captureAndUploadAttendance(
|
.captureAndUploadAttendance(
|
||||||
log.id,
|
log.id,
|
||||||
log.employeeId,
|
log.employeeId,
|
||||||
attendanceController.selectedProjectId!,
|
attendanceController.selectedProjectId!,
|
||||||
comment: "Rejected",
|
comment: "Rejected",
|
||||||
action: 5, // Reject action
|
action: 5,
|
||||||
imageCapture: false,
|
imageCapture: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
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(
|
||||||
attendanceController.selectedProjectId!);
|
attendanceController.selectedProjectId!);
|
||||||
await attendanceController.fetchRegularizationLogs(
|
await attendanceController
|
||||||
attendanceController.selectedProjectId!);
|
.fetchRegularizationLogs(
|
||||||
await attendanceController.fetchProjectData(
|
attendanceController.selectedProjectId!);
|
||||||
attendanceController.selectedProjectId!);
|
await attendanceController.fetchProjectData(
|
||||||
}
|
attendanceController.selectedProjectId!);
|
||||||
|
}
|
||||||
|
|
||||||
attendanceController.uploadingStates[uniqueLogKey]
|
attendanceController
|
||||||
?.value = false; // End loading
|
.uploadingStates[uniqueLogKey]?.value = false;
|
||||||
},
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
AttendanceActionColors.colors[ButtonActions.reject],
|
AttendanceActionColors.colors[ButtonActions.reject],
|
||||||
padding:
|
padding: const EdgeInsets.symmetric(
|
||||||
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: isUploading
|
||||||
|
? const SizedBox(
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
child: CircularProgressIndicator(strokeWidth: 2),
|
||||||
|
)
|
||||||
|
: FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: const Text(
|
||||||
|
"Reject",
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: isUploading
|
|
||||||
? const CircularProgressIndicator(
|
|
||||||
strokeWidth:
|
|
||||||
2) // Show loading indicator while uploading
|
|
||||||
: const Text("Reject"),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user