migrated holidays module to MarianumConnect API, replaced local Holiday model.

This commit is contained in:
2026-05-24 17:49:25 +02:00
parent 93b9929f8f
commit 01b4b44010
15 changed files with 161 additions and 456 deletions
+36 -34
View File
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.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';
@@ -13,7 +14,7 @@ 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/string_extensions.dart';
import '../../../widget/placeholder_view.dart';
class HolidaysView extends StatelessWidget {
const HolidaysView({super.key});
@@ -28,14 +29,13 @@ class HolidaysView extends StatelessWidget {
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.\n\n'
'Die Daten stammen von https://ferien-api.de/',
title: 'Richtigkeit und Bereitstellung der Daten',
'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 in Hessen'),
title: const Text('Schulferien'),
actions: [
IconButton(
icon: const Icon(Icons.info_outline),
@@ -73,34 +73,38 @@ class HolidaysView extends StatelessWidget {
if (state.showDisclaimer) showDisclaimer();
bloc.add(DisclaimerDismissed());
},
child: (state, loading) => ListViewUtil.fromList<Holiday>(
bloc.getHolidays(),
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<McHoliday>(
holidays,
(holiday) {
var holidayType = holiday.name.split(' ').first.capitalize();
String formatDate(String date) =>
Jiffy.parse(date).format(pattern: 'dd.MM.yyyy');
String getYear(String date, {String format = 'yyyy'}) =>
Jiffy.parse(date).format(pattern: format);
String getHolidayYear(String startDate, String endDate) =>
getYear(startDate) == getYear(endDate)
? getYear(startDate)
: '${getYear(startDate)}/${getYear(endDate, format: 'yy')}';
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(
'$holidayType ${getHolidayYear(holiday.start, holiday.end)}',
'${holiday.longName} ${holidayYear()}',
),
subtitle: Text(
'${formatDate(holiday.start)} - ${formatDate(holiday.end)}',
'${holiday.startDate.formatDate()} - ${holiday.endDate.formatDate()}',
),
onTap: () => showDetailsBottomSheet(
context,
header: Padding(
padding: const EdgeInsets.fromLTRB(16, 4, 16, 12),
child: Text(
'$holidayType ${holiday.year} in Hessen',
'${holiday.longName} ${holidayYear()}',
style: Theme.of(context).textTheme.titleLarge,
),
),
@@ -109,25 +113,23 @@ class HolidaysView extends StatelessWidget {
leading: const CenteredLeading(
Icon(Icons.signpost_outlined),
),
title: Text(holiday.name.capitalize()),
subtitle: Text(holiday.slug.capitalize()),
title: Text(holiday.longName),
subtitle: Text(holiday.shortName),
),
ListTile(
leading: const Icon(Icons.date_range_outlined),
title: Text('vom ${formatDate(holiday.start)}'),
title: Text('vom ${holiday.startDate.formatDate()}'),
),
ListTile(
leading: const Icon(Icons.date_range_outlined),
title: Text('bis zum ${formatDate(holiday.end)}'),
title: Text('bis zum ${holiday.endDate.formatDate()}'),
),
if (DateTime.parse(
holiday.start,
).difference(DateTime.now()).isNegative)
if (holiday.startDate.difference(DateTime.now()).isNegative)
ListTile(
leading: const CenteredLeading(
Icon(Icons.content_paste_search_outlined),
),
title: Text(Jiffy.parse(holiday.start).fromNow()),
title: Text(holiday.startDate.formatRelative()),
)
else
ListTile(
@@ -135,11 +137,10 @@ class HolidaysView extends StatelessWidget {
Icon(Icons.timer_outlined),
),
title: AnimatedTime(
callback: () => DateTime.parse(
holiday.start,
).difference(DateTime.now()),
callback: () =>
holiday.startDate.difference(DateTime.now()),
),
subtitle: Text(Jiffy.parse(holiday.start).fromNow()),
subtitle: Text(holiday.startDate.formatRelative()),
),
DebugTile(sheetCtx).jsonData(holiday.toJson()),
],
@@ -147,7 +148,8 @@ class HolidaysView extends StatelessWidget {
trailing: const Icon(Icons.arrow_right),
);
},
),
);
},
),
);
},