Klassenlehrer-Tab: Theme-Ressourcen statt Hex-Farben, gestapelter Trend, Fehlquote seit Schuljahresbeginn

Semantische Brushes (Light/Dark) lösen die fest codierten Dark-Hex-Werte ab, die
im hellen Theme unbenutzbar waren. Trend-Chart zeigt jetzt einen echten
gestapelten Balken über die letzten 7 Schultage statt drei unabhängig
skalierten über Kalendertage; neue Fehlquote je Schüler*in seit
Schuljahresbeginn ergänzt den Heute-Snapshot.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-27 12:47:13 +02:00
co-authored by Claude Sonnet 5
parent cf8de08501
commit 9d375caf14
9 changed files with 510 additions and 119 deletions
+49
View File
@@ -1397,6 +1397,35 @@ eigenen Unterricht abfragt und deshalb mit den regulären Lehrkraft-Rechten funk
jetzt `UntisStudentRosterCacheEntry` statt des vollen `UntisStudentDto` entgegen (nur
`ExternKey`/`DisplayName` wurden je gebraucht).
- [x] **"Klassenlehrer"-Feature — Trend & Fehlquote (August 2026):** Zwei Nutzer-Feedback-Punkte
auf einmal umgesetzt, weil sie sich denselben Datenabruf teilen.
- **Trend als gestapelter Balken statt drei unabhängig skalierten:** `ClassTeacherTrendDay`
lieferte bisher `AlertBarWidth`/`UnexcusedBarWidth`/`LateBarWidth`, jede für sich auf dasselbe
Maximum normiert — das suggerierte drei unabhängige Größen, obwohl Unentschuldigt und
Verspätet Teilmengen von Alerts sind. Jetzt drei überschneidungsfreie Segmente (Unentschuldigt
hat Vorrang vor Verspätet, gleiche Priorisierung wie `ClassTeacherRosterRow.AttentionRank`),
deren Breiten sich exakt zu `TotalBarWidth` summieren; in XAML als `Border ClipToBounds="True"`
mit `CornerRadius` um eine horizontale `StackPanel` aus drei quadratischen Segmenten gerendert,
damit nur die äußeren Kanten abgerundet sind.
- **Trend über die letzten 7 Schultage statt Kalendertage:** an zwei von sieben Tagen war der
Balken bislang systematisch leer, weil `start.AddDays(offset)` Wochenenden mitzählte. Neues
`ClassTeacherOverviewViewModel.LastSchoolDays` überspringt Samstag/Sonntag — bewusst ohne
Ferienkalender, die App kennt keine Schulferien (gilt auch für die Fehlquote unten).
- **Kumulierte Fehlquote seit Schuljahresbeginn je Schüler*in:** der bisherige Heute-Snapshot
sagt für Zeugnis/Attestpflicht wenig aus. `ClassTeacherRosterRow` bekommt
`YearAbsenceDayCount`/`YearUnexcusedDayCount`/`YearAbsenceRatePercent`
(`SchoolDaysElapsed` als Nenner, wieder nur Werktage ohne Ferienkalender) und zeigt sie als
dezente zweite Zeile unter dem Tagesstatus, Details im Tooltip. Dafür holt `Load()` die
Fehlzeiten jetzt für `[Schuljahresbeginn, heute]` statt nur der letzten 7 Tage — teuer ist das
nur beim ersten Öffnen pro Schuljahr, `UntisReportCacheService` cached den "kalten" Bereich
danach dauerhaft (siehe Cache-Eintrag oben). Klassenbuch-Abruf bleibt bewusst bei 7 Tagen
(für "Eintrag diese Woche"/`RecentClassRegisterCount` reicht das, ein Jahr an fremden
Klassenbucheinträgen zu cachen wäre unnötiges Datenvolumen).
Neue `SchoolYearService`-Abhängigkeit in `ClassTeacherOverviewViewModel` (Konstruktor-Injection,
Service war bereits als Singleton registriert).
### 4.4 Wochen-/Tagesansicht
### 4.4 Wochen-/Tagesansicht
- [x] **4.4.1** Kalenderansicht über alle Gruppen: Woche und Tag — siehe Nachtrag zu 4.3
("Heute"-Tab: Tagesliste unten angedockt, gruppenübergreifendes Wochenraster darüber, inkl.
@@ -3052,6 +3081,26 @@ von 4.2.2) der Tab "Kürzel-Katalog" für die Von/Nach-Kürzel des Stundenverlau
ca. 23 XAML-Dateien mit fest codierten Hex-Farben statt Theme-Ressourcen — die
Umschaltung selbst funktioniert, aber einzelne Stellen dürften im Dunkelmodus optisch
nicht passen. Eigene, größere Aufgabe. Schriftgröße nicht umgesetzt.
**Nachtrag (August 2026) — Theme-Ressourcen, erster Schritt:** Neue
[SemanticBrushes.axaml](LehrerApp.Desktop/Styles/SemanticBrushes.axaml) definiert über
`ResourceDictionary.ThemeDictionaries` (Light/Dark) semantische Pinsel für Flächen
(`AppCardBackgroundBrush`, `AppListRowBackgroundBrush`, `AppChipBackgroundBrush`, …),
Akzent (`AppAccentTextBrush`, `AppFilterActive*Brush`, …) und Status
(`AppStatusOk/Info/Warning/DangerBrush`); eingebunden in `Application.Resources` von
`App.axaml`. Der Klassenlehrer-Bereich ist die erste vollständig umgestellte Ansicht — er
war mit ~36 Hex-Werten der stärkste Fall und im hellen Theme unbrauchbar (dunkle
Kartenflächen auf hellem Grund). Zwei Punkte, die beim Umstellen weiterer Ansichten
genauso gelten:
- Farben müssen per **`DynamicResource`** geholt werden — `StaticResource` löst einmalig
auf und bliebe beim Laufzeit-Wechsel stehen.
- Statusfarben dürfen **nicht als Hex-String aus dem ViewModel** kommen (bisheriges Muster
`StatusColor => "#FF5A67"`), aus demselben Grund. Stattdessen liefert das ViewModel eine
semantische Stufe (`ClassTeacherStatusKind`) plus `Is{Kind}Status`-Flags, und ein
Style-Selektor (`TextBlock.status.danger`, `Border.statusFill.warning`) setzt den Pinsel
— die Basisfarbe muss dabei ebenfalls aus einem Selektor kommen, sonst überstimmt sie das
lokale Attribut (siehe CLAUDE.md, Avalonia-XAML-Fallstricke).
Offen bleiben die übrigen Ansichten (Dashboard, Planung, Mitarbeit, Gruppen …).
- [ ] **12.5** Speicherort der Datenbank anzeigen und ändern.
- [ ] **12.6** Backup-Verwaltung (siehe 13.3) in den Einstellungen zugänglich machen.