diff --git a/lib/screens/attendance/attendance_screen.dart b/lib/screens/attendance/attendance_screen.dart index 6eae36fe..9a324c00 100644 --- a/lib/screens/attendance/attendance_screen.dart +++ b/lib/screens/attendance/attendance_screen.dart @@ -105,19 +105,7 @@ class _AttendanceScreenState extends ConsumerState title: 'Attendance', subtitle: 'Check in, logbook, pass slip and leave', ), - TabBar( - controller: _tabController, - isScrollable: true, - tabAlignment: TabAlignment.start, - tabs: const [ - Tab(text: 'Check In'), - Tab(text: 'Logbook'), - Tab(text: 'Work Log'), - Tab(text: 'My Schedule'), - Tab(text: 'Pass Slip'), - Tab(text: 'Leave'), - ], - ), + _buildAttendanceNav(context), Expanded( child: TabBarView( controller: _tabController, @@ -137,6 +125,35 @@ class _AttendanceScreenState extends ConsumerState ); } + Widget _buildAttendanceNav(BuildContext context) { + final isMobile = AppBreakpoints.isMobile(context); + final isDesktop = AppBreakpoints.isDesktop(context); + if (isMobile) { + return _AttendanceSectionPicker( + controller: _tabController, + currentIndex: _tabController.index, + ); + } + return TabBar( + controller: _tabController, + isScrollable: isDesktop, + tabAlignment: isDesktop ? TabAlignment.start : TabAlignment.fill, + tabs: _attendanceTabs(shortLabels: !isDesktop), + ); + } + + List _attendanceTabs({required bool shortLabels}) => [ + Tab(icon: const Icon(Icons.login_rounded, size: 18), text: 'Check In'), + Tab(icon: const Icon(Icons.menu_book_outlined, size: 18), text: 'Logbook'), + Tab(icon: const Icon(Icons.timer_outlined, size: 18), text: 'Work Log'), + Tab( + icon: const Icon(Icons.calendar_month_outlined, size: 18), + text: shortLabels ? 'Schedule' : 'My Schedule', + ), + Tab(icon: const Icon(Icons.directions_walk_outlined, size: 18), text: 'Pass Slip'), + Tab(icon: const Icon(Icons.event_busy_outlined, size: 18), text: 'Leave'), + ]; + Widget _buildFabMenu( BuildContext context, ThemeData theme, @@ -282,6 +299,122 @@ class _AttendanceScreenState extends ConsumerState } } +// ──────────────────────────────────────────────── +// Adaptive section picker — mobile only (<600dp) +// ──────────────────────────────────────────────── + +class _AttendanceSectionPicker extends StatelessWidget { + const _AttendanceSectionPicker({ + required this.controller, + required this.currentIndex, + }); + + final TabController controller; + final int currentIndex; + + static final _sections = <({IconData icon, String label})>[ + (icon: Icons.login_rounded, label: 'Check In'), + (icon: Icons.menu_book_outlined, label: 'Logbook'), + (icon: Icons.timer_outlined, label: 'Work Log'), + (icon: Icons.calendar_month_outlined, label: 'My Schedule'), + (icon: Icons.directions_walk_outlined, label: 'Pass Slip'), + (icon: Icons.event_busy_outlined, label: 'Leave'), + ]; + + @override + Widget build(BuildContext context) { + final cs = Theme.of(context).colorScheme; + final tt = Theme.of(context).textTheme; + final current = _sections[currentIndex]; + + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + child: Row( + children: [ + IconButton( + icon: const Icon(Icons.chevron_left), + onPressed: currentIndex > 0 + ? () => controller.animateTo(currentIndex - 1) + : null, + ), + Expanded( + child: ActionChip( + avatar: Icon(current.icon, size: 16, color: cs.primary), + label: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: Text( + current.label, + style: tt.labelLarge?.copyWith(color: cs.onSurface), + overflow: TextOverflow.ellipsis, + ), + ), + Icon(Icons.expand_more, size: 16, color: cs.onSurfaceVariant), + ], + ), + backgroundColor: cs.surfaceContainerHighest, + side: BorderSide.none, + onPressed: () => _showSheet(context), + ), + ), + IconButton( + icon: const Icon(Icons.chevron_right), + onPressed: currentIndex < _sections.length - 1 + ? () => controller.animateTo(currentIndex + 1) + : null, + ), + ], + ), + ); + } + + void _showSheet(BuildContext context) { + final cs = Theme.of(context).colorScheme; + final tt = Theme.of(context).textTheme; + showModalBottomSheet( + context: context, + useRootNavigator: true, + showDragHandle: true, + builder: (sheetContext) => Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), + child: Align( + alignment: Alignment.centerLeft, + child: Text('Attendance', style: tt.titleMedium), + ), + ), + for (int i = 0; i < _sections.length; i++) + ListTile( + leading: Icon( + _sections[i].icon, + color: i == currentIndex ? cs.primary : cs.onSurfaceVariant, + ), + title: Text( + _sections[i].label, + style: i == currentIndex + ? tt.bodyMedium?.copyWith( + color: cs.primary, + fontWeight: FontWeight.w600, + ) + : tt.bodyMedium, + ), + selected: i == currentIndex, + selectedTileColor: cs.primaryContainer.withValues(alpha: 0.3), + onTap: () { + controller.animateTo(i); + Navigator.pop(sheetContext); + }, + ), + const SizedBox(height: 16), + ], + ), + ); + } +} + // ──────────────────────────────────────────────── // Tab 1 – Check In / Check Out // ────────────────────────────────────────────────