marco.pms.mobileapp/lib/view/dashboard/attendanceScreen.dart

1323 lines
67 KiB
Dart

// import 'package:flutter/material.dart';
// import 'package:flutter_lucide/flutter_lucide.dart';
// import 'package:get/get.dart';
// import 'package:marco/helpers/theme/app_theme.dart';
// import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
// import 'package:marco/helpers/utils/permission_constants.dart';
// import 'package:marco/helpers/utils/attendance_actions.dart';
// import 'package:marco/helpers/widgets/my_breadcrumb.dart';
// import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
// import 'package:marco/helpers/widgets/my_card.dart';
// import 'package:marco/helpers/widgets/my_container.dart';
// import 'package:marco/helpers/widgets/my_flex.dart';
// import 'package:marco/helpers/widgets/my_flex_item.dart';
// import 'package:marco/helpers/widgets/my_list_extension.dart';
// import 'package:marco/helpers/widgets/my_loading_component.dart';
// import 'package:marco/helpers/widgets/my_refresh_wrapper.dart';
// import 'package:marco/helpers/widgets/my_spacing.dart';
// import 'package:marco/helpers/widgets/my_text.dart';
// import 'package:marco/helpers/utils/my_shadow.dart';
// import 'package:marco/model/my_paginated_table.dart';
// import 'package:marco/view/layouts/layout.dart';
// import 'package:marco/controller/dashboard/attendance_screen_controller.dart';
// import 'package:intl/intl.dart';
// import 'package:marco/controller/permission_controller.dart';
// import 'package:url_launcher/url_launcher.dart';
// import 'package:marco/images.dart';
// class AttendanceScreen extends StatefulWidget {
// const AttendanceScreen({super.key});
// @override
// State<AttendanceScreen> createState() => _AttendanceScreenState();
// }
// class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
// final AttendanceController attendanceController =
// Get.put(AttendanceController());
// final PermissionController permissionController =
// Get.put(PermissionController());
// @override
// Widget build(BuildContext context) {
// return Layout(
// child: GetBuilder<AttendanceController>(
// init: attendanceController,
// tag: 'attendance_dashboard_controller',
// builder: (controller) {
// return LoadingComponent(
// isLoading: controller.isLoading.value,
// loadingText: 'Loading Attendance...',
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Padding(
// padding: MySpacing.x(flexSpacing),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// MyText.titleMedium("Attendance",
// fontSize: 18, fontWeight: 600),
// MyBreadcrumb(
// children: [
// MyBreadcrumbItem(name: 'Dashboard'),
// MyBreadcrumbItem(name: 'Attendance', active: true),
// ],
// ),
// ],
// ),
// ),
// MySpacing.height(flexSpacing),
// Padding(
// padding: MySpacing.x(flexSpacing / 2),
// child: MyFlex(
// children: [
// // Project Selection Dropdown
// MyFlexItem(
// sizes: 'lg-12',
// child: MyContainer.bordered(
// padding: MySpacing.xy(8, 8),
// child: PopupMenuButton<String>(
// onSelected: (value) async {
// attendanceController.selectedProjectId = value;
// await attendanceController
// .fetchEmployeesByProject(value);
// await attendanceController
// .fetchAttendanceLogs(value);
// await attendanceController
// .fetchRegularizationLogs(value);
// await attendanceController
// .fetchProjectData(value);
// attendanceController.update();
// },
// itemBuilder: (BuildContext context) {
// if (attendanceController.projects.isEmpty) {
// return [
// PopupMenuItem<String>(
// value: '',
// child: MyText.bodySmall('No Data',
// fontWeight: 600),
// )
// ];
// }
// // Filter projects based on permissions
// final accessibleProjects = attendanceController
// .projects
// .where((project) => permissionController
// .isUserAssignedToProject(
// project.id.toString()))
// .toList();
// if (accessibleProjects.isEmpty) {
// return [
// PopupMenuItem<String>(
// value: '',
// child: MyText.bodySmall(
// 'No Projects Assigned',
// fontWeight: 600),
// )
// ];
// }
// return accessibleProjects.map((project) {
// return PopupMenuItem<String>(
// value: project.id.toString(),
// height: 32,
// child: MyText.bodySmall(
// project.name,
// color: theme.colorScheme.onSurface,
// fontWeight: 600,
// ),
// );
// }).toList();
// },
// color: theme.cardTheme.color,
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// MyText.labelSmall(
// attendanceController.selectedProjectId != null
// ? attendanceController.projects
// .firstWhereOrNull((proj) =>
// proj.id ==
// attendanceController
// .selectedProjectId)
// ?.name ??
// 'Select a Project'
// : 'Select a Project',
// color: theme.colorScheme.onSurface,
// ),
// Icon(LucideIcons.chevron_down,
// size: 20,
// color: theme.colorScheme.onSurface),
// ],
// ),
// ),
// ),
// ),
// // Tab Section
// MyFlexItem(
// sizes: 'lg-12',
// child: Obx(() {
// bool hasRegularizationPermission =
// permissionController.hasPermission(
// Permissions.regularizeAttendance);
// final tabs = <Tab>[
// const Tab(text: 'Today`s'),
// const Tab(text: 'Logs'),
// if (hasRegularizationPermission)
// const Tab(text: 'Regularization'),
// ];
// final views = <Widget>[
// employeeListTab(),
// reportsTab(context),
// if (hasRegularizationPermission)
// regularizationTab(context),
// ];
// return DefaultTabController(
// length: tabs.length,
// child: MyCard.bordered(
// borderRadiusAll: 4,
// border:
// Border.all(color: Colors.grey.withAlpha(50)),
// shadow: MyShadow(
// elevation: 1,
// position: MyShadowPosition.bottom),
// paddingAll: 10,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// TabBar(
// labelColor: theme.colorScheme.primary,
// unselectedLabelColor: theme
// .colorScheme.onSurface
// .withAlpha(150),
// tabs: tabs,
// ),
// MySpacing.height(16),
// SizedBox(
// height: 630,
// child: TabBarView(children: views),
// ),
// ],
// ),
// ),
// );
// }),
// ),
// ],
// ),
// ),
// ],
// ),
// );
// },
// ),
// );
// }
// Widget employeeListTab() {
// return MyCard.bordered(
// borderRadiusAll: 4,
// border: Border.all(color: Colors.grey.withOpacity(0.2)),
// shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
// paddingAll: 24,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// attendanceController.employees.isEmpty
// ? MyText.bodySmall("No Employees Assigned to This Project",
// fontWeight: 600)
// : SizedBox(
// height: 600,
// child: SingleChildScrollView(
// child: Column(
// children: attendanceController.employees.map((employee) {
// int? activity = employee.activity;
// String buttonText = (activity == 0 || activity == 4)
// ? ButtonActions.checkIn
// : ButtonActions.checkOut;
// return Column(
// children: [
// MyContainer.bordered(
// paddingAll: 12,
// child: Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// // LEFT COLUMN: Avatar centered vertically
// Column(
// mainAxisAlignment: MainAxisAlignment.center, // <-- center vertically
// children: [
// MyContainer.rounded(
// paddingAll: 0,
// height: 44,
// width: 44,
// clipBehavior: Clip.antiAliasWithSaveLayer,
// child: Image.asset(
// Images.avatars[1],
// fit: BoxFit.cover,
// ),
// ),
// MySpacing.height(12),
// ],
// ),
// MySpacing.width(16),
// // RIGHT COLUMN: Name and role on the same line + other info
// Expanded(
// flex: 1,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// // Name and designation inline row
// Row(
// children: [
// Expanded(
// child: MyText.bodyMedium(
// employee.name,
// fontWeight: 600,
// overflow: TextOverflow.ellipsis,
// ),
// ),
// MySpacing.width(8),
// Flexible(
// child: MyText.labelMedium(
// employee.designation,
// fontWeight: 600,
// xMuted: true,
// overflow: TextOverflow.ellipsis,
// ),
// ),
// ],
// ),
// MySpacing.height(8),
// Row(
// children: [
// MyText.bodySmall("In: ", fontWeight: 600),
// MyText.bodySmall(
// employee.checkIn != null
// ? DateFormat('hh:mm a')
// .format(employee.checkIn!)
// : '--',
// fontWeight: 600,
// ),
// MySpacing.width(16),
// MyText.bodySmall("Out: ", fontWeight: 600),
// MyText.bodySmall(
// employee.checkOut != null
// ? DateFormat('hh:mm a')
// .format(employee.checkOut!)
// : '--',
// fontWeight: 600,
// ),
// ],
// ),
// MySpacing.height(12),
// Row(
// children: [
// IconButton(
// icon: const Icon(Icons.visibility, size: 20),
// onPressed: () async {
// await attendanceController
// .fetchLogsView(employee.id.toString());
// showModalBottomSheet(
// context: context,
// isScrollControlled: true,
// shape: const RoundedRectangleBorder(
// borderRadius: BorderRadius.vertical(
// top: Radius.circular(16),
// ),
// ),
// backgroundColor: Theme.of(context).cardColor,
// builder: (context) {
// return Padding(
// padding: EdgeInsets.only(
// left: 16,
// right: 16,
// top: 16,
// bottom: MediaQuery.of(context)
// .viewInsets
// .bottom +
// 16,
// ),
// // Your modal content here
// );
// },
// );
// },
// ),
// MySpacing.width(8),
// Obx(() {
// final isUploading =
// attendanceController
// .uploadingStates[
// employee.employeeId]
// ?.value ??
// false;
// final controller = attendanceController;
// return ConstrainedBox(
// constraints: const BoxConstraints(
// minWidth: 100, maxWidth: 140),
// child: SizedBox(
// height: 30,
// child: ElevatedButton(
// onPressed: isUploading
// ? null
// : () async {
// controller.uploadingStates[
// employee.employeeId] =
// RxBool(true);
// if (controller
// .selectedProjectId ==
// null) {
// ScaffoldMessenger.of(
// context)
// .showSnackBar(
// 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] =
// 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),
// padding:
// const EdgeInsets.symmetric(
// horizontal: 12),
// ),
// child: isUploading
// ? 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),
// ),
// ),
// ),
// ),
// );
// }),
// ],
// ),
// ],
// ),
// ),
// ],
// ),
// ),
// MySpacing.height(16),
// ],
// );
// }).toList(),
// ),
// ),
// ),
// ],
// ),
// );
// }
// Widget reportsTab(BuildContext context) {
// final attendanceController = Get.find<AttendanceController>();
// final groupedLogs = attendanceController.groupLogsByCheckInDate();
// final columns = [
// DataColumn(label: MyText.labelLarge('Name', color: contentTheme.primary)),
// DataColumn(
// label: MyText.labelLarge('Check-In', color: contentTheme.primary)),
// DataColumn(
// label: MyText.labelLarge('Check-Out', color: contentTheme.primary)),
// DataColumn(label: MyText.labelLarge('View', color: contentTheme.primary)),
// DataColumn(
// label: MyText.labelLarge('Action', color: contentTheme.primary)),
// ];
// List<DataRow> rows = [];
// // Iterate over grouped logs
// groupedLogs.forEach((checkInDate, logs) {
// // Add a row for the check-in date as a header
// rows.add(
// DataRow(color: WidgetStateProperty.all(Colors.grey[200]), cells: [
// DataCell(MyText.bodyMedium(checkInDate, fontWeight: 600)),
// DataCell(MyText.bodyMedium('')),
// DataCell(MyText.bodyMedium('')),
// DataCell(MyText.bodyMedium('')),
// DataCell(MyText.bodyMedium('')),
// ]));
// // Add rows for each log in this group
// for (var log in logs) {
// rows.add(DataRow(cells: [
// DataCell(
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// 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('hh:mm a').format(log.checkIn!)
// : '--',
// fontWeight: 600,
// ),
// ],
// ),
// ),
// DataCell(
// Column(
// mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// MyText.bodyMedium(
// log.checkOut != null
// ? DateFormat('hh:mm a').format(log.checkOut!)
// : '--',
// fontWeight: 600,
// ),
// ],
// ),
// ),
// DataCell(
// IconButton(
// icon: const Icon(Icons.visibility, size: 18),
// onPressed: () async {
// await attendanceController.fetchLogsView(log.id.toString());
// showModalBottomSheet(
// context: context,
// isScrollControlled: true,
// shape: const RoundedRectangleBorder(
// borderRadius:
// BorderRadius.vertical(top: Radius.circular(16)),
// ),
// backgroundColor: Theme.of(context).cardColor,
// builder: (context) {
// return Padding(
// padding: EdgeInsets.only(
// left: 16,
// right: 16,
// top: 16,
// bottom: MediaQuery.of(context).viewInsets.bottom + 16,
// ),
// child: SingleChildScrollView(
// child: Column(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// MyText.titleMedium(
// "Attendance Log Details",
// fontWeight: 700,
// ),
// IconButton(
// icon: const Icon(Icons.close),
// onPressed: () => Navigator.pop(context),
// ),
// ],
// ),
// const SizedBox(height: 16),
// if (attendanceController
// .attendenceLogsView.isNotEmpty) ...[
// Row(
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Expanded(
// child: MyText.bodyMedium("Date",
// fontWeight: 600)),
// Expanded(
// child: MyText.bodyMedium("Time",
// fontWeight: 600)),
// Expanded(
// child: MyText.bodyMedium("Description",
// fontWeight: 600)),
// Expanded(
// child: MyText.bodyMedium("Image",
// fontWeight: 600)),
// ],
// ),
// const Divider(thickness: 1, height: 24),
// ],
// if (attendanceController
// .attendenceLogsView.isNotEmpty)
// ...attendanceController.attendenceLogsView
// .map((log) => Padding(
// padding: const EdgeInsets.symmetric(
// vertical: 8.0),
// child: Row(
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Expanded(
// child: MyText.bodyMedium(
// log.formattedDate ?? '-',
// fontWeight: 600)),
// Expanded(
// child: MyText.bodyMedium(
// log.formattedTime ?? '-',
// fontWeight: 600)),
// Expanded(
// child: Row(
// children: [
// if (log.latitude != null &&
// log.longitude != null)
// GestureDetector(
// onTap: () async {
// final url =
// 'https://www.google.com/maps/search/?api=1&query=${log.latitude},${log.longitude}';
// if (await canLaunchUrl(
// Uri.parse(url))) {
// await launchUrl(
// Uri.parse(url),
// mode: LaunchMode
// .externalApplication);
// } else {
// ScaffoldMessenger.of(
// context)
// .showSnackBar(
// const SnackBar(
// content: Text(
// 'Could not open Google Maps')),
// );
// }
// },
// child: const Padding(
// padding:
// EdgeInsets.only(
// right: 4.0),
// child: Icon(
// Icons.location_on,
// size: 18,
// color: Colors.blue),
// ),
// ),
// Expanded(
// child: MyText.bodyMedium(
// log.comment ?? '-',
// fontWeight: 600,
// ),
// ),
// ],
// ),
// ),
// Expanded(
// child: GestureDetector(
// onTap: () {
// if (log.preSignedUrl !=
// null) {
// showDialog(
// context: context,
// builder: (_) => Dialog(
// child: Image.network(
// log.preSignedUrl!,
// fit: BoxFit.cover,
// height: 400,
// errorBuilder:
// (context, error,
// stackTrace) {
// return const Icon(
// Icons
// .broken_image,
// size: 50,
// color: Colors
// .grey);
// },
// ),
// ),
// );
// }
// },
// child: log.thumbPreSignedUrl !=
// null
// ? Image.network(
// log.thumbPreSignedUrl!,
// height: 40,
// width: 40,
// fit: BoxFit.cover,
// errorBuilder: (context,
// error, stackTrace) {
// return const Icon(
// Icons
// .broken_image,
// size: 40,
// color:
// Colors.grey);
// },
// )
// : const Icon(
// Icons.broken_image,
// size: 40,
// color: Colors.grey),
// ),
// ),
// ],
// ),
// )),
// ],
// ),
// ),
// );
// },
// );
// },
// ),
// ),
// DataCell(
// Obx(() {
// final uniqueLogKey =
// AttendanceButtonHelper.getUniqueKey(log.employeeId, log.id);
// final isUploading =
// attendanceController.uploadingStates[uniqueLogKey]?.value ??
// false;
// final isYesterday = AttendanceButtonHelper.isLogFromYesterday(
// log.checkIn, log.checkOut);
// final isTodayApproved = AttendanceButtonHelper.isTodayApproved(
// log.activity, log.checkIn);
// final isApprovedButNotToday =
// AttendanceButtonHelper.isApprovedButNotToday(
// log.activity, isTodayApproved);
// final isButtonDisabled = AttendanceButtonHelper.isButtonDisabled(
// isUploading: isUploading,
// isYesterday: isYesterday,
// activity: log.activity,
// isApprovedButNotToday: isApprovedButNotToday,
// );
// return ConstrainedBox(
// constraints: const BoxConstraints(minWidth: 100, maxWidth: 150),
// child: SizedBox(
// height: 30,
// child: ElevatedButton(
// onPressed: isButtonDisabled
// ? null
// : () async {
// attendanceController.uploadingStates[uniqueLogKey] =
// RxBool(true);
// if (attendanceController.selectedProjectId ==
// null) {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content:
// Text("Please select a project first"),
// ),
// );
// attendanceController
// .uploadingStates[uniqueLogKey] =
// RxBool(false);
// return;
// }
// int updatedAction;
// String actionText;
// bool imageCapture = true;
// switch (log.activity) {
// case 0:
// updatedAction = 0;
// actionText = ButtonActions.checkIn;
// 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;
// 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
// .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()}'),
// ),
// );
// }
// } 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] =
// RxBool(false);
// if (success) {
// attendanceController.fetchEmployeesByProject(
// attendanceController.selectedProjectId!);
// attendanceController.fetchAttendanceLogs(
// attendanceController.selectedProjectId!);
// await attendanceController
// .fetchRegularizationLogs(
// attendanceController.selectedProjectId!);
// await attendanceController.fetchProjectData(
// attendanceController.selectedProjectId!);
// attendanceController.update();
// }
// },
// style: ElevatedButton.styleFrom(
// backgroundColor: AttendanceButtonHelper.getButtonColor(
// isYesterday: isYesterday,
// isTodayApproved: isTodayApproved,
// activity: log.activity,
// ),
// padding: const EdgeInsets.symmetric(
// vertical: 4, horizontal: 6),
// textStyle: const TextStyle(fontSize: 12),
// ),
// child: isUploading
// ? const SizedBox(
// 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),
// ),
// ),
// ),
// ),
// );
// }),
// ),
// ]));
// }
// });
// return SingleChildScrollView(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Padding(
// padding: const EdgeInsets.all(8.0),
// child: GetBuilder<AttendanceController>(
// id: 'attendance_dashboard_controller',
// builder: (controller) {
// String labelText;
// if (controller.startDateAttendance != null &&
// controller.endDateAttendance != null) {
// final start = DateFormat('dd MM yyyy')
// .format(controller.startDateAttendance!);
// final end = DateFormat('dd MM yyyy')
// .format(controller.endDateAttendance!);
// labelText = "$start - $end";
// } else {
// labelText = "Select Date Range for Attendance";
// }
// return TextButton.icon(
// icon: const Icon(Icons.date_range),
// label: Text(labelText, overflow: TextOverflow.ellipsis),
// onPressed: () => controller.selectDateRangeForAttendance(
// Get.context!, controller),
// );
// },
// ),
// ),
// if (attendanceController.attendanceLogs.isEmpty)
// Align(
// alignment: Alignment.center,
// child: Padding(
// padding: const EdgeInsets.symmetric(vertical: 40),
// child: MyText.bodySmall(
// "No Attendance Records Found",
// fontWeight: 600,
// ),
// ),
// )
// else
// MyRefreshableContent(
// onRefresh: () async {
// if (attendanceController.selectedProjectId != null) {
// await attendanceController.fetchAttendanceLogs(
// attendanceController.selectedProjectId!);
// await attendanceController.fetchProjectData(
// attendanceController.selectedProjectId!);
// attendanceController.update();
// } else {
// await attendanceController.fetchProjects();
// }
// },
// child: SingleChildScrollView(
// child: MyPaginatedTable(
// columns: columns,
// rows: rows,
// ),
// ),
// )
// ],
// ),
// );
// }
// Widget regularizationTab(BuildContext context) {
// final attendanceController = Get.find<AttendanceController>();
// final columns = [
// DataColumn(label: MyText.labelLarge('Name', color: contentTheme.primary)),
// DataColumn(
// label: MyText.labelLarge('Check-In', color: contentTheme.primary)),
// DataColumn(
// label: MyText.labelLarge('Check-Out', color: contentTheme.primary)),
// DataColumn(
// label: MyText.labelLarge('Action', color: contentTheme.primary)),
// ];
// final rows =
// attendanceController.regularizationLogs.mapIndexed((index, log) {
// final uniqueLogKey =
// '${log.id}-${log.employeeId}'; // Unique key for each log
// final isUploading =
// attendanceController.uploadingStates[uniqueLogKey]?.value ??
// false; // Check the upload state
// return DataRow(cells: [
// DataCell(
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// 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(
// log.checkIn != null
// ? DateFormat('hh:mm a').format(log.checkIn!)
// : '',
// fontWeight: 600,
// ),
// ],
// ),
// ),
// DataCell(
// Column(
// mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// MyText.bodyMedium(
// log.checkOut != null
// ? DateFormat('dd MMM yyyy').format(log.checkOut!)
// : '-',
// fontWeight: 600,
// ),
// MyText.bodyMedium(
// log.checkOut != null
// ? DateFormat('hh:mm a').format(log.checkOut!)
// : '',
// fontWeight: 600,
// ),
// ],
// ),
// ),
// DataCell(
// Row(
// children: [
// // Approve Button
// ConstrainedBox(
// constraints: const BoxConstraints(minWidth: 70, maxWidth: 120),
// child: SizedBox(
// height: 30,
// child: ElevatedButton(
// onPressed: isUploading
// ? 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;
// final success = await attendanceController
// .captureAndUploadAttendance(
// log.id,
// log.employeeId,
// attendanceController.selectedProjectId!,
// comment: "Accepted",
// action: 4,
// imageCapture: false,
// );
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text(success
// ? 'Approval marked successfully!'
// : 'Failed to mark approval.'),
// ),
// );
// if (success) {
// attendanceController.fetchEmployeesByProject(
// attendanceController.selectedProjectId!);
// attendanceController.fetchAttendanceLogs(
// attendanceController.selectedProjectId!);
// await attendanceController
// .fetchRegularizationLogs(
// attendanceController.selectedProjectId!);
// await attendanceController.fetchProjectData(
// 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,
// ),
// ),
// ),
// ),
// ),
// const SizedBox(width: 8),
// // Reject Button
// ConstrainedBox(
// constraints: const BoxConstraints(minWidth: 70, maxWidth: 120),
// child: SizedBox(
// height: 30,
// child: ElevatedButton(
// onPressed: isUploading
// ? 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;
// final success = await attendanceController
// .captureAndUploadAttendance(
// log.id,
// log.employeeId,
// attendanceController.selectedProjectId!,
// comment: "Rejected",
// action: 5,
// imageCapture: false,
// );
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text(success
// ? 'Attendance marked as Rejected!'
// : 'Failed to mark attendance.'),
// ),
// );
// if (success) {
// attendanceController.fetchEmployeesByProject(
// attendanceController.selectedProjectId!);
// attendanceController.fetchAttendanceLogs(
// attendanceController.selectedProjectId!);
// await attendanceController
// .fetchRegularizationLogs(
// attendanceController.selectedProjectId!);
// await attendanceController.fetchProjectData(
// attendanceController.selectedProjectId!);
// }
// attendanceController
// .uploadingStates[uniqueLogKey]?.value = false;
// },
// style: ElevatedButton.styleFrom(
// backgroundColor:
// AttendanceActionColors.colors[ButtonActions.reject],
// 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(
// "Reject",
// overflow: TextOverflow.ellipsis,
// ),
// ),
// ),
// ),
// ),
// ],
// ),
// ),
// ]);
// }).toList();
// return Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Padding(
// padding: const EdgeInsets.all(8.0),
// ),
// if (attendanceController.regularizationLogs.isEmpty)
// Expanded(
// child: Center(
// child: MyText.bodySmall("No Regularization Records Found",
// fontWeight: 600),
// ),
// )
// else
// Expanded(
// child: MyRefreshableContent(
// onRefresh: () async {
// if (attendanceController.selectedProjectId != null) {
// await attendanceController.fetchProjectData(
// attendanceController.selectedProjectId!);
// await attendanceController.fetchRegularizationLogs(
// attendanceController.selectedProjectId!);
// attendanceController.update();
// } else {
// await attendanceController.fetchProjects();
// }
// },
// child: SingleChildScrollView(
// child: MyPaginatedTable(
// columns: columns,
// rows: rows,
// columnSpacing: 15.0,
// ),
// ),
// ),
// )
// ],
// );
// }
// Future<DateTime?> showTimePickerForRegularization({
// required BuildContext context,
// required DateTime checkInTime,
// }) async {
// final pickedTime = await showTimePicker(
// context: context,
// initialTime: TimeOfDay.fromDateTime(DateTime.now()),
// );
// if (pickedTime != null) {
// final selectedDateTime = DateTime(
// checkInTime.year,
// checkInTime.month,
// checkInTime.day,
// pickedTime.hour,
// pickedTime.minute,
// );
// // Ensure selected time is after check-in time
// if (selectedDateTime.isAfter(checkInTime)) {
// return selectedDateTime;
// } else {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text("Please select a time after check-in time.")),
// );
// return null;
// }
// }
// return null;
// }
// }