import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:table_calendar/table_calendar.dart'; import 'package:intl/intl.dart'; import '../../providers/time_provider.dart'; import '../../models/time_registration.dart'; import 'registration_detail_screen.dart'; class HistoryScreen extends ConsumerStatefulWidget { const HistoryScreen({super.key}); @override ConsumerState createState() => _HistoryScreenState(); } class _HistoryScreenState extends ConsumerState { CalendarFormat _calendarFormat = CalendarFormat.week; DateTime _focusedDay = DateTime.now(); DateTime? _selectedDay; @override void initState() { super.initState(); _selectedDay = _focusedDay; } @override Widget build(BuildContext context) { // Hent registreringer for valgt dag final selectedDate = _selectedDay ?? DateTime.now(); final dateRange = DateRange( start: DateTime(selectedDate.year, selectedDate.month, selectedDate.day), end: DateTime(selectedDate.year, selectedDate.month, selectedDate.day, 23, 59, 59), ); final registrationsAsync = ref.watch(registrationsProvider(dateRange)); final totalHoursAsync = ref.watch(totalHoursProvider(dateRange)); return Scaffold( appBar: AppBar( title: const Text('Historikk'), ), body: Column( children: [ TableCalendar( locale: 'nb_NO', firstDay: DateTime.utc(2020, 1, 1), lastDay: DateTime.utc(2030, 12, 31), focusedDay: _focusedDay, calendarFormat: _calendarFormat, selectedDayPredicate: (day) { return isSameDay(_selectedDay, day); }, onDaySelected: (selectedDay, focusedDay) { if (!isSameDay(_selectedDay, selectedDay)) { setState(() { _selectedDay = selectedDay; _focusedDay = focusedDay; }); } }, onFormatChanged: (format) { if (_calendarFormat != format) { setState(() { _calendarFormat = format; }); } }, onPageChanged: (focusedDay) { _focusedDay = focusedDay; }, calendarStyle: CalendarStyle( selectedDecoration: BoxDecoration( color: Theme.of(context).colorScheme.primary, shape: BoxShape.circle, ), todayDecoration: BoxDecoration( color: Theme.of(context).colorScheme.primary.withOpacity(0.5), shape: BoxShape.circle, ), ), ), const Divider(), // Dagens oppsummering Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), child: totalHoursAsync.when( data: (hours) { final total = hours['total'] ?? 0; return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Totalt denne dagen:', style: Theme.of(context).textTheme.titleMedium, ), Text( '${total ~/ 60}t ${total % 60}m', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.primary, ), ), ], ); }, loading: () => const SizedBox(height: 20), error: (_, __) => const SizedBox.shrink(), ), ), const Divider(), // Liste over registreringer Expanded( child: registrationsAsync.when( data: (registrations) { if (registrations.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.event_note, size: 64, color: Colors.grey[300], ), const SizedBox(height: 16), Text( 'Ingen registreringer denne dagen', style: TextStyle(color: Colors.grey[600]), ), ], ), ); } return ListView.builder( itemCount: registrations.length, itemBuilder: (context, index) { final reg = registrations[index]; return Card( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), child: ListTile( leading: CircleAvatar( backgroundColor: _getColorForType(reg.type).withOpacity(0.2), child: Icon( _getIconForType(reg.type), color: _getColorForType(reg.type), size: 20, ), ), title: Text( '${DateFormat('HH:mm').format(reg.startTime)} - ${reg.endTime != null ? DateFormat('HH:mm').format(reg.endTime!) : 'Pågår'}', style: const TextStyle(fontWeight: FontWeight.bold), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(_getTypeDisplayName(reg.type)), if (reg.comment != null && reg.comment!.isNotEmpty) Text( reg.comment!, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle(fontStyle: FontStyle.italic), ), ], ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ if (reg.deviations.isNotEmpty) const Padding( padding: EdgeInsets.only(right: 8.0), child: Icon(Icons.warning_amber, color: Colors.orange), ), Text( reg.endTime != null ? '${reg.netWorkMinutes ~/ 60}t ${reg.netWorkMinutes % 60}m' : '...', style: const TextStyle(fontWeight: FontWeight.bold), ), const Icon(Icons.chevron_right), ], ), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => RegistrationDetailScreen(registration: reg), ), ); }, ), ); }, ); }, loading: () => const Center(child: CircularProgressIndicator()), error: (error, _) => Center(child: Text('Feil: $error')), ), ), ], ), ); } Color _getColorForType(RegistrationType type) { switch (type) { case RegistrationType.ordinary: return Colors.blue; case RegistrationType.overtime: return Colors.orange; case RegistrationType.oncall: return Colors.purple; case RegistrationType.travel: return Colors.green; } } IconData _getIconForType(RegistrationType type) { switch (type) { case RegistrationType.ordinary: return Icons.work; case RegistrationType.overtime: return Icons.access_time_filled; case RegistrationType.oncall: return Icons.phone_in_talk; case RegistrationType.travel: return Icons.directions_car; } } String _getTypeDisplayName(RegistrationType type) { switch (type) { case RegistrationType.ordinary: return 'Ordinær'; case RegistrationType.overtime: return 'Overtid'; case RegistrationType.oncall: return 'Beredskap'; case RegistrationType.travel: return 'Reisetid'; } } }