Files
LehrerApp/LehrerApp.Desktop/ViewModels/MainWindowViewModel.cs
T
adminandClaude Sonnet 5 f8058b537b feat: Geräte-Pairing-UI + Einstellungen-Neustrukturierung
- Sync-Settings-Tab: neuer Bereich "Gerät koppeln" (10.3.1), nutzt den
  bereits vorhandenen, bisher nirgends verdrahteten SnapshotService.
  Ein Gerät erzeugt per CreatePairingCode einen verschlüsselten
  DB-Snapshot + Einmal-Code, das zweite Gerät übernimmt per
  RedeemPairingCode Datenbank und Sync-Schlüssel. Bestätigungsdialog
  vor dem Einlösen, da die lokale Datenbank dabei vollständig ersetzt
  wird (alter Stand wird automatisch als Backup gesichert).
- Einstellungen: TabPlacement von Top auf Left umgestellt (vertikale
  Liste statt langem horizontalem Balken) und die 13 Tabs in drei
  logische Gruppen sortiert (Fachliches / Zeitplanung / System).
- Neuer SettingsTab-Enum ersetzt rohe int-Tab-Indizes bei
  MainWindowViewModel.NavigateToSettings/
  TimetableViewModel.OnNavigateToSettings. Dabei einen bestehenden Bug
  gefunden und mitbehoben: das Zahnrad im Stundenplan öffnete über den
  hartcodierten Index 7 tatsächlich "Datenschutz" statt des laut
  Kommentar/Tooltip beabsichtigten "Ferien & Feiertage".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 01:09:25 +02:00

146 lines
5.3 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using LehrerApp.Core.Services;
using LehrerApp.Desktop.Services;
using LehrerApp.Desktop.ViewModels.Groups;
using LehrerApp.Desktop.ViewModels.Planning;
using LehrerApp.Desktop.ViewModels.Settings;
using LehrerApp.Desktop.ViewModels.Students;
using LehrerApp.Desktop.ViewModels.Workload;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.ObjectModel;
namespace LehrerApp.Desktop.ViewModels;
public partial class MainWindowViewModel : ObservableObject
{
private readonly IServiceProvider _services;
[ObservableProperty] private ObservableObject? _currentPage;
[ObservableProperty] private NavItem _activeNavItem = NavItem.Dashboard;
[ObservableProperty] private string _currentSchoolYear = "";
public SyncStatusViewModel SyncStatus { get; }
public ObservableCollection<ToastItem> Toasts { get; }
public AppLockViewModel AppLock { get; }
public bool IsDashboardActive => ActiveNavItem == NavItem.Dashboard;
public bool IsGroupsActive => ActiveNavItem == NavItem.Groups;
public bool IsStudentsActive => ActiveNavItem == NavItem.Students;
public bool IsExamsActive => ActiveNavItem == NavItem.Exams;
public bool IsPlannerActive => ActiveNavItem == NavItem.Planner;
public bool IsWorkloadActive => ActiveNavItem == NavItem.Workload;
public bool IsSettingsActive => ActiveNavItem == NavItem.Settings;
public MainWindowViewModel(IServiceProvider services,
DashboardViewModel dashboard, SchoolYearService sy,
SyncStatusViewModel syncStatus, NotificationService notifications, AppLockViewModel appLock)
{
_services = services;
SyncStatus = syncStatus;
Toasts = notifications.Toasts;
AppLock = appLock;
CurrentSchoolYear = sy.CurrentSchoolYear();
CurrentPage = dashboard;
AppLock.ApplyConfig();
}
partial void OnActiveNavItemChanged(NavItem value)
{
OnPropertyChanged(nameof(IsDashboardActive));
OnPropertyChanged(nameof(IsGroupsActive));
OnPropertyChanged(nameof(IsStudentsActive));
OnPropertyChanged(nameof(IsExamsActive));
OnPropertyChanged(nameof(IsPlannerActive));
OnPropertyChanged(nameof(IsWorkloadActive));
OnPropertyChanged(nameof(IsSettingsActive));
}
[RelayCommand]
private void NavigateTo(NavItem item)
{
ActiveNavItem = item;
CurrentPage = item switch
{
NavItem.Dashboard => GetDashboard(),
NavItem.Groups => _services.GetRequiredService<GroupListViewModel>(),
NavItem.Students => GetStudents(),
NavItem.Exams => new PlaceholderViewModel { Title = "Klausuren", Icon = "📝" },
NavItem.Planner => GetTimetable(),
NavItem.Workload => GetWorkload(),
NavItem.Settings => _services.GetRequiredService<SettingsViewModel>(),
_ => CurrentPage,
};
}
private DashboardViewModel GetDashboard()
{
var dashboard = _services.GetRequiredService<DashboardViewModel>();
dashboard.RefreshCommand.Execute(null);
return dashboard;
}
private StudentListViewModel GetStudents()
{
var students = _services.GetRequiredService<StudentListViewModel>();
students.SelectedStudent = null;
students.LoadStudents();
return students;
}
private TimetableViewModel GetTimetable()
{
var timetable = _services.GetRequiredService<TimetableViewModel>();
timetable.WeekOffset = 0;
timetable.Load();
timetable.ActiveTabIndex = 0;
return timetable;
}
private WorkloadViewModel GetWorkload()
{
var workload = _services.GetRequiredService<WorkloadViewModel>();
workload.Tasks.Load();
workload.TimeTracking.Load();
workload.Evaluation.Load();
workload.ActiveTabIndex = 0;
return workload;
}
public void NavigateToGroupDetail(Guid groupId, int initialTab = 0)
{
ActiveNavItem = NavItem.Groups;
var vm = _services.GetRequiredService<GroupDetailViewModel>();
vm.ActiveTabIndex = initialTab;
CurrentPage = vm; // View bindet zuerst → Callbacks werden registriert
vm.LoadGroup(groupId); // dann Daten laden
}
public void NavigateToSettings(SettingsTab initialTab = SettingsTab.Subjects)
{
ActiveNavItem = NavItem.Settings;
var vm = _services.GetRequiredService<SettingsViewModel>();
vm.ActiveTabIndex = (int)initialTab;
CurrentPage = vm;
}
public void NavigateToStudent(Guid studentId)
{
ActiveNavItem = NavItem.Students;
var vm = _services.GetRequiredService<StudentDetailViewModel>();
vm.OnReturnToStudentList = NavigateToStudents;
vm.LoadStudent(studentId);
CurrentPage = vm;
}
public void NavigateToStudents() => NavigateTo(NavItem.Students);
}
public enum NavItem { Dashboard, Groups, Students, Exams, Planner, Workload, Settings }
public partial class PlaceholderViewModel : ObservableObject
{
[ObservableProperty] private string _title = "";
[ObservableProperty] private string _icon = "";
}