From 01b4b44010eec6373b965d13f7c7427703b76276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Sun, 24 May 2026 17:49:25 +0200 Subject: [PATCH] migrated holidays module to MarianumConnect API, replaced local `Holiday` model. --- .../marianumconnect/models/mc_holiday.dart | 30 ++ .../marianumconnect/models/mc_holiday.g.dart | 21 ++ .../queries/get_holidays/get_holidays.dart | 25 ++ .../timetable_get_holidays_response.dart | 30 +- .../timetable_get_holidays_response.g.dart | 14 - .../basis/dataloader/holiday_data_loader.dart | 8 - lib/state/app/modules/app_modules.dart | 2 +- .../modules/holidays/bloc/holidays_bloc.dart | 5 +- .../modules/holidays/bloc/holidays_state.dart | 19 +- .../holidays/bloc/holidays_state.freezed.dart | 312 +----------------- .../holidays/bloc/holidays_state.g.dart | 20 +- .../data_provider/holidays_get_holidays.dart | 14 - .../repository/holidays_repository.dart | 5 +- lib/view/pages/holidays/holidays_view.dart | 70 ++-- lib/widget/placeholder_view.dart | 42 ++- 15 files changed, 161 insertions(+), 456 deletions(-) create mode 100644 lib/api/marianumconnect/models/mc_holiday.dart create mode 100644 lib/api/marianumconnect/models/mc_holiday.g.dart create mode 100644 lib/api/marianumconnect/queries/get_holidays/get_holidays.dart delete mode 100644 lib/state/app/basis/dataloader/holiday_data_loader.dart delete mode 100644 lib/state/app/modules/holidays/data_provider/holidays_get_holidays.dart diff --git a/lib/api/marianumconnect/models/mc_holiday.dart b/lib/api/marianumconnect/models/mc_holiday.dart new file mode 100644 index 0000000..af4478d --- /dev/null +++ b/lib/api/marianumconnect/models/mc_holiday.dart @@ -0,0 +1,30 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'mc_holiday.g.dart'; + +@JsonSerializable(explicitToJson: true) +class McHoliday { + final String shortName; + final String longName; + + @JsonKey(fromJson: _dateFromJson, toJson: _dateToJson) + final DateTime startDate; + + @JsonKey(fromJson: _dateFromJson, toJson: _dateToJson) + final DateTime endDate; + + McHoliday({ + required this.shortName, + required this.longName, + required this.startDate, + required this.endDate, + }); + + factory McHoliday.fromJson(Map json) => + _$McHolidayFromJson(json); + Map toJson() => _$McHolidayToJson(this); + + static DateTime _dateFromJson(String raw) => DateTime.parse(raw); + static String _dateToJson(DateTime d) => + '${d.year.toString().padLeft(4, '0')}-${d.month.toString().padLeft(2, '0')}-${d.day.toString().padLeft(2, '0')}'; +} diff --git a/lib/api/marianumconnect/models/mc_holiday.g.dart b/lib/api/marianumconnect/models/mc_holiday.g.dart new file mode 100644 index 0000000..4d52890 --- /dev/null +++ b/lib/api/marianumconnect/models/mc_holiday.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'mc_holiday.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +McHoliday _$McHolidayFromJson(Map json) => McHoliday( + shortName: json['shortName'] as String, + longName: json['longName'] as String, + startDate: McHoliday._dateFromJson(json['startDate'] as String), + endDate: McHoliday._dateFromJson(json['endDate'] as String), +); + +Map _$McHolidayToJson(McHoliday instance) => { + 'shortName': instance.shortName, + 'longName': instance.longName, + 'startDate': McHoliday._dateToJson(instance.startDate), + 'endDate': McHoliday._dateToJson(instance.endDate), +}; diff --git a/lib/api/marianumconnect/queries/get_holidays/get_holidays.dart b/lib/api/marianumconnect/queries/get_holidays/get_holidays.dart new file mode 100644 index 0000000..f896f22 --- /dev/null +++ b/lib/api/marianumconnect/queries/get_holidays/get_holidays.dart @@ -0,0 +1,25 @@ +import 'package:dio/dio.dart'; + +import '../../errors/marianumconnect_error.dart'; +import '../../marianumconnect_api.dart'; +import '../../marianumconnect_endpoint.dart'; +import '../../models/mc_holiday.dart'; + +class GetHolidays { + final Dio _dio; + + GetHolidays({Dio? dio}) : _dio = dio ?? MarianumConnectApi.dio(); + + Future> run() async { + try { + final response = await _dio.get>( + MarianumConnectEndpoint.resolve('holidays'), + ); + return response.data! + .map((e) => McHoliday.fromJson(e as Map)) + .toList(); + } on DioException catch (e) { + throw mapMarianumConnectError(e); + } + } +} diff --git a/lib/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.dart b/lib/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.dart index 58360dc..409273b 100644 --- a/lib/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.dart +++ b/lib/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.dart @@ -1,36 +1,12 @@ import 'package:json_annotation/json_annotation.dart'; import '../../../api_response.dart'; +import '../../models/mc_holiday.dart'; + +export '../../models/mc_holiday.dart'; part 'timetable_get_holidays_response.g.dart'; -@JsonSerializable(explicitToJson: true) -class McHoliday { - final String shortName; - final String longName; - - @JsonKey(fromJson: _dateFromJson, toJson: _dateToJson) - final DateTime startDate; - - @JsonKey(fromJson: _dateFromJson, toJson: _dateToJson) - final DateTime endDate; - - McHoliday({ - required this.shortName, - required this.longName, - required this.startDate, - required this.endDate, - }); - - factory McHoliday.fromJson(Map json) => - _$McHolidayFromJson(json); - Map toJson() => _$McHolidayToJson(this); - - static DateTime _dateFromJson(String raw) => DateTime.parse(raw); - static String _dateToJson(DateTime d) => - '${d.year.toString().padLeft(4, '0')}-${d.month.toString().padLeft(2, '0')}-${d.day.toString().padLeft(2, '0')}'; -} - @JsonSerializable(explicitToJson: true) class TimetableGetHolidaysResponse extends ApiResponse { final List result; diff --git a/lib/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.g.dart b/lib/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.g.dart index a49a40f..6d094a4 100644 --- a/lib/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.g.dart +++ b/lib/api/marianumconnect/queries/timetable_get_holidays/timetable_get_holidays_response.g.dart @@ -6,20 +6,6 @@ part of 'timetable_get_holidays_response.dart'; // JsonSerializableGenerator // ************************************************************************** -McHoliday _$McHolidayFromJson(Map json) => McHoliday( - shortName: json['shortName'] as String, - longName: json['longName'] as String, - startDate: McHoliday._dateFromJson(json['startDate'] as String), - endDate: McHoliday._dateFromJson(json['endDate'] as String), -); - -Map _$McHolidayToJson(McHoliday instance) => { - 'shortName': instance.shortName, - 'longName': instance.longName, - 'startDate': McHoliday._dateToJson(instance.startDate), - 'endDate': McHoliday._dateToJson(instance.endDate), -}; - TimetableGetHolidaysResponse _$TimetableGetHolidaysResponseFromJson( Map json, ) => diff --git a/lib/state/app/basis/dataloader/holiday_data_loader.dart b/lib/state/app/basis/dataloader/holiday_data_loader.dart deleted file mode 100644 index b148ebe..0000000 --- a/lib/state/app/basis/dataloader/holiday_data_loader.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:dio/dio.dart'; - -import '../../infrastructure/data_loader/data_loader.dart'; - -abstract class HolidayDataLoader extends DataLoader { - HolidayDataLoader() - : super(Dio(BaseOptions(baseUrl: 'https://ferien-api.de/api/v1/'))); -} diff --git a/lib/state/app/modules/app_modules.dart b/lib/state/app/modules/app_modules.dart index e59ad63..83b95eb 100644 --- a/lib/state/app/modules/app_modules.dart +++ b/lib/state/app/modules/app_modules.dart @@ -115,7 +115,7 @@ class AppModule { Modules.holidays: AppModule( Modules.holidays, name: 'Schulferien', - icon: () => Icon(Icons.flight), + icon: () => Icon(Icons.beach_access_outlined), breakerArea: BreakerArea.more, create: HolidaysView.new, ), diff --git a/lib/state/app/modules/holidays/bloc/holidays_bloc.dart b/lib/state/app/modules/holidays/bloc/holidays_bloc.dart index bf2de75..4e5d4fe 100644 --- a/lib/state/app/modules/holidays/bloc/holidays_bloc.dart +++ b/lib/state/app/modules/holidays/bloc/holidays_bloc.dart @@ -1,3 +1,4 @@ +import '../../../../../api/marianumconnect/models/mc_holiday.dart'; import '../../../infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_hydrated_bloc.dart'; import '../../../infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_hydrated_bloc_event.dart'; import '../repository/holidays_repository.dart'; @@ -24,12 +25,12 @@ class HolidaysBloc bool showPastHolidays() => innerState?.showPastHolidays ?? false; bool showDisclaimerOnEntry() => innerState?.showDisclaimer ?? false; - List? getHolidays() => + List? getHolidays() => innerState?.holidays .where( (element) => showPastHolidays() || - DateTime.parse(element.end).isAfter(DateTime.now()), + element.endDate.isAfter(DateTime.now()), ) .toList() ?? []; diff --git a/lib/state/app/modules/holidays/bloc/holidays_state.dart b/lib/state/app/modules/holidays/bloc/holidays_state.dart index d2755e4..be47abd 100644 --- a/lib/state/app/modules/holidays/bloc/holidays_state.dart +++ b/lib/state/app/modules/holidays/bloc/holidays_state.dart @@ -1,6 +1,8 @@ import 'package:flutter/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import '../../../../../api/marianumconnect/models/mc_holiday.dart'; + part 'holidays_state.freezed.dart'; part 'holidays_state.g.dart'; @@ -9,24 +11,9 @@ abstract class HolidaysState with _$HolidaysState { const factory HolidaysState({ required bool showPastHolidays, required bool showDisclaimer, - required List holidays, + required List holidays, }) = _HolidaysState; factory HolidaysState.fromJson(Map json) => _$HolidaysStateFromJson(json); } - -@freezed -abstract class Holiday with _$Holiday { - const factory Holiday({ - required String start, - required String end, - required int year, - required String stateCode, - required String name, - required String slug, - }) = _Holiday; - - factory Holiday.fromJson(Map json) => - _$HolidayFromJson(json); -} diff --git a/lib/state/app/modules/holidays/bloc/holidays_state.freezed.dart b/lib/state/app/modules/holidays/bloc/holidays_state.freezed.dart index f8c2f15..56ec81b 100644 --- a/lib/state/app/modules/holidays/bloc/holidays_state.freezed.dart +++ b/lib/state/app/modules/holidays/bloc/holidays_state.freezed.dart @@ -15,7 +15,7 @@ T _$identity(T value) => value; /// @nodoc mixin _$HolidaysState implements DiagnosticableTreeMixin { - bool get showPastHolidays; bool get showDisclaimer; List get holidays; + bool get showPastHolidays; bool get showDisclaimer; List get holidays; /// Create a copy of HolidaysState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -54,7 +54,7 @@ abstract mixin class $HolidaysStateCopyWith<$Res> { factory $HolidaysStateCopyWith(HolidaysState value, $Res Function(HolidaysState) _then) = _$HolidaysStateCopyWithImpl; @useResult $Res call({ - bool showPastHolidays, bool showDisclaimer, List holidays + bool showPastHolidays, bool showDisclaimer, List holidays }); @@ -76,7 +76,7 @@ class _$HolidaysStateCopyWithImpl<$Res> showPastHolidays: null == showPastHolidays ? _self.showPastHolidays : showPastHolidays // ignore: cast_nullable_to_non_nullable as bool,showDisclaimer: null == showDisclaimer ? _self.showDisclaimer : showDisclaimer // ignore: cast_nullable_to_non_nullable as bool,holidays: null == holidays ? _self.holidays : holidays // ignore: cast_nullable_to_non_nullable -as List, +as List, )); } @@ -161,7 +161,7 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( bool showPastHolidays, bool showDisclaimer, List holidays)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( bool showPastHolidays, bool showDisclaimer, List holidays)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _HolidaysState() when $default != null: return $default(_that.showPastHolidays,_that.showDisclaimer,_that.holidays);case _: @@ -182,7 +182,7 @@ return $default(_that.showPastHolidays,_that.showDisclaimer,_that.holidays);case /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( bool showPastHolidays, bool showDisclaimer, List holidays) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( bool showPastHolidays, bool showDisclaimer, List holidays) $default,) {final _that = this; switch (_that) { case _HolidaysState(): return $default(_that.showPastHolidays,_that.showDisclaimer,_that.holidays);case _: @@ -202,7 +202,7 @@ return $default(_that.showPastHolidays,_that.showDisclaimer,_that.holidays);case /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( bool showPastHolidays, bool showDisclaimer, List holidays)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( bool showPastHolidays, bool showDisclaimer, List holidays)? $default,) {final _that = this; switch (_that) { case _HolidaysState() when $default != null: return $default(_that.showPastHolidays,_that.showDisclaimer,_that.holidays);case _: @@ -217,13 +217,13 @@ return $default(_that.showPastHolidays,_that.showDisclaimer,_that.holidays);case @JsonSerializable() class _HolidaysState with DiagnosticableTreeMixin implements HolidaysState { - const _HolidaysState({required this.showPastHolidays, required this.showDisclaimer, required final List holidays}): _holidays = holidays; + const _HolidaysState({required this.showPastHolidays, required this.showDisclaimer, required final List holidays}): _holidays = holidays; factory _HolidaysState.fromJson(Map json) => _$HolidaysStateFromJson(json); @override final bool showPastHolidays; @override final bool showDisclaimer; - final List _holidays; -@override List get holidays { + final List _holidays; +@override List get holidays { if (_holidays is EqualUnmodifiableListView) return _holidays; // ignore: implicit_dynamic_type return EqualUnmodifiableListView(_holidays); @@ -269,7 +269,7 @@ abstract mixin class _$HolidaysStateCopyWith<$Res> implements $HolidaysStateCopy factory _$HolidaysStateCopyWith(_HolidaysState value, $Res Function(_HolidaysState) _then) = __$HolidaysStateCopyWithImpl; @override @useResult $Res call({ - bool showPastHolidays, bool showDisclaimer, List holidays + bool showPastHolidays, bool showDisclaimer, List holidays }); @@ -291,297 +291,7 @@ class __$HolidaysStateCopyWithImpl<$Res> showPastHolidays: null == showPastHolidays ? _self.showPastHolidays : showPastHolidays // ignore: cast_nullable_to_non_nullable as bool,showDisclaimer: null == showDisclaimer ? _self.showDisclaimer : showDisclaimer // ignore: cast_nullable_to_non_nullable as bool,holidays: null == holidays ? _self._holidays : holidays // ignore: cast_nullable_to_non_nullable -as List, - )); -} - - -} - - -/// @nodoc -mixin _$Holiday implements DiagnosticableTreeMixin { - - String get start; String get end; int get year; String get stateCode; String get name; String get slug; -/// Create a copy of Holiday -/// with the given fields replaced by the non-null parameter values. -@JsonKey(includeFromJson: false, includeToJson: false) -@pragma('vm:prefer-inline') -$HolidayCopyWith get copyWith => _$HolidayCopyWithImpl(this as Holiday, _$identity); - - /// Serializes this Holiday to a JSON map. - Map toJson(); - -@override -void debugFillProperties(DiagnosticPropertiesBuilder properties) { - properties - ..add(DiagnosticsProperty('type', 'Holiday')) - ..add(DiagnosticsProperty('start', start))..add(DiagnosticsProperty('end', end))..add(DiagnosticsProperty('year', year))..add(DiagnosticsProperty('stateCode', stateCode))..add(DiagnosticsProperty('name', name))..add(DiagnosticsProperty('slug', slug)); -} - -@override -bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is Holiday&&(identical(other.start, start) || other.start == start)&&(identical(other.end, end) || other.end == end)&&(identical(other.year, year) || other.year == year)&&(identical(other.stateCode, stateCode) || other.stateCode == stateCode)&&(identical(other.name, name) || other.name == name)&&(identical(other.slug, slug) || other.slug == slug)); -} - -@JsonKey(includeFromJson: false, includeToJson: false) -@override -int get hashCode => Object.hash(runtimeType,start,end,year,stateCode,name,slug); - -@override -String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) { - return 'Holiday(start: $start, end: $end, year: $year, stateCode: $stateCode, name: $name, slug: $slug)'; -} - - -} - -/// @nodoc -abstract mixin class $HolidayCopyWith<$Res> { - factory $HolidayCopyWith(Holiday value, $Res Function(Holiday) _then) = _$HolidayCopyWithImpl; -@useResult -$Res call({ - String start, String end, int year, String stateCode, String name, String slug -}); - - - - -} -/// @nodoc -class _$HolidayCopyWithImpl<$Res> - implements $HolidayCopyWith<$Res> { - _$HolidayCopyWithImpl(this._self, this._then); - - final Holiday _self; - final $Res Function(Holiday) _then; - -/// Create a copy of Holiday -/// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? start = null,Object? end = null,Object? year = null,Object? stateCode = null,Object? name = null,Object? slug = null,}) { - return _then(_self.copyWith( -start: null == start ? _self.start : start // ignore: cast_nullable_to_non_nullable -as String,end: null == end ? _self.end : end // ignore: cast_nullable_to_non_nullable -as String,year: null == year ? _self.year : year // ignore: cast_nullable_to_non_nullable -as int,stateCode: null == stateCode ? _self.stateCode : stateCode // ignore: cast_nullable_to_non_nullable -as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable -as String,slug: null == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable -as String, - )); -} - -} - - -/// Adds pattern-matching-related methods to [Holiday]. -extension HolidayPatterns on Holiday { -/// A variant of `map` that fallback to returning `orElse`. -/// -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case final Subclass value: -/// return ...; -/// case _: -/// return orElse(); -/// } -/// ``` - -@optionalTypeArgs TResult maybeMap(TResult Function( _Holiday value)? $default,{required TResult orElse(),}){ -final _that = this; -switch (_that) { -case _Holiday() when $default != null: -return $default(_that);case _: - return orElse(); - -} -} -/// A `switch`-like method, using callbacks. -/// -/// Callbacks receives the raw object, upcasted. -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case final Subclass value: -/// return ...; -/// case final Subclass2 value: -/// return ...; -/// } -/// ``` - -@optionalTypeArgs TResult map(TResult Function( _Holiday value) $default,){ -final _that = this; -switch (_that) { -case _Holiday(): -return $default(_that);case _: - throw StateError('Unexpected subclass'); - -} -} -/// A variant of `map` that fallback to returning `null`. -/// -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case final Subclass value: -/// return ...; -/// case _: -/// return null; -/// } -/// ``` - -@optionalTypeArgs TResult? mapOrNull(TResult? Function( _Holiday value)? $default,){ -final _that = this; -switch (_that) { -case _Holiday() when $default != null: -return $default(_that);case _: - return null; - -} -} -/// A variant of `when` that fallback to an `orElse` callback. -/// -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case Subclass(:final field): -/// return ...; -/// case _: -/// return orElse(); -/// } -/// ``` - -@optionalTypeArgs TResult maybeWhen(TResult Function( String start, String end, int year, String stateCode, String name, String slug)? $default,{required TResult orElse(),}) {final _that = this; -switch (_that) { -case _Holiday() when $default != null: -return $default(_that.start,_that.end,_that.year,_that.stateCode,_that.name,_that.slug);case _: - return orElse(); - -} -} -/// A `switch`-like method, using callbacks. -/// -/// As opposed to `map`, this offers destructuring. -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case Subclass(:final field): -/// return ...; -/// case Subclass2(:final field2): -/// return ...; -/// } -/// ``` - -@optionalTypeArgs TResult when(TResult Function( String start, String end, int year, String stateCode, String name, String slug) $default,) {final _that = this; -switch (_that) { -case _Holiday(): -return $default(_that.start,_that.end,_that.year,_that.stateCode,_that.name,_that.slug);case _: - throw StateError('Unexpected subclass'); - -} -} -/// A variant of `when` that fallback to returning `null` -/// -/// It is equivalent to doing: -/// ```dart -/// switch (sealedClass) { -/// case Subclass(:final field): -/// return ...; -/// case _: -/// return null; -/// } -/// ``` - -@optionalTypeArgs TResult? whenOrNull(TResult? Function( String start, String end, int year, String stateCode, String name, String slug)? $default,) {final _that = this; -switch (_that) { -case _Holiday() when $default != null: -return $default(_that.start,_that.end,_that.year,_that.stateCode,_that.name,_that.slug);case _: - return null; - -} -} - -} - -/// @nodoc -@JsonSerializable() - -class _Holiday with DiagnosticableTreeMixin implements Holiday { - const _Holiday({required this.start, required this.end, required this.year, required this.stateCode, required this.name, required this.slug}); - factory _Holiday.fromJson(Map json) => _$HolidayFromJson(json); - -@override final String start; -@override final String end; -@override final int year; -@override final String stateCode; -@override final String name; -@override final String slug; - -/// Create a copy of Holiday -/// with the given fields replaced by the non-null parameter values. -@override @JsonKey(includeFromJson: false, includeToJson: false) -@pragma('vm:prefer-inline') -_$HolidayCopyWith<_Holiday> get copyWith => __$HolidayCopyWithImpl<_Holiday>(this, _$identity); - -@override -Map toJson() { - return _$HolidayToJson(this, ); -} -@override -void debugFillProperties(DiagnosticPropertiesBuilder properties) { - properties - ..add(DiagnosticsProperty('type', 'Holiday')) - ..add(DiagnosticsProperty('start', start))..add(DiagnosticsProperty('end', end))..add(DiagnosticsProperty('year', year))..add(DiagnosticsProperty('stateCode', stateCode))..add(DiagnosticsProperty('name', name))..add(DiagnosticsProperty('slug', slug)); -} - -@override -bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _Holiday&&(identical(other.start, start) || other.start == start)&&(identical(other.end, end) || other.end == end)&&(identical(other.year, year) || other.year == year)&&(identical(other.stateCode, stateCode) || other.stateCode == stateCode)&&(identical(other.name, name) || other.name == name)&&(identical(other.slug, slug) || other.slug == slug)); -} - -@JsonKey(includeFromJson: false, includeToJson: false) -@override -int get hashCode => Object.hash(runtimeType,start,end,year,stateCode,name,slug); - -@override -String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) { - return 'Holiday(start: $start, end: $end, year: $year, stateCode: $stateCode, name: $name, slug: $slug)'; -} - - -} - -/// @nodoc -abstract mixin class _$HolidayCopyWith<$Res> implements $HolidayCopyWith<$Res> { - factory _$HolidayCopyWith(_Holiday value, $Res Function(_Holiday) _then) = __$HolidayCopyWithImpl; -@override @useResult -$Res call({ - String start, String end, int year, String stateCode, String name, String slug -}); - - - - -} -/// @nodoc -class __$HolidayCopyWithImpl<$Res> - implements _$HolidayCopyWith<$Res> { - __$HolidayCopyWithImpl(this._self, this._then); - - final _Holiday _self; - final $Res Function(_Holiday) _then; - -/// Create a copy of Holiday -/// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? start = null,Object? end = null,Object? year = null,Object? stateCode = null,Object? name = null,Object? slug = null,}) { - return _then(_Holiday( -start: null == start ? _self.start : start // ignore: cast_nullable_to_non_nullable -as String,end: null == end ? _self.end : end // ignore: cast_nullable_to_non_nullable -as String,year: null == year ? _self.year : year // ignore: cast_nullable_to_non_nullable -as int,stateCode: null == stateCode ? _self.stateCode : stateCode // ignore: cast_nullable_to_non_nullable -as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable -as String,slug: null == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable -as String, +as List, )); } diff --git a/lib/state/app/modules/holidays/bloc/holidays_state.g.dart b/lib/state/app/modules/holidays/bloc/holidays_state.g.dart index 95211a2..4173e20 100644 --- a/lib/state/app/modules/holidays/bloc/holidays_state.g.dart +++ b/lib/state/app/modules/holidays/bloc/holidays_state.g.dart @@ -11,7 +11,7 @@ _HolidaysState _$HolidaysStateFromJson(Map json) => showPastHolidays: json['showPastHolidays'] as bool, showDisclaimer: json['showDisclaimer'] as bool, holidays: (json['holidays'] as List) - .map((e) => Holiday.fromJson(e as Map)) + .map((e) => McHoliday.fromJson(e as Map)) .toList(), ); @@ -21,21 +21,3 @@ Map _$HolidaysStateToJson(_HolidaysState instance) => 'showDisclaimer': instance.showDisclaimer, 'holidays': instance.holidays, }; - -_Holiday _$HolidayFromJson(Map json) => _Holiday( - start: json['start'] as String, - end: json['end'] as String, - year: (json['year'] as num).toInt(), - stateCode: json['stateCode'] as String, - name: json['name'] as String, - slug: json['slug'] as String, -); - -Map _$HolidayToJson(_Holiday instance) => { - 'start': instance.start, - 'end': instance.end, - 'year': instance.year, - 'stateCode': instance.stateCode, - 'name': instance.name, - 'slug': instance.slug, -}; diff --git a/lib/state/app/modules/holidays/data_provider/holidays_get_holidays.dart b/lib/state/app/modules/holidays/data_provider/holidays_get_holidays.dart deleted file mode 100644 index 79c9c60..0000000 --- a/lib/state/app/modules/holidays/data_provider/holidays_get_holidays.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:dio/dio.dart'; - -import '../../../basis/dataloader/holiday_data_loader.dart'; -import '../../../infrastructure/data_loader/data_loader.dart'; -import '../bloc/holidays_state.dart'; - -class HolidaysGetHolidays extends HolidayDataLoader> { - @override - List assemble(DataLoaderResult data) => - data.asListOfMaps().map(Holiday.fromJson).toList(); - - @override - Future> fetch() => dio.get('/holidays/HE'); -} diff --git a/lib/state/app/modules/holidays/repository/holidays_repository.dart b/lib/state/app/modules/holidays/repository/holidays_repository.dart index 7e964c6..b58e837 100644 --- a/lib/state/app/modules/holidays/repository/holidays_repository.dart +++ b/lib/state/app/modules/holidays/repository/holidays_repository.dart @@ -1,7 +1,8 @@ +import '../../../../../api/marianumconnect/models/mc_holiday.dart'; +import '../../../../../api/marianumconnect/queries/get_holidays/get_holidays.dart'; import '../../../infrastructure/repository/repository.dart'; import '../bloc/holidays_state.dart'; -import '../data_provider/holidays_get_holidays.dart'; class HolidaysRepository extends Repository { - Future> getHolidays() => HolidaysGetHolidays().run(); + Future> getHolidays() => GetHolidays().run(); } diff --git a/lib/view/pages/holidays/holidays_view.dart b/lib/view/pages/holidays/holidays_view.dart index 2018d2d..d3adae1 100644 --- a/lib/view/pages/holidays/holidays_view.dart +++ b/lib/view/pages/holidays/holidays_view.dart @@ -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( - 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( + 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), ); }, - ), + ); + }, ), ); }, diff --git a/lib/widget/placeholder_view.dart b/lib/widget/placeholder_view.dart index 27e114a..2c98806 100644 --- a/lib/widget/placeholder_view.dart +++ b/lib/widget/placeholder_view.dart @@ -12,26 +12,32 @@ class PlaceholderView extends StatelessWidget { }); @override - Widget build(BuildContext context) => Scaffold( - body: Center( - child: Container( - margin: const EdgeInsets.only(top: 100, left: 20, right: 20), - child: Column( - children: [ - Container( - margin: const EdgeInsets.all(30), - child: Icon(icon, size: 60), + Widget build(BuildContext context) => CustomScrollView( + physics: const AlwaysScrollableScrollPhysics(), + slivers: [ + SliverFillRemaining( + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.all(30), + child: Icon(icon, size: 60), + ), + Text( + text, + style: const TextStyle(fontSize: 20), + textAlign: TextAlign.center, + ), + const SizedBox(height: 30), + ?button, + ], ), - Text( - text, - style: const TextStyle(fontSize: 20), - textAlign: TextAlign.center, - ), - const SizedBox(height: 30), - ?button, - ], + ), ), ), - ), + ], ); }