using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using LehrerApp.Core.Interfaces; using LehrerApp.Core.Models; namespace LehrerApp.Desktop.ViewModels.Groups; /// /// Unterrichtsmodus (14.x): konsolidierte Ansicht für eine konkrete, heute stattfindende Stunde - /// Verlaufsplan und Sitzplan mit Schnellbewertung auf einem Bildschirm, statt zwischen den Tabs /// der Gruppe hin- und herzuspringen. Wird über TimetableViewModel.StartTeachingModeCommand aus /// der "Heute"-Tagesliste heraus gestartet. /// /// Bewusst keine eigene DI-Registrierung als Singleton/Transient: wie LessonViewerViewModel wird /// diese ViewModel direkt vom Code-Behind konstruiert, das dafür nötige SeatingPlanTabViewModel/ /// ParticipationTabViewModel aber weiterhin über DI aufgelöst (transient, siehe AppBootstrapper) /// und hier per Konstruktor entgegengenommen statt selbst aus App.Services zu ziehen - /// ViewModels greifen in diesem Code nicht selbst auf den Service-Container zu, das bleibt /// Aufgabe des Code-Behind. /// public class TeachingModeViewModel { public string GroupName { get; } public LessonViewerViewModel LessonInfo { get; } public SeatingPlanTabViewModel SeatingPlan { get; } /// Nutzer-Feedback: die Schnellbewertungs-Dialoge für Mitarbeit/Anwesenheit-Hausaufgabe /// gab es bislang nur über den Mitarbeit-Tab der Gruppe — im Unterrichtsmodus musste man dafür /// erst wieder raus. Hier dieselbe wie im Mitarbeit-Tab, /// aber auf die zu dieser Stunde gehörende Sitzung vorselektiert (siehe Konstruktor), damit die /// über OnQuickInput/OnStatusQuickInput geöffneten Dialoge (Wiring in /// TeachingModeWindow.axaml.cs, gleiches Muster wie ParticipationTabView.axaml.cs) direkt auf /// der richtigen Sitzung starten. public ParticipationTabViewModel Participation { get; } public TeachingModeHomeworkViewModel Homework { get; } public TeachingModeViewModel(Lesson lesson, LearningGroup group, IAlternativeLessonPathRepository alternativePaths, ILessonRepository lessons, SeatingPlanTabViewModel seatingPlan, ParticipationTabViewModel participation) { GroupName = group.Name; LessonInfo = new LessonViewerViewModel(lesson, alternativePaths); SeatingPlan = seatingPlan; SeatingPlan.Initialize(group.Id, !group.IsActive); SeatingPlan.SelectOrCreateSessionForLesson(lesson); Participation = participation; Participation.Initialize(group.Id, group.SchoolYear, !group.IsActive); if (SeatingPlan.SelectedSession is { } linkedSession) Participation.SelectedSession = Participation.Sessions.FirstOrDefault(s => s.Id == linkedSession.Id); // 4.5.4: dieselbe "letzte Stunde vor dieser"-Suche wie das Stundenplan-Badge // "Hausaufgabe kontrollieren" (TimetableViewModel.HasUnhandledHomework) - 120 Tage // Lookback deckt auch längere Ferienpausen ab, ohne unbegrenzt weit zurückzuscannen. var previousLesson = lessons.GetByGroupAndRange(group.Id, lesson.Date.AddDays(-120), lesson.Date.AddDays(-1)) .OrderByDescending(l => l.Date).ThenByDescending(l => l.LessonNumber ?? 0) .FirstOrDefault(); Homework = new TeachingModeHomeworkViewModel(lesson, previousLesson, lessons); } } /// /// Nutzer-Feedback: im Unterrichtsmodus sollte man die Hausaufgabe aus der letzten Stunde als /// kontrolliert abhaken und die neue Hausaufgabe eintragen/ändern können, ohne dafür den vollen /// -Editor zu öffnen (der zusätzlich Phasen/Reflexion usw. zeigt) /// - manchmal ergibt sich die Hausaufgabe erst während der Stunde. Bewusst eine eigene, kleine /// statt Felder direkt auf , da /// diese Klasse (wie ) selbst keine Bindable-Basisklasse hat. /// public partial class TeachingModeHomeworkViewModel : ObservableObject { private readonly ILessonRepository _lessons; private readonly Lesson _lesson; private readonly Lesson? _previousLesson; public bool HasPreviousHomework => _previousLesson is not null && !string.IsNullOrWhiteSpace(_previousLesson.Homework); public string PreviousHomeworkText => _previousLesson?.Homework ?? ""; public string PreviousLessonLabel => _previousLesson is null ? "" : $"{_previousLesson.Date:dd.MM.yyyy}" + (string.IsNullOrWhiteSpace(_previousLesson.Topic) ? "" : $" · {_previousLesson.Topic}"); [ObservableProperty] private bool _previousHomeworkChecked; [ObservableProperty] private string _currentHomework; [ObservableProperty] private string _saveStatus = ""; public TeachingModeHomeworkViewModel(Lesson lesson, Lesson? previousLesson, ILessonRepository lessons) { _lesson = lesson; _previousLesson = previousLesson; _lessons = lessons; _previousHomeworkChecked = previousLesson?.HomeworkChecked ?? false; _currentHomework = lesson.Homework ?? ""; } /// Sofort beim Umschalten gespeichert (kein separater Speichern-Klick nötig) - dieselbe /// Checkbox-Semantik wie im LessonDialog (4.5.4): "kontrolliert" und "nicht kontrollieren" /// schließen sich aus. partial void OnPreviousHomeworkCheckedChanged(bool value) { if (_previousLesson is null) return; _previousLesson.HomeworkChecked = value; if (value) _previousLesson.HomeworkCheckDismissed = false; _lessons.Save(_previousLesson); } [RelayCommand] private void SaveCurrentHomework() { _lesson.Homework = CurrentHomework; _lessons.Save(_lesson); SaveStatus = "Gespeichert."; } }