using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using LehrerApp.Core.Interfaces; using LehrerApp.Core.Models; using System.Collections.ObjectModel; namespace LehrerApp.Desktop.ViewModels.Students; // ── Schülerliste ────────────────────────────────────────────────────────────── public partial class StudentListViewModel : ObservableObject { private readonly IStudentRepository _students; [ObservableProperty] private string _searchText = ""; [ObservableProperty] private bool _showInactive; [ObservableProperty] private StudentListItem? _selectedStudent; public ObservableCollection Students { get; } = []; public StudentListViewModel(IStudentRepository students) { _students = students; LoadStudents(); } partial void OnSearchTextChanged(string value) => LoadStudents(); partial void OnShowInactiveChanged(bool value) => LoadStudents(); private void LoadStudents() { Students.Clear(); var all = _students.GetAll(includeInactive: ShowInactive); var filtered = string.IsNullOrWhiteSpace(SearchText) ? all : all.Where(s => s.LastName.Contains(SearchText, StringComparison.OrdinalIgnoreCase) || s.FirstName.Contains(SearchText, StringComparison.OrdinalIgnoreCase)); foreach (var s in filtered) Students.Add(new StudentListItem(s)); } [RelayCommand] private void AddStudent() { // TODO: Neuer-Schüler-Dialog } [RelayCommand] private void Refresh() => LoadStudents(); } public class StudentListItem { public Guid Id { get; } public string FullName { get; } public string DateOfBirth { get; } public bool IsActive { get; } public StudentListItem(Student s) { Id = s.Id; FullName = s.FullName; DateOfBirth = s.DateOfBirth?.ToString("dd.MM.yyyy") ?? ""; IsActive = s.IsActive; } } // ── Schülerdetail ───────────────────────────────────────────────────────────── public partial class StudentDetailViewModel : ObservableObject { private readonly IStudentRepository _students; private readonly IEnrollmentRepository _enrollments; private readonly IGroupRepository _groups; private readonly IGradeRepository _grades; private readonly IDocumentationRepository _docs; [ObservableProperty] private Student? _student; [ObservableProperty] private string _studentTitle = ""; [ObservableProperty] private StudentTab _activeTab = StudentTab.Overview; [ObservableProperty] private bool _isEditing; // Bearbeitbare Felder [ObservableProperty] private string _editFirstName = ""; [ObservableProperty] private string _editLastName = ""; [ObservableProperty] private string _editNotes = ""; public ObservableCollection Enrollments { get; } = []; public ObservableCollection Grades { get; } = []; public ObservableCollection Documentation { get; } = []; public StudentDetailViewModel( IStudentRepository students, IEnrollmentRepository enrollments, IGroupRepository groups, IGradeRepository grades, IDocumentationRepository docs) { _students = students; _enrollments = enrollments; _groups = groups; _grades = grades; _docs = docs; } public void LoadStudent(Guid studentId) { Student = _students.GetById(studentId); if (Student is null) return; StudentTitle = Student.FullName; EditFirstName = Student.FirstName; EditLastName = Student.LastName; EditNotes = Student.Notes ?? ""; LoadEnrollments(); LoadDocs(); } [RelayCommand] private void SwitchTab(StudentTab tab) => ActiveTab = tab; [RelayCommand] private void StartEdit() => IsEditing = true; [RelayCommand] private void CancelEdit() { if (Student is null) return; EditFirstName = Student.FirstName; EditLastName = Student.LastName; EditNotes = Student.Notes ?? ""; IsEditing = false; } [RelayCommand] private void SaveEdit() { if (Student is null) return; Student.FirstName = EditFirstName; Student.LastName = EditLastName; Student.Notes = string.IsNullOrWhiteSpace(EditNotes) ? null : EditNotes; _students.Save(Student); StudentTitle = Student.FullName; IsEditing = false; } private void LoadEnrollments() { if (Student is null) return; Enrollments.Clear(); var enrollments = _enrollments.GetByStudent(Student.Id); var groupIds = enrollments.Select(e => e.GroupId).Distinct(); var groupMap = groupIds .Select(id => _groups.GetById(id)) .Where(g => g is not null) .ToDictionary(g => g!.Id); foreach (var e in enrollments.OrderByDescending(e => e.SchoolYear)) { if (!groupMap.TryGetValue(e.GroupId, out var group)) continue; Enrollments.Add(new EnrollmentEntry { SchoolYear = e.SchoolYear, GroupName = group.Name, Subject = group.Subject ?? "", }); } } private void LoadDocs() { if (Student is null) return; Documentation.Clear(); foreach (var doc in _docs.GetByStudent(Student.Id)) { Documentation.Add(new DocEntry { Date = doc.Date.ToString("dd.MM.yyyy"), Title = doc.Title, TypeLabel = doc.Type switch { DocumentationType.Conversation => "Gespräch", DocumentationType.Incident => "Vorkommnis", DocumentationType.SupportPlan => "Förderplan", DocumentationType.Absence => "Fehlzeit", _ => "", }, IsConfidential = doc.IsConfidential, }); } } } public enum StudentTab { Overview, Grades, Documentation } public class EnrollmentEntry { public string SchoolYear { get; set; } = ""; public string GroupName { get; set; } = ""; public string Subject { get; set; } = ""; } public class GradeEntry { public string Date { get; set; } = ""; public string Value { get; set; } = ""; public string Category { get; set; } = ""; public string GroupName { get; set; } = ""; } public class DocEntry { public string Date { get; set; } = ""; public string Title { get; set; } = ""; public string TypeLabel { get; set; } = ""; public bool IsConfidential { get; set; } }