import 'package:flutter/material.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/my_shadow.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_spacing.dart'; import 'package:marco/helpers/widgets/my_text.dart'; import 'package:marco/view/layouts/layout.dart'; import 'package:marco/controller/attendance/attendance_screen_controller.dart'; import 'package:marco/controller/permission_controller.dart'; import 'package:intl/intl.dart'; import 'package:marco/model/attendance/attendence_action_button.dart'; import 'package:marco/helpers/widgets/avatar.dart'; import 'package:marco/model/attendance/log_details_view.dart'; class AttendenceLogScreen extends StatefulWidget { const AttendenceLogScreen({super.key}); @override State createState() => _AttendenceLogScreenState(); } class _AttendenceLogScreenState extends State with UIMixin { final AttendanceController attendanceController = Get.put(AttendanceController()); final PermissionController permissionController = Get.put(PermissionController()); @override Widget build(BuildContext context) { return Layout( child: GetBuilder( init: attendanceController, tag: 'attendence_controller', builder: (controller) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: MySpacing.x(flexSpacing), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ MyText.titleMedium("Attendence", fontSize: 18, fontWeight: 600), MyBreadcrumb( children: [ MyBreadcrumbItem(name: 'Dashboard'), MyBreadcrumbItem(name: 'Attendence', active: true), ], ), ], ), ), MySpacing.height(flexSpacing), Padding( padding: MySpacing.x(flexSpacing / 2), child: MyFlex(children: [ MyFlexItem(sizes: 'lg-12 md-12 sm-12', child: employeeLog()), ]), ) ], ); }, ), ); } Widget employeeLog() { return MyCard.bordered( borderRadiusAll: 4, border: Border.all(color: Colors.grey.withOpacity(0.2)), shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom), paddingAll: 8, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ attendanceController.employees.isEmpty ? MyText.bodySmall("No Employees Assigned to This Project", fontWeight: 600) : Column( children: List.generate(attendanceController.employees.length, (index) { final employee = attendanceController.employees[index]; return Column( children: [ Padding( padding: const EdgeInsets.only(bottom: 16.0), child: MyContainer( paddingAll: 12, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Avatar( firstName: employee.firstName, lastName: employee.lastName, size: 31, ) ], ), MySpacing.width(16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: MyText.bodyMedium( '${employee.name} ' ' (${employee.designation})', fontWeight: 600, maxLines: null, overflow: TextOverflow.visible, softWrap: true, ), ), ], ), 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: [ AttendanceLogViewButton( employee: employee, attendanceController: attendanceController, ), MySpacing.width(8), AttendanceActionButton( employee: employee, attendanceController: attendanceController, ), ], ), ], ), ), ], ), ), ), if (index != attendanceController.employees.length - 1) Padding( padding: const EdgeInsets.symmetric(), child: Divider( color: Colors.grey.withOpacity(0.3), thickness: 1, height: 1, ), ), ], ); }), ), ], ), ); } Future 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; } }