diff --git a/lib/api/holidays/getHolidays.dart b/lib/api/holidays/getHolidays.dart
index 1d7be0b..8ce3325 100644
--- a/lib/api/holidays/getHolidays.dart
+++ b/lib/api/holidays/getHolidays.dart
@@ -1,5 +1,4 @@
 import 'dart:convert';
-
 import 'package:http/http.dart' as http;
 
 import 'getHolidaysResponse.dart';
@@ -7,11 +6,10 @@ import 'getHolidaysResponse.dart';
 class GetHolidays {
   Future<GetHolidaysResponse> query() async {
     var response = (await http.get(Uri.parse('https://ferien-api.de/api/v1/holidays/HE'))).body;
+    var data = jsonDecode(response) as List<dynamic>;
     return GetHolidaysResponse(
         List<GetHolidaysResponseObject>.from(
-            jsonDecode(response).map<GetHolidaysResponseObject>(
-                    GetHolidaysResponseObject.fromJson
-            )
+            data.map<GetHolidaysResponseObject>((e) => GetHolidaysResponseObject.fromJson(e as Map<String, dynamic>))
         )
     );
   }
diff --git a/lib/api/holidays/getHolidaysCache.dart b/lib/api/holidays/getHolidaysCache.dart
index d27a9ed..49e04e1 100644
--- a/lib/api/holidays/getHolidaysCache.dart
+++ b/lib/api/holidays/getHolidaysCache.dart
@@ -13,12 +13,11 @@ class GetHolidaysCache extends RequestCache<GetHolidaysResponse> {
   GetHolidaysResponse onLocalData(String json) {
     List<dynamic> parsedListJson = jsonDecode(json)['data'];
     return GetHolidaysResponse(
-        List<GetHolidaysResponseObject>.from(
-            parsedListJson.map<GetHolidaysResponseObject>(
-                    // ignore: unnecessary_lambdas
-                    (dynamic i) => GetHolidaysResponseObject.fromJson(i)
-            )
+      List<GetHolidaysResponseObject>.from(
+        parsedListJson.map<GetHolidaysResponseObject>(
+          (i) => GetHolidaysResponseObject.fromJson(i as Map<String, dynamic>)
         )
+      )
     );
   }
 
diff --git a/lib/state/app/basis/dataloader/holiday_data_loader.dart b/lib/state/app/basis/dataloader/holiday_data_loader.dart
new file mode 100644
index 0000000..19c345f
--- /dev/null
+++ b/lib/state/app/basis/dataloader/holiday_data_loader.dart
@@ -0,0 +1,9 @@
+import 'package:dio/dio.dart';
+
+import '../../infrastructure/dataLoader/data_loader.dart';
+
+abstract class HolidayDataLoader<TResult> extends DataLoader<TResult> {
+  HolidayDataLoader() : super(Dio(BaseOptions(
+    baseUrl: 'https://ferien-api.de/api/v1/',
+  )));
+}
diff --git a/lib/state/app/infrastructure/dataLoader/mhsl_data_loader.dart b/lib/state/app/basis/dataloader/mhsl_data_loader.dart
similarity index 78%
rename from lib/state/app/infrastructure/dataLoader/mhsl_data_loader.dart
rename to lib/state/app/basis/dataloader/mhsl_data_loader.dart
index 0825587..6b4baab 100644
--- a/lib/state/app/infrastructure/dataLoader/mhsl_data_loader.dart
+++ b/lib/state/app/basis/dataloader/mhsl_data_loader.dart
@@ -1,6 +1,6 @@
 import 'package:dio/dio.dart';
 
-import 'data_loader.dart';
+import '../../infrastructure/dataLoader/data_loader.dart';
 
 abstract class MhslDataLoader<TResult> extends DataLoader<TResult> {
   MhslDataLoader() : super(Dio(BaseOptions(
diff --git a/lib/state/app/infrastructure/dataLoader/data_loader.dart b/lib/state/app/infrastructure/dataLoader/data_loader.dart
index cb4a3fe..64c1aa7 100644
--- a/lib/state/app/infrastructure/dataLoader/data_loader.dart
+++ b/lib/state/app/infrastructure/dataLoader/data_loader.dart
@@ -35,8 +35,12 @@ abstract class DataLoader<TResult> {
 }
 
 class DataLoaderResult {
-  final Map<String, dynamic> json;
+  final dynamic json;
   final Map<String, String> headers;
 
+  Map<String, dynamic> asMap() => json as Map<String, dynamic>;
+  List<dynamic> asList() => json as List<dynamic>;
+  List<Map<String, dynamic>> asListOfMaps() => asList().map((e) => e as Map<String, dynamic>).toList();
+
   DataLoaderResult({required this.json, required this.headers});
 }
diff --git a/lib/state/app/infrastructure/loadableState/loadable_state.dart b/lib/state/app/infrastructure/loadableState/loadable_state.dart
index ac1626a..b163e41 100644
--- a/lib/state/app/infrastructure/loadableState/loadable_state.dart
+++ b/lib/state/app/infrastructure/loadableState/loadable_state.dart
@@ -9,11 +9,11 @@ class LoadableState<TState> with _$LoadableState {
   const LoadableState._();
 
   const factory LoadableState({
-    @Default(true) bool isLoading,
-    @Default(null) TState? data,
-    @Default(null) int? lastFetch,
-    @Default(null) void Function()? reFetch,
-    @Default(null) LoadingError? error,
+    required bool isLoading,
+    required TState? data,
+    required int? lastFetch,
+    required void Function()? reFetch,
+    required LoadingError? error,
   }) = _LoadableState;
 
   bool _hasError() => error != null;
diff --git a/lib/state/app/infrastructure/loadableState/view/loadable_state_consumer.dart b/lib/state/app/infrastructure/loadableState/view/loadable_state_consumer.dart
index 7d9244e..b0cdc65 100644
--- a/lib/state/app/infrastructure/loadableState/view/loadable_state_consumer.dart
+++ b/lib/state/app/infrastructure/loadableState/view/loadable_state_consumer.dart
@@ -15,14 +15,20 @@ import 'loadable_state_primary_loading.dart';
 
 class LoadableStateConsumer<TController extends Bloc<LoadableHydratedBlocEvent<TState>, LoadableState<TState>>, TState> extends StatelessWidget {
   final Widget Function(TState state, bool loading) child;
+  final void Function(TState state)? onLoad;
   final bool wrapWithScrollView;
-  const LoadableStateConsumer({required this.child, this.wrapWithScrollView = false, super.key});
+  const LoadableStateConsumer({required this.child, this.onLoad, this.wrapWithScrollView = false, super.key});
 
   static Duration animationDuration = const Duration(milliseconds: 200);
 
   @override
   Widget build(BuildContext context) {
     var loadableState = context.watch<TController>().state;
+
+    if(!loadableState.isLoading && onLoad != null) {
+      WidgetsBinding.instance.addPostFrameCallback((timeStamp) => onLoad!(loadableState.data));
+    }
+
     var childWidget = ConditionalWrapper(
       condition: loadableState.reFetch != null,
       wrapper: (child) => RefreshIndicator(
diff --git a/lib/state/app/infrastructure/loadableState/view/loadable_state_error_bar.dart b/lib/state/app/infrastructure/loadableState/view/loadable_state_error_bar.dart
index bc5353c..fd27b2b 100644
--- a/lib/state/app/infrastructure/loadableState/view/loadable_state_error_bar.dart
+++ b/lib/state/app/infrastructure/loadableState/view/loadable_state_error_bar.dart
@@ -89,4 +89,3 @@ class _LoadableStateErrorBarTextState extends State<LoadableStateErrorBarText> {
     super.dispose();
   }
 }
-
diff --git a/lib/state/app/infrastructure/utilityWidgets/bloc_module.dart b/lib/state/app/infrastructure/utilityWidgets/bloc_module.dart
index 35297b7..fa1bee7 100644
--- a/lib/state/app/infrastructure/utilityWidgets/bloc_module.dart
+++ b/lib/state/app/infrastructure/utilityWidgets/bloc_module.dart
@@ -5,14 +5,19 @@ class BlocModule<TBloc extends StateStreamableSource<TState>, TState> extends St
   final TBloc Function(BuildContext context) create;
   final Widget Function(BuildContext context, TBloc bloc, TState state) child;
   final bool autoRebuild;
-  const BlocModule({required this.create, required this.child, this.autoRebuild = false, super.key});
+  final void Function(BuildContext context, TBloc bloc)? onInitialisation;
+  const BlocModule({required this.create, required this.child, this.autoRebuild = false, this.onInitialisation, super.key});
 
   Widget rebuildChild(BuildContext context) => child(context, context.watch<TBloc>(), context.watch<TBloc>().state);
   Widget staticChild(BuildContext context) => child(context, context.read<TBloc>(), context.read<TBloc>().state);
 
   @override
   Widget build(BuildContext context) => BlocProvider<TBloc>(
-    create: create,
+    create: (context) {
+      var bloc = create(context);
+      this.onInitialisation != null ? this.onInitialisation!(context, bloc) : null;
+      return bloc;
+    },
     child: Builder(
       builder: (context) => autoRebuild
         ? rebuildChild(context)
diff --git a/lib/state/app/infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc.dart b/lib/state/app/infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc.dart
index 116bad2..66e20d6 100644
--- a/lib/state/app/infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc.dart
+++ b/lib/state/app/infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc.dart
@@ -17,23 +17,40 @@ abstract class LoadableHydratedBloc<
     LoadableState<TState>
 > {
   late TRepository _repository;
-  LoadableHydratedBloc() : super(const LoadableState()) {
+  LoadableHydratedBloc() : super(const LoadableState(
+    error: null,
+    data: null,
+    isLoading: true,
+    lastFetch: null,
+    reFetch: null,
+  )) {
 
-    on<Emit<TState>>((event, emit) => emit(LoadableState(
-        isLoading: event.loading,
+    on<Emit<TState>>((event, emit) {
+      emit(LoadableState(
+        isLoading: state.isLoading,
         data: event.state(innerState ?? fromNothing()),
-        lastFetch: DateTime.now().millisecondsSinceEpoch,
-        reFetch: retry
+        lastFetch: state.lastFetch,
+        reFetch: retry,
+        error: state.error,
+      ));
+    });
+
+    on<DataGathered<TState>>((event, emit) => emit(LoadableState(
+      isLoading: false,
+      data: event.state(innerState ?? fromNothing()),
+      lastFetch: DateTime.now().millisecondsSinceEpoch,
+      reFetch: retry,
+      error: null,
     )));
 
     on<RefetchStarted<TState>>((event, emit) => emit(LoadableState(
         isLoading: true,
         data: innerState,
-        lastFetch: state.lastFetch
+        lastFetch: state.lastFetch,
+        reFetch: null,
+        error: null,
     )));
 
-    on<ClearState<TState>>((event, emit) => emit(const LoadableState()));
-
     on<Error<TState>>((event, emit) => emit(LoadableState(
         isLoading: false,
         data: innerState,
@@ -61,7 +78,7 @@ abstract class LoadableHydratedBloc<
       (e) {
         log('Error while fetching ${TState.toString()}: ${e.toString()}');
         add(Error(LoadingError(
-          message: e.message,
+          message: e.message ?? e.toString(),
           allowRetry: true,
         )));
       },
@@ -73,14 +90,29 @@ abstract class LoadableHydratedBloc<
   @override
   fromJson(Map<String, dynamic> json) {
     var rawData = LoadableSaveContext.unwrap(json);
-    return LoadableState(isLoading: true, lastFetch: rawData.meta.timestamp, data: fromStorage(rawData.data));
+    return LoadableState(
+      isLoading: true,
+      data: fromStorage(rawData.data),
+      lastFetch: rawData.meta.timestamp,
+      reFetch: null,
+      error: null,
+    );
   }
 
   @override
-  Map<String, dynamic>? toJson(LoadableState<TState> state) => LoadableSaveContext.wrap(
-      toStorage(state.data),
+  Map<String, dynamic>? toJson(LoadableState<TState> state) {
+    Map<String, dynamic>? data;
+    try {
+      data = state.data == null ? null : toStorage(state.data);
+    } catch(e) {
+      log('Failed to save state ${TState.toString()}: ${e.toString()}');
+    }
+
+    return LoadableSaveContext.wrap(
+      data,
       state.lastFetch ?? DateTime.now().millisecondsSinceEpoch
-  );
+    );
+  }
 
   Future<void> gatherData();
   TRepository repository();
diff --git a/lib/state/app/infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart b/lib/state/app/infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart
index 06462de..55b8e6a 100644
--- a/lib/state/app/infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart
+++ b/lib/state/app/infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart
@@ -3,10 +3,12 @@ import '../../loadableState/loading_error.dart';
 class LoadableHydratedBlocEvent<TState> {}
 class Emit<TState> extends LoadableHydratedBlocEvent<TState> {
   final TState Function(TState state) state;
-  final bool loading;
-  Emit(this.state, {this.loading = false});
+  Emit(this.state);
+}
+class DataGathered<TState> extends LoadableHydratedBlocEvent<TState> {
+  final TState Function(TState state) state;
+  DataGathered(this.state);
 }
-class ClearState<TState> extends LoadableHydratedBlocEvent<TState> {}
 class Error<TState> extends LoadableHydratedBlocEvent<TState> {
   final LoadingError error;
   Error(this.error);
diff --git a/lib/state/app/infrastructure/utilityWidgets/loadableHydratedBloc/loadable_save_context.dart b/lib/state/app/infrastructure/utilityWidgets/loadableHydratedBloc/loadable_save_context.dart
index e4d68d5..0dea5cd 100644
--- a/lib/state/app/infrastructure/utilityWidgets/loadableHydratedBloc/loadable_save_context.dart
+++ b/lib/state/app/infrastructure/utilityWidgets/loadableHydratedBloc/loadable_save_context.dart
@@ -21,4 +21,3 @@ class LoadableSaveContext with _$LoadableSaveContext {
   static ({Map<String, dynamic> data, LoadableSaveContext meta}) unwrap(Map<String, dynamic> data) =>
       (data: data[dataKey] as Map<String, dynamic>, meta: LoadableSaveContext.fromJson(data[metaKey]));
 }
-
diff --git a/lib/state/app/modules/app_modules.dart b/lib/state/app/modules/app_modules.dart
index 83b93b5..796cfe6 100644
--- a/lib/state/app/modules/app_modules.dart
+++ b/lib/state/app/modules/app_modules.dart
@@ -4,12 +4,12 @@ import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
 import '../../../api/mhsl/breaker/getBreakers/getBreakersResponse.dart';
 import '../../../model/breakers/Breaker.dart';
 import '../../../view/pages/files/files.dart';
-import '../../../view/pages/more/holidays/holidays.dart';
 import '../../../view/pages/more/roomplan/roomplan.dart';
 import '../../../view/pages/talk/chatList.dart';
 import '../../../view/pages/timetable/timetable.dart';
 import '../../../widget/centeredLeading.dart';
 import 'gradeAverages/view/grade_averages_view.dart';
+import 'holidays/view/holidays_view.dart';
 import 'marianumMessage/view/marianum_message_list_view.dart';
 
 class AppModule {
@@ -26,7 +26,7 @@ class AppModule {
     Modules.marianumMessage: AppModule('Marianum Message', Icons.newspaper, MarianumMessageListView.new),
     Modules.roomPlan: AppModule('Raumplan', Icons.location_pin, Roomplan.new),
     Modules.gradeAveragesCalculator: AppModule('Notendurschnittsrechner', Icons.calculate, GradeAveragesView.new),
-    Modules.holidays: AppModule('Schulferien', Icons.holiday_village, Holidays.new),
+    Modules.holidays: AppModule('Schulferien', Icons.flight, HolidaysView.new),
   };
 
   static AppModule getModule(Modules module) => modules()[module]!;
diff --git a/lib/state/app/modules/holidays/bloc/holidays_bloc.dart b/lib/state/app/modules/holidays/bloc/holidays_bloc.dart
new file mode 100644
index 0000000..3f82d04
--- /dev/null
+++ b/lib/state/app/modules/holidays/bloc/holidays_bloc.dart
@@ -0,0 +1,37 @@
+import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc.dart';
+import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart';
+import '../repository/holidays_repository.dart';
+import 'holidays_event.dart';
+import 'holidays_state.dart';
+
+class HolidaysBloc extends LoadableHydratedBloc<HolidaysEvent, HolidaysState, HolidaysRepository> {
+  HolidaysBloc() {
+    on<SetPastHolidaysVisible>((event, emit) {
+      add(Emit((state) => state.copyWith(showPastHolidays: event.shouldBeVisible)));
+    });
+
+    on<DisclaimerDismissed>((event, emit) => add(
+      Emit((state) => state.copyWith(showDisclaimer: false))
+    ));
+  }
+
+  bool showPastHolidays() => innerState?.showPastHolidays ?? false;
+  bool showDisclaimerOnEntry() => innerState?.showDisclaimer ?? false;
+  List<Holiday>? getHolidays() => innerState?.holidays
+      .where((element) => showPastHolidays() || DateTime.parse(element.end).isAfter(DateTime.now()))
+      .toList() ?? [];
+
+  @override
+  fromNothing() => const HolidaysState(showPastHolidays: false, holidays: [], showDisclaimer: true);
+  @override
+  fromStorage(Map<String, dynamic> json) => HolidaysState.fromJson(json);
+  @override
+  Future<void> gatherData() async {
+    var holidays = await repo.getHolidays();
+    add(DataGathered((state) => state.copyWith(holidays: holidays)));
+  }
+  @override
+  repository() => HolidaysRepository();
+  @override
+  Map<String, dynamic>? toStorage(state) => state.toJson();
+}
diff --git a/lib/state/app/modules/holidays/bloc/holidays_event.dart b/lib/state/app/modules/holidays/bloc/holidays_event.dart
new file mode 100644
index 0000000..8565250
--- /dev/null
+++ b/lib/state/app/modules/holidays/bloc/holidays_event.dart
@@ -0,0 +1,9 @@
+import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart';
+import 'holidays_state.dart';
+
+sealed class HolidaysEvent extends LoadableHydratedBlocEvent<HolidaysState> {}
+class SetPastHolidaysVisible extends HolidaysEvent {
+  final bool shouldBeVisible;
+  SetPastHolidaysVisible(this.shouldBeVisible);
+}
+class DisclaimerDismissed extends HolidaysEvent {}
diff --git a/lib/state/app/modules/holidays/bloc/holidays_state.dart b/lib/state/app/modules/holidays/bloc/holidays_state.dart
new file mode 100644
index 0000000..05c0cd2
--- /dev/null
+++ b/lib/state/app/modules/holidays/bloc/holidays_state.dart
@@ -0,0 +1,30 @@
+import 'package:freezed_annotation/freezed_annotation.dart';
+import 'package:flutter/foundation.dart';
+
+part 'holidays_state.freezed.dart';
+part 'holidays_state.g.dart';
+
+@freezed
+class HolidaysState with _$HolidaysState {
+  const factory HolidaysState({
+    required bool showPastHolidays,
+    required bool showDisclaimer,
+    required List<Holiday> holidays,
+  }) = _HolidaysState;
+
+  factory HolidaysState.fromJson(Map<String, Object?> json) => _$HolidaysStateFromJson(json);
+}
+
+@freezed
+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<String, Object?> 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
new file mode 100644
index 0000000..6659f45
--- /dev/null
+++ b/lib/state/app/modules/holidays/bloc/holidays_state.freezed.dart
@@ -0,0 +1,463 @@
+// coverage:ignore-file
+// GENERATED CODE - DO NOT MODIFY BY HAND
+// ignore_for_file: type=lint
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
+
+part of 'holidays_state.dart';
+
+// **************************************************************************
+// FreezedGenerator
+// **************************************************************************
+
+T _$identity<T>(T value) => value;
+
+final _privateConstructorUsedError = UnsupportedError(
+    'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
+
+HolidaysState _$HolidaysStateFromJson(Map<String, dynamic> json) {
+  return _HolidaysState.fromJson(json);
+}
+
+/// @nodoc
+mixin _$HolidaysState {
+  bool get showPastHolidays => throw _privateConstructorUsedError;
+  bool get showDisclaimer => throw _privateConstructorUsedError;
+  List<Holiday> get holidays => throw _privateConstructorUsedError;
+
+  Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
+  @JsonKey(ignore: true)
+  $HolidaysStateCopyWith<HolidaysState> get copyWith =>
+      throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $HolidaysStateCopyWith<$Res> {
+  factory $HolidaysStateCopyWith(
+          HolidaysState value, $Res Function(HolidaysState) then) =
+      _$HolidaysStateCopyWithImpl<$Res, HolidaysState>;
+  @useResult
+  $Res call(
+      {bool showPastHolidays, bool showDisclaimer, List<Holiday> holidays});
+}
+
+/// @nodoc
+class _$HolidaysStateCopyWithImpl<$Res, $Val extends HolidaysState>
+    implements $HolidaysStateCopyWith<$Res> {
+  _$HolidaysStateCopyWithImpl(this._value, this._then);
+
+  // ignore: unused_field
+  final $Val _value;
+  // ignore: unused_field
+  final $Res Function($Val) _then;
+
+  @pragma('vm:prefer-inline')
+  @override
+  $Res call({
+    Object? showPastHolidays = null,
+    Object? showDisclaimer = null,
+    Object? holidays = null,
+  }) {
+    return _then(_value.copyWith(
+      showPastHolidays: null == showPastHolidays
+          ? _value.showPastHolidays
+          : showPastHolidays // ignore: cast_nullable_to_non_nullable
+              as bool,
+      showDisclaimer: null == showDisclaimer
+          ? _value.showDisclaimer
+          : showDisclaimer // ignore: cast_nullable_to_non_nullable
+              as bool,
+      holidays: null == holidays
+          ? _value.holidays
+          : holidays // ignore: cast_nullable_to_non_nullable
+              as List<Holiday>,
+    ) as $Val);
+  }
+}
+
+/// @nodoc
+abstract class _$$HolidaysStateImplCopyWith<$Res>
+    implements $HolidaysStateCopyWith<$Res> {
+  factory _$$HolidaysStateImplCopyWith(
+          _$HolidaysStateImpl value, $Res Function(_$HolidaysStateImpl) then) =
+      __$$HolidaysStateImplCopyWithImpl<$Res>;
+  @override
+  @useResult
+  $Res call(
+      {bool showPastHolidays, bool showDisclaimer, List<Holiday> holidays});
+}
+
+/// @nodoc
+class __$$HolidaysStateImplCopyWithImpl<$Res>
+    extends _$HolidaysStateCopyWithImpl<$Res, _$HolidaysStateImpl>
+    implements _$$HolidaysStateImplCopyWith<$Res> {
+  __$$HolidaysStateImplCopyWithImpl(
+      _$HolidaysStateImpl _value, $Res Function(_$HolidaysStateImpl) _then)
+      : super(_value, _then);
+
+  @pragma('vm:prefer-inline')
+  @override
+  $Res call({
+    Object? showPastHolidays = null,
+    Object? showDisclaimer = null,
+    Object? holidays = null,
+  }) {
+    return _then(_$HolidaysStateImpl(
+      showPastHolidays: null == showPastHolidays
+          ? _value.showPastHolidays
+          : showPastHolidays // ignore: cast_nullable_to_non_nullable
+              as bool,
+      showDisclaimer: null == showDisclaimer
+          ? _value.showDisclaimer
+          : showDisclaimer // ignore: cast_nullable_to_non_nullable
+              as bool,
+      holidays: null == holidays
+          ? _value._holidays
+          : holidays // ignore: cast_nullable_to_non_nullable
+              as List<Holiday>,
+    ));
+  }
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$HolidaysStateImpl
+    with DiagnosticableTreeMixin
+    implements _HolidaysState {
+  const _$HolidaysStateImpl(
+      {required this.showPastHolidays,
+      required this.showDisclaimer,
+      required final List<Holiday> holidays})
+      : _holidays = holidays;
+
+  factory _$HolidaysStateImpl.fromJson(Map<String, dynamic> json) =>
+      _$$HolidaysStateImplFromJson(json);
+
+  @override
+  final bool showPastHolidays;
+  @override
+  final bool showDisclaimer;
+  final List<Holiday> _holidays;
+  @override
+  List<Holiday> get holidays {
+    if (_holidays is EqualUnmodifiableListView) return _holidays;
+    // ignore: implicit_dynamic_type
+    return EqualUnmodifiableListView(_holidays);
+  }
+
+  @override
+  String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
+    return 'HolidaysState(showPastHolidays: $showPastHolidays, showDisclaimer: $showDisclaimer, holidays: $holidays)';
+  }
+
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties
+      ..add(DiagnosticsProperty('type', 'HolidaysState'))
+      ..add(DiagnosticsProperty('showPastHolidays', showPastHolidays))
+      ..add(DiagnosticsProperty('showDisclaimer', showDisclaimer))
+      ..add(DiagnosticsProperty('holidays', holidays));
+  }
+
+  @override
+  bool operator ==(Object other) {
+    return identical(this, other) ||
+        (other.runtimeType == runtimeType &&
+            other is _$HolidaysStateImpl &&
+            (identical(other.showPastHolidays, showPastHolidays) ||
+                other.showPastHolidays == showPastHolidays) &&
+            (identical(other.showDisclaimer, showDisclaimer) ||
+                other.showDisclaimer == showDisclaimer) &&
+            const DeepCollectionEquality().equals(other._holidays, _holidays));
+  }
+
+  @JsonKey(ignore: true)
+  @override
+  int get hashCode => Object.hash(runtimeType, showPastHolidays, showDisclaimer,
+      const DeepCollectionEquality().hash(_holidays));
+
+  @JsonKey(ignore: true)
+  @override
+  @pragma('vm:prefer-inline')
+  _$$HolidaysStateImplCopyWith<_$HolidaysStateImpl> get copyWith =>
+      __$$HolidaysStateImplCopyWithImpl<_$HolidaysStateImpl>(this, _$identity);
+
+  @override
+  Map<String, dynamic> toJson() {
+    return _$$HolidaysStateImplToJson(
+      this,
+    );
+  }
+}
+
+abstract class _HolidaysState implements HolidaysState {
+  const factory _HolidaysState(
+      {required final bool showPastHolidays,
+      required final bool showDisclaimer,
+      required final List<Holiday> holidays}) = _$HolidaysStateImpl;
+
+  factory _HolidaysState.fromJson(Map<String, dynamic> json) =
+      _$HolidaysStateImpl.fromJson;
+
+  @override
+  bool get showPastHolidays;
+  @override
+  bool get showDisclaimer;
+  @override
+  List<Holiday> get holidays;
+  @override
+  @JsonKey(ignore: true)
+  _$$HolidaysStateImplCopyWith<_$HolidaysStateImpl> get copyWith =>
+      throw _privateConstructorUsedError;
+}
+
+Holiday _$HolidayFromJson(Map<String, dynamic> json) {
+  return _Holiday.fromJson(json);
+}
+
+/// @nodoc
+mixin _$Holiday {
+  String get start => throw _privateConstructorUsedError;
+  String get end => throw _privateConstructorUsedError;
+  int get year => throw _privateConstructorUsedError;
+  String get stateCode => throw _privateConstructorUsedError;
+  String get name => throw _privateConstructorUsedError;
+  String get slug => throw _privateConstructorUsedError;
+
+  Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
+  @JsonKey(ignore: true)
+  $HolidayCopyWith<Holiday> get copyWith => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $HolidayCopyWith<$Res> {
+  factory $HolidayCopyWith(Holiday value, $Res Function(Holiday) then) =
+      _$HolidayCopyWithImpl<$Res, Holiday>;
+  @useResult
+  $Res call(
+      {String start,
+      String end,
+      int year,
+      String stateCode,
+      String name,
+      String slug});
+}
+
+/// @nodoc
+class _$HolidayCopyWithImpl<$Res, $Val extends Holiday>
+    implements $HolidayCopyWith<$Res> {
+  _$HolidayCopyWithImpl(this._value, this._then);
+
+  // ignore: unused_field
+  final $Val _value;
+  // ignore: unused_field
+  final $Res Function($Val) _then;
+
+  @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(_value.copyWith(
+      start: null == start
+          ? _value.start
+          : start // ignore: cast_nullable_to_non_nullable
+              as String,
+      end: null == end
+          ? _value.end
+          : end // ignore: cast_nullable_to_non_nullable
+              as String,
+      year: null == year
+          ? _value.year
+          : year // ignore: cast_nullable_to_non_nullable
+              as int,
+      stateCode: null == stateCode
+          ? _value.stateCode
+          : stateCode // ignore: cast_nullable_to_non_nullable
+              as String,
+      name: null == name
+          ? _value.name
+          : name // ignore: cast_nullable_to_non_nullable
+              as String,
+      slug: null == slug
+          ? _value.slug
+          : slug // ignore: cast_nullable_to_non_nullable
+              as String,
+    ) as $Val);
+  }
+}
+
+/// @nodoc
+abstract class _$$HolidayImplCopyWith<$Res> implements $HolidayCopyWith<$Res> {
+  factory _$$HolidayImplCopyWith(
+          _$HolidayImpl value, $Res Function(_$HolidayImpl) then) =
+      __$$HolidayImplCopyWithImpl<$Res>;
+  @override
+  @useResult
+  $Res call(
+      {String start,
+      String end,
+      int year,
+      String stateCode,
+      String name,
+      String slug});
+}
+
+/// @nodoc
+class __$$HolidayImplCopyWithImpl<$Res>
+    extends _$HolidayCopyWithImpl<$Res, _$HolidayImpl>
+    implements _$$HolidayImplCopyWith<$Res> {
+  __$$HolidayImplCopyWithImpl(
+      _$HolidayImpl _value, $Res Function(_$HolidayImpl) _then)
+      : super(_value, _then);
+
+  @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(_$HolidayImpl(
+      start: null == start
+          ? _value.start
+          : start // ignore: cast_nullable_to_non_nullable
+              as String,
+      end: null == end
+          ? _value.end
+          : end // ignore: cast_nullable_to_non_nullable
+              as String,
+      year: null == year
+          ? _value.year
+          : year // ignore: cast_nullable_to_non_nullable
+              as int,
+      stateCode: null == stateCode
+          ? _value.stateCode
+          : stateCode // ignore: cast_nullable_to_non_nullable
+              as String,
+      name: null == name
+          ? _value.name
+          : name // ignore: cast_nullable_to_non_nullable
+              as String,
+      slug: null == slug
+          ? _value.slug
+          : slug // ignore: cast_nullable_to_non_nullable
+              as String,
+    ));
+  }
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$HolidayImpl with DiagnosticableTreeMixin implements _Holiday {
+  const _$HolidayImpl(
+      {required this.start,
+      required this.end,
+      required this.year,
+      required this.stateCode,
+      required this.name,
+      required this.slug});
+
+  factory _$HolidayImpl.fromJson(Map<String, dynamic> json) =>
+      _$$HolidayImplFromJson(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;
+
+  @override
+  String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
+    return 'Holiday(start: $start, end: $end, year: $year, stateCode: $stateCode, name: $name, slug: $slug)';
+  }
+
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(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 _$HolidayImpl &&
+            (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(ignore: true)
+  @override
+  int get hashCode =>
+      Object.hash(runtimeType, start, end, year, stateCode, name, slug);
+
+  @JsonKey(ignore: true)
+  @override
+  @pragma('vm:prefer-inline')
+  _$$HolidayImplCopyWith<_$HolidayImpl> get copyWith =>
+      __$$HolidayImplCopyWithImpl<_$HolidayImpl>(this, _$identity);
+
+  @override
+  Map<String, dynamic> toJson() {
+    return _$$HolidayImplToJson(
+      this,
+    );
+  }
+}
+
+abstract class _Holiday implements Holiday {
+  const factory _Holiday(
+      {required final String start,
+      required final String end,
+      required final int year,
+      required final String stateCode,
+      required final String name,
+      required final String slug}) = _$HolidayImpl;
+
+  factory _Holiday.fromJson(Map<String, dynamic> json) = _$HolidayImpl.fromJson;
+
+  @override
+  String get start;
+  @override
+  String get end;
+  @override
+  int get year;
+  @override
+  String get stateCode;
+  @override
+  String get name;
+  @override
+  String get slug;
+  @override
+  @JsonKey(ignore: true)
+  _$$HolidayImplCopyWith<_$HolidayImpl> get copyWith =>
+      throw _privateConstructorUsedError;
+}
diff --git a/lib/state/app/modules/holidays/bloc/holidays_state.g.dart b/lib/state/app/modules/holidays/bloc/holidays_state.g.dart
new file mode 100644
index 0000000..1d0f3f0
--- /dev/null
+++ b/lib/state/app/modules/holidays/bloc/holidays_state.g.dart
@@ -0,0 +1,43 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'holidays_state.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+_$HolidaysStateImpl _$$HolidaysStateImplFromJson(Map<String, dynamic> json) =>
+    _$HolidaysStateImpl(
+      showPastHolidays: json['showPastHolidays'] as bool,
+      showDisclaimer: json['showDisclaimer'] as bool,
+      holidays: (json['holidays'] as List<dynamic>)
+          .map((e) => Holiday.fromJson(e as Map<String, dynamic>))
+          .toList(),
+    );
+
+Map<String, dynamic> _$$HolidaysStateImplToJson(_$HolidaysStateImpl instance) =>
+    <String, dynamic>{
+      'showPastHolidays': instance.showPastHolidays,
+      'showDisclaimer': instance.showDisclaimer,
+      'holidays': instance.holidays,
+    };
+
+_$HolidayImpl _$$HolidayImplFromJson(Map<String, dynamic> json) =>
+    _$HolidayImpl(
+      start: json['start'] as String,
+      end: json['end'] as String,
+      year: json['year'] as int,
+      stateCode: json['stateCode'] as String,
+      name: json['name'] as String,
+      slug: json['slug'] as String,
+    );
+
+Map<String, dynamic> _$$HolidayImplToJson(_$HolidayImpl instance) =>
+    <String, dynamic>{
+      '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/dataProvider/holidays_get_holidays.dart b/lib/state/app/modules/holidays/dataProvider/holidays_get_holidays.dart
new file mode 100644
index 0000000..cd52128
--- /dev/null
+++ b/lib/state/app/modules/holidays/dataProvider/holidays_get_holidays.dart
@@ -0,0 +1,13 @@
+import 'package:dio/dio.dart';
+
+import '../../../basis/dataloader/holiday_data_loader.dart';
+import '../../../infrastructure/dataLoader/data_loader.dart';
+import '../bloc/holidays_state.dart';
+
+class HolidaysGetHolidays extends HolidayDataLoader<List<Holiday>> {
+  @override
+  List<Holiday> assemble(DataLoaderResult data) => data.asListOfMaps().map(Holiday.fromJson).toList();
+
+  @override
+  Future<Response<String>> 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
new file mode 100644
index 0000000..72ec949
--- /dev/null
+++ b/lib/state/app/modules/holidays/repository/holidays_repository.dart
@@ -0,0 +1,7 @@
+import '../../../infrastructure/repository/repository.dart';
+import '../bloc/holidays_state.dart';
+import '../dataProvider/holidays_get_holidays.dart';
+
+class HolidaysRepository extends Repository<HolidaysState> {
+  Future<List<Holiday>> getHolidays() => HolidaysGetHolidays().run();
+}
diff --git a/lib/state/app/modules/holidays/view/holidays_view.dart b/lib/state/app/modules/holidays/view/holidays_view.dart
new file mode 100644
index 0000000..41be1f3
--- /dev/null
+++ b/lib/state/app/modules/holidays/view/holidays_view.dart
@@ -0,0 +1,119 @@
+import 'package:flutter/material.dart';
+import 'package:jiffy/jiffy.dart';
+
+import '../../../../../widget/animatedTime.dart';
+import '../../../../../widget/list_view_util.dart';
+import '../../../../../widget/centeredLeading.dart';
+import '../../../../../widget/debug/debugTile.dart';
+import '../../../../../widget/string_extensions.dart';
+import '../../../infrastructure/loadableState/loadable_state.dart';
+import '../../../infrastructure/loadableState/view/loadable_state_consumer.dart';
+import '../../../infrastructure/utilityWidgets/bloc_module.dart';
+import '../bloc/holidays_bloc.dart';
+import '../bloc/holidays_event.dart';
+import '../bloc/holidays_state.dart';
+
+class HolidaysView extends StatelessWidget {
+  const HolidaysView({super.key});
+
+  @override
+  Widget build(BuildContext context) => BlocModule<HolidaysBloc, LoadableState<HolidaysState>>(
+    create: (context) => HolidaysBloc(),
+    autoRebuild: true,
+    child: (context, bloc, state) {
+      void showDisclaimer() {
+        showDialog(context: context, builder: (context) => AlertDialog(
+          title: const Text('Richtigkeit und Bereitstellung der Daten'),
+          content: const Text(''
+              '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/'),
+          actions: [
+            TextButton(child: const Text('Okay'), onPressed: () => Navigator.of(context).pop()),
+          ],
+        ));
+      }
+
+      return Scaffold(
+        appBar: AppBar(
+          title: const Text('Schulferien in Hessen'),
+          actions: [
+            IconButton(
+              icon: const Icon(Icons.info_outline),
+              onPressed: showDisclaimer,
+            ),
+            PopupMenuButton<bool>(
+              initialValue: bloc.showPastHolidays(),
+              icon: const Icon(Icons.history),
+              itemBuilder: (context) => [true, false].map((e) => PopupMenuItem<bool>(
+                  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<HolidaysBloc, HolidaysState>(
+          onLoad: (state) {
+            if(state.showDisclaimer) showDisclaimer();
+            bloc.add(DisclaimerDismissed());
+          },
+          child: (state, loading) => ListViewUtil.fromList<Holiday>(bloc.getHolidays(), (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')}';
+
+            return ListTile(
+              leading: const CenteredLeading(Icon(Icons.calendar_month)),
+              title: Text('$holidayType ${getHolidayYear(holiday.start, holiday.end)}'),
+              subtitle: Text('${formatDate(holiday.start)} - ${formatDate(holiday.end)}'),
+              onTap: () => showDialog(context: context, builder: (context) => SimpleDialog(
+                title: Text('$holidayType ${holiday.year} in Hessen'),
+                children: [
+                  ListTile(
+                    leading: const CenteredLeading(Icon(Icons.signpost_outlined)),
+                    title: Text(holiday.name.capitalize()),
+                    subtitle: Text(holiday.slug.capitalize()),
+                  ),
+                  ListTile(
+                    leading: const Icon(Icons.date_range_outlined),
+                    title: Text('vom ${formatDate(holiday.start)}'),
+                  ),
+                  ListTile(
+                    leading: const Icon(Icons.date_range_outlined),
+                    title: Text('bis zum ${formatDate(holiday.end)}'),
+                  ),
+                  Visibility(
+                    visible: !DateTime.parse(holiday.start).difference(DateTime.now()).isNegative,
+                    replacement: ListTile(
+                      leading: const CenteredLeading(Icon(Icons.content_paste_search_outlined)),
+                      title: Text(Jiffy.parse(holiday.start).fromNow()),
+                    ),
+                    child: ListTile(
+                      leading: const CenteredLeading(Icon(Icons.timer_outlined)),
+                      title: AnimatedTime(callback: () => DateTime.parse(holiday.start).difference(DateTime.now())),
+                      subtitle: Text(Jiffy.parse(holiday.start).fromNow()),
+                    ),
+                  ),
+                  DebugTile(context).jsonData(holiday.toJson()),
+                ],
+              )),
+              trailing: const Icon(Icons.arrow_right),
+            );
+          }),
+        ),
+      );
+    },
+  );
+}
diff --git a/lib/state/app/modules/marianumMessage/bloc/marianum_message_bloc.dart b/lib/state/app/modules/marianumMessage/bloc/marianum_message_bloc.dart
index 7876351..97c3b95 100644
--- a/lib/state/app/modules/marianumMessage/bloc/marianum_message_bloc.dart
+++ b/lib/state/app/modules/marianumMessage/bloc/marianum_message_bloc.dart
@@ -8,7 +8,7 @@ class MarianumMessageBloc extends LoadableHydratedBloc<MarianumMessageEvent, Mar
   @override
   Future<void> gatherData() async {
     var messages = await repo.getMessages();
-    add(Emit((state) => state.copyWith(messageList: messages)));
+    add(DataGathered((state) => state.copyWith(messageList: messages)));
   }
 
   @override
diff --git a/lib/state/app/modules/marianumMessage/dataProvider/marianum_message_get_messages.dart b/lib/state/app/modules/marianumMessage/dataProvider/marianum_message_get_messages.dart
index cb7f9db..f8c4b24 100644
--- a/lib/state/app/modules/marianumMessage/dataProvider/marianum_message_get_messages.dart
+++ b/lib/state/app/modules/marianumMessage/dataProvider/marianum_message_get_messages.dart
@@ -1,7 +1,7 @@
 import 'package:dio/dio.dart';
 
 import '../../../infrastructure/dataLoader/data_loader.dart';
-import '../../../infrastructure/dataLoader/mhsl_data_loader.dart';
+import '../../../basis/dataloader/mhsl_data_loader.dart';
 import '../bloc/marianum_message_state.dart';
 
 class MarianumMessageGetMessages extends MhslDataLoader<MarianumMessageList> {
diff --git a/lib/view/pages/more/feedback/feedbackDialog.dart b/lib/view/pages/more/feedback/feedbackDialog.dart
index c3b6d15..f78eea2 100644
--- a/lib/view/pages/more/feedback/feedbackDialog.dart
+++ b/lib/view/pages/more/feedback/feedbackDialog.dart
@@ -60,12 +60,17 @@ class _FeedbackDialogState extends State<FeedbackDialog> {
             Padding(
               padding: const EdgeInsets.all(10),
               child: TextField(
+                onChanged: (value) {
+                  if(value.trim().toLowerCase() == 'ranzig') {
+                    _feedbackInput.text = 'selber';
+                  }
+                },
                 controller: _feedbackInput,
                 autofocus: true,
                 decoration: InputDecoration(
                   border: const OutlineInputBorder(),
                   label: const Text('Feedback und Verbesserungen'),
-                  errorText: _textFieldEmpty ? 'Bitte gib eine Beschreibung an' : null,
+                  errorText: _textFieldEmpty ? 'Bitte gib eine Beschreibung an???' : null,
                 ),
                 minLines: 4,
                 maxLines: 7,
diff --git a/lib/view/pages/more/holidays/holidays.dart b/lib/view/pages/more/holidays/holidays.dart
deleted file mode 100644
index 6d5df2a..0000000
--- a/lib/view/pages/more/holidays/holidays.dart
+++ /dev/null
@@ -1,157 +0,0 @@
-import 'dart:core';
-
-import 'package:flutter/material.dart';
-import 'package:jiffy/jiffy.dart';
-import 'package:provider/provider.dart';
-
-import '../../../../model/holidays/holidaysProps.dart';
-import '../../../../storage/base/settingsProvider.dart';
-import '../../../../widget/centeredLeading.dart';
-import '../../../../widget/confirmDialog.dart';
-import '../../../../widget/debug/debugTile.dart';
-import '../../../../widget/loadingSpinner.dart';
-import '../../../../widget/placeholderView.dart';
-import '../../../../widget/animatedTime.dart';
-
-class Holidays extends StatefulWidget {
-  const Holidays({super.key});
-
-  @override
-  State<Holidays> createState() => _HolidaysState();
-}
-
-extension StringExtension on String {
-  String capitalize() => '${this[0].toUpperCase()}${substring(1).toLowerCase()}';
-}
-
-class _HolidaysState extends State<Holidays> {
-  late SettingsProvider settings = Provider.of<SettingsProvider>(context, listen: false);
-  late bool showPastEvents = settings.val().holidaysSettings.showPastEvents;
-
-  @override
-  void initState() {
-    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
-      Provider.of<HolidaysProps>(context, listen: false).run();
-      if(!settings.val().holidaysSettings.dismissedDisclaimer) showDisclaimer();
-    });
-
-    super.initState();
-  }
-
-  String parseString(String enDate) => Jiffy.parse(enDate).format(pattern: 'dd.MM.yyyy');
-
-  void showDisclaimer() {
-    showDialog(context: context, builder: (context) => AlertDialog(
-        title: const Text('Richtigkeit und Bereitstellung der Daten'),
-        content: Column(
-          mainAxisSize: MainAxisSize.min,
-          children: [
-            const Text(''
-                '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/'),
-            const SizedBox(height: 30),
-            ListTile(
-              title: const Text('Diese Meldung nicht mehr anzeigen'),
-              trailing: Checkbox(
-                value: settings.val().holidaysSettings.dismissedDisclaimer,
-                onChanged: (value) => settings.val(write: true).holidaysSettings.dismissedDisclaimer = value!,
-              ),
-            )
-          ],
-        ),
-        actions: [
-          TextButton(child: const Text('ferien-api.de besuchen'), onPressed: () => ConfirmDialog.openBrowser(context, 'https://ferien-api.de/')),
-          TextButton(child: const Text('Okay'), onPressed: () => Navigator.of(context).pop()),
-        ],
-      ));
-  }
-
-  @override
-  Widget build(BuildContext context) => Scaffold(
-      appBar: AppBar(
-        title: const Text('Schulferien in Hessen'),
-        actions: [
-          IconButton(
-            icon: const Icon(Icons.warning_amber_outlined),
-            onPressed: showDisclaimer,
-          ),
-          PopupMenuButton<bool>(
-            initialValue: settings.val().holidaysSettings.showPastEvents,
-            icon: const Icon(Icons.manage_history_outlined),
-            itemBuilder: (context) => [true, false].map((e) => PopupMenuItem<bool>(
-                  value: e,
-                  enabled: e != showPastEvents,
-                  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) {
-              setState(() {
-                showPastEvents = e;
-                settings.val(write: true).holidaysSettings.showPastEvents = e;
-              });
-            },
-          ),
-        ],
-      ),
-      body: Consumer<HolidaysProps>(builder: (context, value, child) {
-        if(value.primaryLoading()) return const LoadingSpinner();
-
-        var holidays = value.getHolidaysResponse.data;
-        if(!showPastEvents) holidays = holidays.where((element) => DateTime.parse(element.end).isAfter(DateTime.now())).toList();
-
-        if(holidays.isEmpty) return const PlaceholderView(icon: Icons.search_off, text: 'Es wurden keine Ferieneinträge gefunden!');
-
-        return ListView.builder(
-            itemCount: holidays.length,
-            itemBuilder: (context, index) {
-              var holiday = holidays[index];
-              var holidayType = holiday.name.split(' ').first.capitalize();
-              return ListTile(
-                leading: const CenteredLeading(Icon(Icons.calendar_month)),
-                title: Text('$holidayType ab ${parseString(holiday.start)}'),
-                subtitle: Text('bis ${parseString(holiday.end)}'),
-                onTap: () => showDialog(context: context, builder: (context) => SimpleDialog(
-                  title: Text('$holidayType ${holiday.year} in Hessen'),
-                  children: [
-                    ListTile(
-                      leading: const CenteredLeading(Icon(Icons.signpost_outlined)),
-                      title: Text(holiday.name),
-                      subtitle: Text(holiday.slug),
-                    ),
-                    ListTile(
-                      leading: const Icon(Icons.arrow_forward),
-                      title: Text('vom ${parseString(holiday.start)}'),
-                    ),
-                    ListTile(
-                      leading: const Icon(Icons.arrow_back),
-                      title: Text('bis zum ${parseString(holiday.end)}'),
-                    ),
-                    Visibility(
-                      visible: !DateTime.parse(holiday.start).difference(DateTime.now()).isNegative,
-                      replacement: ListTile(
-                        leading: const CenteredLeading(Icon(Icons.content_paste_search_outlined)),
-                        title: Text(Jiffy.parse(holiday.start).fromNow()),
-                      ),
-                      child: ListTile(
-                        leading: const CenteredLeading(Icon(Icons.timer_outlined)),
-                        title: AnimatedTime(callback: () => DateTime.parse(holiday.start).difference(DateTime.now())),
-                        subtitle: Text(Jiffy.parse(holiday.start).fromNow()),
-                      ),
-                    ),
-                    DebugTile(context).jsonData(holiday.toJson()),
-                  ],
-                )),
-                trailing: const Icon(Icons.arrow_right),
-              );
-            },
-          );
-        },
-      )
-    );
-}
diff --git a/lib/view/pages/talk/components/chatBubble.dart b/lib/view/pages/talk/components/chatBubble.dart
index 8110c1c..0539f19 100644
--- a/lib/view/pages/talk/components/chatBubble.dart
+++ b/lib/view/pages/talk/components/chatBubble.dart
@@ -2,7 +2,6 @@ import 'package:better_open_file/better_open_file.dart';
 import 'package:bubble/bubble.dart';
 import 'package:emoji_picker_flutter/emoji_picker_flutter.dart' as emojis;
 import 'package:flowder/flowder.dart';
-import 'package:flutter/cupertino.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
diff --git a/lib/view/pages/talk/components/chatBubbleStyles.dart b/lib/view/pages/talk/components/chatBubbleStyles.dart
index c640ca2..5cf527a 100644
--- a/lib/view/pages/talk/components/chatBubbleStyles.dart
+++ b/lib/view/pages/talk/components/chatBubbleStyles.dart
@@ -51,4 +51,4 @@ class ChatBubbleStyles {
       alignment: Alignment.topRight,
     );
   }
-}
\ No newline at end of file
+}
diff --git a/lib/widget/list_view_util.dart b/lib/widget/list_view_util.dart
new file mode 100644
index 0000000..468ae95
--- /dev/null
+++ b/lib/widget/list_view_util.dart
@@ -0,0 +1,9 @@
+
+import 'package:flutter/material.dart';
+
+class ListViewUtil {
+  static ListView fromList<T>(List<T>? items, Widget Function(T item) map) => ListView.builder(
+      itemCount: items?.length ?? 0,
+      itemBuilder: (context, index) => items != null ? map(items[index]) : null,
+    );
+}
diff --git a/lib/widget/string_extensions.dart b/lib/widget/string_extensions.dart
new file mode 100644
index 0000000..21c3901
--- /dev/null
+++ b/lib/widget/string_extensions.dart
@@ -0,0 +1,3 @@
+extension StringExtensions on String {
+  String capitalize() => '${this[0].toUpperCase()}${substring(1).toLowerCase()}';
+}