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/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/controller/attendance/attendance_screen_controller.dart'; import 'package:marco/controller/permission_controller.dart'; import 'package:marco/model/attendance/attendence_filter_sheet.dart'; import 'package:marco/controller/project_controller.dart'; import 'package:marco/view/Attendence/regularization_requests_tab.dart'; import 'package:marco/view/Attendence/attendance_logs_tab.dart'; import 'package:marco/view/Attendence/todays_attendance_tab.dart'; import 'package:marco/helpers/widgets/my_refresh_indicator.dart'; class AttendanceScreen extends StatefulWidget { const AttendanceScreen({super.key}); @override State createState() => _AttendanceScreenState(); } class _AttendanceScreenState extends State with UIMixin { final attendanceController = Get.put(AttendanceController()); final permissionController = Get.put(PermissionController()); final projectController = Get.find(); String selectedTab = 'todaysAttendance'; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { // Listen for future project selection changes ever(projectController.selectedProjectId, (projectId) async { if (projectId.isNotEmpty) await _loadData(projectId); }); // Load initial data final projectId = projectController.selectedProjectId.value; if (projectId.isNotEmpty) _loadData(projectId); }); } Future _loadData(String projectId) async { try { await attendanceController.loadAttendanceData(projectId); attendanceController.update(['attendance_dashboard_controller']); } catch (e) { debugPrint("Error loading data: $e"); } } Future _refreshData() async { final projectId = projectController.selectedProjectId.value; if (projectId.isNotEmpty) await _loadData(projectId); } Widget _buildAppBar() { return AppBar( backgroundColor: const Color(0xFFF5F5F5), elevation: 0.5, automaticallyImplyLeading: false, titleSpacing: 0, title: Padding( padding: MySpacing.xy(16, 0), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ IconButton( icon: const Icon(Icons.arrow_back_ios_new, color: Colors.black, size: 20), onPressed: () => Get.offNamed('/dashboard'), ), MySpacing.width(8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ MyText.titleLarge('Attendance', fontWeight: 700, color: Colors.black), MySpacing.height(2), GetBuilder( builder: (projectController) { final projectName = projectController.selectedProject?.name ?? 'Select Project'; return Row( children: [ const Icon(Icons.work_outline, size: 14, color: Colors.grey), MySpacing.width(4), Expanded( child: MyText.bodySmall( projectName, fontWeight: 600, overflow: TextOverflow.ellipsis, color: Colors.grey[700], ), ), ], ); }, ), ], ), ), ], ), ), ); } Widget _buildFilterAndRefreshRow() { return Row( mainAxisAlignment: MainAxisAlignment.end, children: [ MyText.bodyMedium("Filter", fontWeight: 600), Tooltip( message: 'Filter Project', child: InkWell( borderRadius: BorderRadius.circular(24), onTap: () async { final result = await showModalBottomSheet>( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(12)), ), builder: (context) => AttendanceFilterBottomSheet( controller: attendanceController, permissionController: permissionController, selectedTab: selectedTab, ), ); if (result != null) { final selectedProjectId = projectController.selectedProjectId.value; final selectedView = result['selectedTab'] as String?; if (selectedProjectId.isNotEmpty) { try { await attendanceController .fetchEmployeesByProject(selectedProjectId); await attendanceController .fetchAttendanceLogs(selectedProjectId); await attendanceController .fetchRegularizationLogs(selectedProjectId); await attendanceController .fetchProjectData(selectedProjectId); } catch (_) {} attendanceController .update(['attendance_dashboard_controller']); } if (selectedView != null && selectedView != selectedTab) { setState(() => selectedTab = selectedView); } } }, child: Padding( padding: const EdgeInsets.all(8.0), child: Icon(Icons.tune, size: 18), ), ), ), ], ); } Widget _buildNoProjectWidget() { return Center( child: Padding( padding: const EdgeInsets.all(24.0), child: MyText.titleMedium( 'No Records Found', fontWeight: 600, color: Colors.grey[600], ), ), ); } Widget _buildSelectedTabContent() { switch (selectedTab) { case 'attendanceLogs': return AttendanceLogsTab(controller: attendanceController); case 'regularizationRequests': return RegularizationRequestsTab(controller: attendanceController); case 'todaysAttendance': default: return TodaysAttendanceTab(controller: attendanceController); } } @override Widget build(BuildContext context) { return Scaffold( appBar: PreferredSize( preferredSize: const Size.fromHeight(72), child: _buildAppBar(), ), body: SafeArea( child: GetBuilder( init: attendanceController, tag: 'attendance_dashboard_controller', builder: (controller) { final selectedProjectId = projectController.selectedProjectId.value; final noProjectSelected = selectedProjectId.isEmpty; return MyRefreshIndicator( onRefresh: _refreshData, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), padding: MySpacing.zero, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ MySpacing.height(flexSpacing), _buildFilterAndRefreshRow(), MySpacing.height(flexSpacing), MyFlex( children: [ MyFlexItem( sizes: 'lg-12 md-12 sm-12', child: noProjectSelected ? _buildNoProjectWidget() : _buildSelectedTabContent(), ), ], ), ], ), ), ); }, ), ), ); } }