marco.pms.mobileapp/lib/model/attendance/regualrize_action_button.dart
Vaibhav Surve 34100a4d9e -- Enhance layout with floating action button and navigation improvements
- Added a floating action button to the Layout widget for better accessibility.
- Updated the left bar navigation items for clarity and consistency.
- Introduced Daily Progress Report and Daily Task Planning screens with comprehensive UI.
- Implemented filtering and refreshing functionalities in task planning.
- Improved user experience with better spacing and layout adjustments.
- Updated pubspec.yaml to include new dependencies for image handling and path management.
2025-05-28 17:35:42 +05:30

144 lines
4.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:marco/helpers/utils/attendance_actions.dart';
import 'package:marco/helpers/widgets/my_snackbar.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 {
if (widget.attendanceController.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,
widget.attendanceController.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(
widget.attendanceController.selectedProjectId!);
widget.attendanceController
.fetchAttendanceLogs(widget.attendanceController.selectedProjectId!);
await widget.attendanceController.fetchRegularizationLogs(
widget.attendanceController.selectedProjectId!);
await widget.attendanceController
.fetchProjectData(widget.attendanceController.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, // Ensures visibility on all backgrounds
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: Text(
buttonText,
overflow: TextOverflow.ellipsis,
),
),
),
),
);
}
}