import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:marco/controller/attendance/attendance_screen_controller.dart'; import 'package:marco/helpers/utils/date_time_utils.dart'; import 'package:marco/helpers/widgets/avatar.dart'; import 'package:marco/helpers/widgets/my_card.dart'; import 'package:marco/helpers/widgets/my_container.dart'; import 'package:marco/helpers/widgets/my_spacing.dart'; import 'package:marco/helpers/widgets/my_text.dart'; import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; import 'package:marco/model/attendance/log_details_view.dart'; import 'package:marco/model/attendance/attendence_action_button.dart'; class AttendanceLogsTab extends StatelessWidget { final AttendanceController controller; const AttendanceLogsTab({super.key, required this.controller}); @override Widget build(BuildContext context) { return Obx(() { final logs = List.of(controller.attendanceLogs); logs.sort((a, b) { final aDate = a.checkIn ?? DateTime(0); final bDate = b.checkIn ?? DateTime(0); return bDate.compareTo(aDate); }); final dateRangeText = controller.startDateAttendance != null && controller.endDateAttendance != null ? '${DateTimeUtils.formatDate(controller.startDateAttendance!, 'dd MMM yyyy')} - ' '${DateTimeUtils.formatDate(controller.endDateAttendance!, 'dd MMM yyyy')}' : 'Select date range'; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ MyText.titleMedium("Attendance Logs", fontWeight: 600), controller.isLoading.value ? SkeletonLoaders.dateSkeletonLoader() : MyText.bodySmall( dateRangeText, fontWeight: 600, color: Colors.grey[700], overflow: TextOverflow.ellipsis, ), ], ), ), if (controller.isLoadingAttendanceLogs.value) SkeletonLoaders.employeeListSkeletonLoader() else if (logs.isEmpty) const SizedBox( height: 120, child: Center( child: Text("No Attendance Logs Found for this Project"), ), ) else MyCard.bordered( paddingAll: 8, child: Column( children: List.generate(logs.length, (index) { final employee = logs[index]; final currentDate = employee.checkIn != null ? DateTimeUtils.formatDate( employee.checkIn!, 'dd MMM yyyy') : ''; final previousDate = index > 0 && logs[index - 1].checkIn != null ? DateTimeUtils.formatDate( logs[index - 1].checkIn!, 'dd MMM yyyy') : ''; final showDateHeader = index == 0 || currentDate != previousDate; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (showDateHeader) Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: MyText.bodyMedium( currentDate, fontWeight: 700, ), ), MyContainer( paddingAll: 8, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Avatar( firstName: employee.firstName, lastName: employee.lastName, size: 31, ), MySpacing.width(16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Flexible( child: MyText.bodyMedium( employee.name, fontWeight: 600, overflow: TextOverflow.ellipsis, ), ), MySpacing.width(6), Flexible( child: MyText.bodySmall( '(${employee.designation})', fontWeight: 600, color: Colors.grey[700], overflow: TextOverflow.ellipsis, ), ), ], ), MySpacing.height(8), if (employee.checkIn != null || employee.checkOut != null) Row( children: [ if (employee.checkIn != null) ...[ const Icon(Icons.arrow_circle_right, size: 16, color: Colors.green), MySpacing.width(4), MyText.bodySmall( DateTimeUtils.formatDate( employee.checkIn!, 'hh:mm a'), fontWeight: 600, ), MySpacing.width(16), ], if (employee.checkOut != null) ...[ const Icon(Icons.arrow_circle_left, size: 16, color: Colors.red), MySpacing.width(4), MyText.bodySmall( DateTimeUtils.formatDate( employee.checkOut!, 'hh:mm a'), fontWeight: 600, ), ], ], ), MySpacing.height(12), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ AttendanceActionButton( employee: employee, attendanceController: controller, ), MySpacing.width(8), AttendanceLogViewButton( employee: employee, attendanceController: controller, ), ], ), ], ), ), ], ), ), if (index != logs.length - 1) Divider(color: Colors.grey.withOpacity(0.3)), ], ); }), ), ), ], ); }); } }