148 lines
4.4 KiB
Dart
148 lines
4.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:marco/helpers/utils/attendance_actions.dart';
|
|
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
|
import 'package:marco/controller/project_controller.dart';
|
|
import 'package:get/get.dart';
|
|
|
|
enum ButtonActions { approve, reject }
|
|
|
|
class RegularizeActionButton extends StatefulWidget {
|
|
final dynamic attendanceController;
|
|
final dynamic log;
|
|
final String uniqueLogKey;
|
|
final ButtonActions action;
|
|
|
|
const RegularizeActionButton({
|
|
Key? key,
|
|
required this.attendanceController,
|
|
required this.log,
|
|
required this.uniqueLogKey,
|
|
required this.action,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
State<RegularizeActionButton> createState() => _RegularizeActionButtonState();
|
|
}
|
|
|
|
String capitalizeFirstLetter(String text) {
|
|
if (text.isEmpty) return text;
|
|
return text[0].toUpperCase() + text.substring(1);
|
|
}
|
|
|
|
class _RegularizeActionButtonState extends State<RegularizeActionButton> {
|
|
bool isUploading = false;
|
|
|
|
static const Map<ButtonActions, String> _buttonTexts = {
|
|
ButtonActions.approve: "Approve",
|
|
ButtonActions.reject: "Reject",
|
|
};
|
|
|
|
static const Map<ButtonActions, String> _buttonComments = {
|
|
ButtonActions.approve: "Accepted",
|
|
ButtonActions.reject: "Rejected",
|
|
};
|
|
|
|
static const Map<ButtonActions, int> _buttonActionCodes = {
|
|
ButtonActions.approve: 4,
|
|
ButtonActions.reject: 5,
|
|
};
|
|
|
|
Color get backgroundColor {
|
|
// Use string keys for correct color lookup
|
|
return AttendanceActionColors.colors[_buttonTexts[widget.action]!] ??
|
|
Colors.grey;
|
|
}
|
|
|
|
Future<void> _handlePress() async {
|
|
final projectController = Get.find<ProjectController>();
|
|
final selectedProjectId = projectController.selectedProject?.id;
|
|
|
|
if (selectedProjectId == null) {
|
|
showAppSnackbar(
|
|
title: 'Warning',
|
|
message: 'Please select a project first',
|
|
type: SnackbarType.warning,
|
|
);
|
|
return;
|
|
}
|
|
|
|
setState(() {
|
|
isUploading = true;
|
|
});
|
|
|
|
widget.attendanceController.uploadingStates[widget.uniqueLogKey]?.value =
|
|
true;
|
|
|
|
final success =
|
|
await widget.attendanceController.captureAndUploadAttendance(
|
|
widget.log.id,
|
|
widget.log.employeeId,
|
|
selectedProjectId,
|
|
comment: _buttonComments[widget.action]!,
|
|
action: _buttonActionCodes[widget.action]!,
|
|
imageCapture: false,
|
|
);
|
|
|
|
showAppSnackbar(
|
|
title: success ? 'Success' : 'Error',
|
|
message: success
|
|
? '${capitalizeFirstLetter(_buttonTexts[widget.action]!)} marked successfully!'
|
|
: 'Failed to mark ${capitalizeFirstLetter(_buttonTexts[widget.action]!)}.',
|
|
type: success ? SnackbarType.success : SnackbarType.error,
|
|
);
|
|
|
|
if (success) {
|
|
widget.attendanceController.fetchEmployeesByProject(selectedProjectId);
|
|
widget.attendanceController.fetchAttendanceLogs(selectedProjectId);
|
|
await widget.attendanceController
|
|
.fetchRegularizationLogs(selectedProjectId);
|
|
await widget.attendanceController.fetchProjectData(selectedProjectId);
|
|
}
|
|
|
|
widget.attendanceController.uploadingStates[widget.uniqueLogKey]?.value =
|
|
false;
|
|
|
|
setState(() {
|
|
isUploading = false;
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final buttonText = _buttonTexts[widget.action]!;
|
|
|
|
return ConstrainedBox(
|
|
constraints: const BoxConstraints(minWidth: 70, maxWidth: 120),
|
|
child: SizedBox(
|
|
height: 30,
|
|
child: ElevatedButton(
|
|
onPressed: isUploading ? null : _handlePress,
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: backgroundColor,
|
|
foregroundColor: Colors.white,
|
|
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 6),
|
|
minimumSize: const Size(60, 20),
|
|
textStyle: const TextStyle(fontSize: 12),
|
|
),
|
|
child: isUploading
|
|
? Container(
|
|
width: 60,
|
|
height: 14,
|
|
decoration: BoxDecoration(
|
|
color: Colors.white.withOpacity(0.5),
|
|
borderRadius: BorderRadius.circular(4),
|
|
),
|
|
)
|
|
: FittedBox(
|
|
fit: BoxFit.scaleDown,
|
|
child: Text(
|
|
buttonText,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|