Initial
This commit is contained in:
223
LehrerApp.Desktop/ViewModels/Students/StudentViewModels.cs
Normal file
223
LehrerApp.Desktop/ViewModels/Students/StudentViewModels.cs
Normal file
@@ -0,0 +1,223 @@
|
||||
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; }
|
||||
}
|
||||
Reference in New Issue
Block a user