224 lines
6.9 KiB
C#
224 lines
6.9 KiB
C#
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<StudentListItem> 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<EnrollmentEntry> Enrollments { get; } = [];
|
|
public ObservableCollection<GradeEntry> Grades { get; } = [];
|
|
public ObservableCollection<DocEntry> 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; }
|
|
}
|