added guardian login with views for their assigned childs

This commit is contained in:
2026-09-20 11:11:58 +02:00
parent e4e2b1a4fb
commit 67c935c05b
117 changed files with 4784 additions and 1514 deletions
@@ -0,0 +1,110 @@
import '../../../../../api/marianumconnect/queries/timetable_get_element_week/timetable_element_type.dart';
/// Whose timetable a [TimetableBloc] shows. The render pipeline is identical
/// for every subject; only the week endpoint, persistence and the
/// user-private extras (custom events) differ.
sealed class TimetableSubject {
const TimetableSubject();
/// Suffix of the hydrated storage slot. Must be unique per subject so
/// subjects never overwrite each other's cached weeks.
String get storageId;
/// Whether the bloc keeps its state across app restarts.
bool get persistent;
/// Custom events are user-private and only exist for the own plan.
bool get supportsCustomEvents;
}
/// The signed-in user's own plan (`timetable/me`).
final class OwnTimetable extends TimetableSubject {
const OwnTimetable();
// Empty on purpose: keeps the pre-existing storage slot "TimetableBloc", so
// updating the app does not drop the cached weeks.
@override
String get storageId => '';
@override
bool get persistent => true;
@override
bool get supportsCustomEvents => true;
@override
bool operator ==(Object other) => other is OwnTimetable;
@override
int get hashCode => (OwnTimetable).hashCode;
}
/// A foreign element picked by the user (teacher, room, class, student).
final class ElementTimetable extends TimetableSubject {
final TimetableElementRef element;
const ElementTimetable(this.element);
@override
String get storageId => 'element-${element.type.name}-${element.id}';
@override
bool get persistent => false;
@override
bool get supportsCustomEvents => false;
@override
bool operator ==(Object other) =>
other is ElementTimetable &&
other.element.type == element.type &&
other.element.id == element.id;
@override
int get hashCode => Object.hash(element.type, element.id);
}
/// A guardian's child (`timetable/child/{id}`). Kept across restarts per
/// child, so switching between siblings shows the cached plan immediately.
final class ChildTimetable extends TimetableSubject {
final String childId;
const ChildTimetable(this.childId);
@override
String get storageId => 'child-$childId';
@override
bool get persistent => true;
@override
bool get supportsCustomEvents => false;
@override
bool operator ==(Object other) =>
other is ChildTimetable && other.childId == childId;
@override
int get hashCode => childId.hashCode;
}
/// No plan to show: signed out, or a guardian without (known) children. The
/// bloc loads nothing; the view explains why.
final class NoTimetable extends TimetableSubject {
const NoTimetable();
@override
String get storageId => 'none';
@override
bool get persistent => false;
@override
bool get supportsCustomEvents => false;
@override
bool operator ==(Object other) => other is NoTimetable;
@override
int get hashCode => (NoTimetable).hashCode;
}