import 'package:flutter/material.dart'; import '../../../api/marianumconnect/models/mc_holiday.dart'; import '../../../extensions/date_time.dart'; import '../../../state/app/infrastructure/loadable_state/loadable_state.dart'; import '../../../state/app/infrastructure/loadable_state/view/loadable_state_consumer.dart'; import '../../../state/app/infrastructure/utility_widgets/bloc_module.dart'; import '../../../state/app/modules/holidays/bloc/holidays_bloc.dart'; import '../../../state/app/modules/holidays/bloc/holidays_event.dart'; import '../../../state/app/modules/holidays/bloc/holidays_state.dart'; import '../../../widget/animated_time.dart'; import '../../../widget/centered_leading.dart'; import '../../../widget/debug/debug_tile.dart'; import '../../../widget/details_bottom_sheet.dart'; import '../../../widget/info_dialog.dart'; import '../../../widget/list_view_util.dart'; import '../../../widget/placeholder_view.dart'; class HolidaysView extends StatelessWidget { const HolidaysView({super.key}); @override Widget build( BuildContext context, ) => BlocModule>( create: (context) => HolidaysBloc(), autoRebuild: true, child: (context, bloc, state) { void showDisclaimer() => InfoDialog.show( context, 'Sämtliche Datumsangaben sind ohne Gewähr.\n' 'Ich übernehme weder Verantwortung für die Richtigkeit der Daten noch hafte ich für wirtschaftliche Schäden die aus der Verwendung dieser Daten entstehen können.', title: 'Richtigkeit der Daten', ); return Scaffold( appBar: AppBar( title: const Text('Schulferien'), actions: [ IconButton( icon: const Icon(Icons.info_outline), onPressed: showDisclaimer, ), PopupMenuButton( initialValue: bloc.showPastHolidays(), icon: const Icon(Icons.history), itemBuilder: (context) => [true, false] .map( (e) => PopupMenuItem( value: e, enabled: e != bloc.showPastHolidays(), child: Row( children: [ Icon( e ? Icons.history_outlined : Icons.history_toggle_off_outlined, color: Theme.of(context).colorScheme.onSurface, ), const SizedBox(width: 15), Text(e ? 'Alle anzeigen' : 'Nur zukünftige anzeigen'), ], ), ), ) .toList(), onSelected: (e) => bloc.add(SetPastHolidaysVisible(e)), ), ], ), body: LoadableStateConsumer( onLoad: (state) { if (state.showDisclaimer) showDisclaimer(); bloc.add(DisclaimerDismissed()); }, child: (state, loading) { final holidays = bloc.getHolidays(); if (holidays == null || holidays.isEmpty) { return const PlaceholderView( icon: Icons.beach_access_outlined, text: 'Keine Schulferien verfügbar', ); } return ListViewUtil.fromList( holidays, (holiday) { String holidayYear() { final startYear = holiday.startDate.year; final endYear = holiday.endDate.year; if (startYear == endYear) return '$startYear'; return '$startYear/${endYear % 100}'; } return ListTile( leading: const CenteredLeading(Icon(Icons.calendar_month)), title: Text( '${holiday.longName} ${holidayYear()}', ), subtitle: Text( '${holiday.startDate.formatDate()} - ${holiday.endDate.formatDate()}', ), onTap: () => showDetailsBottomSheet( context, header: Padding( padding: const EdgeInsets.fromLTRB(16, 4, 16, 12), child: Text( '${holiday.longName} ${holidayYear()}', style: Theme.of(context).textTheme.titleLarge, ), ), children: (sheetCtx) => [ ListTile( leading: const CenteredLeading( Icon(Icons.signpost_outlined), ), title: Text(holiday.longName), subtitle: Text(holiday.shortName), ), ListTile( leading: const Icon(Icons.date_range_outlined), title: Text('vom ${holiday.startDate.formatDate()}'), ), ListTile( leading: const Icon(Icons.date_range_outlined), title: Text('bis zum ${holiday.endDate.formatDate()}'), ), if (holiday.startDate.difference(DateTime.now()).isNegative) ListTile( leading: const CenteredLeading( Icon(Icons.content_paste_search_outlined), ), title: Text(holiday.startDate.formatRelative()), ) else ListTile( leading: const CenteredLeading( Icon(Icons.timer_outlined), ), title: AnimatedTime( callback: () => holiday.startDate.difference(DateTime.now()), ), subtitle: Text(holiday.startDate.formatRelative()), ), DebugTile(sheetCtx).jsonData(holiday.toJson()), ], ), trailing: const Icon(Icons.arrow_right), ); }, ); }, ), ); }, ); }