feat: Pädagogische Klassen-Aufgaben, Prioritäten/Checklisten, Dashboard-Schnellzugriffe

Neue Aufgabenart über bestehende Felder (WorkTask.Kind=Reminder + GroupId) statt Vererbung,
mit Priorität (TaskPriority) und optionaler Abhak-Liste (ChecklistItems, wahlweise Kurs-
Roster oder Freitext). Kurs-Dashboard zeigt jetzt eine "Anstehende Aufgaben"-Karte samt
direktem Anlege-Button; derselbe Anlege-Einstieg wurde auch ins Hauptdashboard und (als
Schnellüberblick samt fehlender Übersicht/Mitarbeit-Buttons) in die Gruppenliste gezogen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 22:24:38 +02:00
co-authored by Claude Sonnet 5
parent e7c3fdd4ec
commit e65a729f97
25 changed files with 878 additions and 39 deletions
@@ -5,11 +5,13 @@ using LehrerApp.Core.Importing;
using LehrerApp.Core.Interfaces;
using LehrerApp.Core.Models;
using LehrerApp.Core.Services;
using LehrerApp.Desktop.ViewModels;
using LehrerApp.Desktop.ViewModels.Groups;
using LehrerApp.Desktop.ViewModels.Students;
using LehrerApp.Desktop.Services;
using LehrerApp.Desktop.Views.Shared;
using LehrerApp.Desktop.Views.Students;
using LehrerApp.Desktop.Views.Workload;
using Microsoft.Extensions.DependencyInjection;
namespace LehrerApp.Desktop.Views.Groups;
@@ -34,9 +36,19 @@ public partial class GroupDetailView : UserControl
vm.OnGradeExam = ShowGradeExamDialog;
vm.OnEvaluateExam = ShowEvaluateExamDialog;
vm.OnConfirmReactivate = ShowReactivateConfirmDialog;
vm.OverviewTab.OnNavigateToWorkload = () =>
App.Services.GetRequiredService<MainWindowViewModel>().NavigateToWorkload();
vm.OverviewTab.OnAddGroupTask = ShowAddGroupTaskDialog;
}
}
private async Task<WorkTask?> ShowAddGroupTaskDialog(Guid groupId)
{
var owner = TopLevel.GetTopLevel(this) as Window;
if (owner is null) return null;
return await WorkTaskDialogHelper.ShowDialog(owner, preselectedGroupId: groupId);
}
private async Task<bool> ShowReactivateConfirmDialog()
{
var dialog = new ConfirmDialog
@@ -5,6 +5,13 @@
x:Class="LehrerApp.Desktop.Views.Groups.GroupListView"
x:DataType="vm:GroupListViewModel">
<UserControl.Styles>
<Style Selector="TextBlock.overdue">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontWeight" Value="SemiBold"/>
</Style>
</UserControl.Styles>
<Grid RowDefinitions="Auto,*">
<!-- Kopfzeile mit Schuljahr-Wähler und Neu-Button -->
@@ -108,10 +115,48 @@
<Separator/>
<!-- Schnellüberblick (Nutzer-Feedback) -->
<StackPanel Spacing="8" IsVisible="{Binding QuickHasAnything}">
<TextBlock Text="SCHNELLÜBERBLICK" FontSize="10" FontWeight="Bold" Opacity="0.4"/>
<StackPanel Spacing="1" IsVisible="{Binding QuickHasNextLesson}">
<TextBlock Text="Nächste Stunde" FontSize="11" Opacity="0.55"/>
<TextBlock Text="{Binding QuickNextLessonLabel}" FontSize="13" TextWrapping="Wrap"/>
</StackPanel>
<StackPanel Spacing="1" IsVisible="{Binding QuickHasNextExam}">
<TextBlock Text="Nächste Klausur" FontSize="11" Opacity="0.55"/>
<TextBlock Text="{Binding QuickNextExamLabel}" FontSize="13" TextWrapping="Wrap"/>
</StackPanel>
<StackPanel Spacing="4" IsVisible="{Binding QuickHasTasks}">
<TextBlock Text="Wichtige Aufgaben" FontSize="11" Opacity="0.55"/>
<ItemsControl ItemsSource="{Binding QuickTasks}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:GroupTaskItem">
<Grid ColumnDefinitions="4,Auto,*,Auto" Margin="0,2">
<Border Grid.Column="0" Background="{Binding PriorityColorHex}" CornerRadius="2"
Margin="0,0,6,0" IsVisible="{Binding IsHighPriority}"/>
<TextBlock Grid.Column="1" Text="🔔" FontSize="11" Margin="0,0,4,0"
IsVisible="{Binding IsReminder}" VerticalAlignment="Center"/>
<TextBlock Grid.Column="2" Text="{Binding Title}" FontSize="12"
TextTrimming="CharacterEllipsis" VerticalAlignment="Center"/>
<TextBlock Grid.Column="3" Text="{Binding DueDateDisplay}" FontSize="11"
VerticalAlignment="Center" Classes.overdue="{Binding IsOverdue}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</StackPanel>
<Separator IsVisible="{Binding QuickHasAnything}"/>
<!-- Bereichs-Navigation -->
<TextBlock Text="BEREICHE" FontSize="10" FontWeight="Bold"
Opacity="0.4" Margin="0,0,0,2"/>
<StackPanel Spacing="6">
<Button Content="📊 Übersicht"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Left"
Padding="12,9"
Command="{Binding NavigateToSectionCommand}"
CommandParameter="0"/>
<Button Content="👤 Schülerliste"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Left"
Padding="12,9"
@@ -122,6 +167,11 @@
Padding="12,9"
Command="{Binding NavigateToSectionCommand}"
CommandParameter="2"/>
<Button Content="✋ Mitarbeit"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Left"
Padding="12,9"
Command="{Binding NavigateToSectionCommand}"
CommandParameter="3"/>
<Button Content="📝 Klausuren"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Left"
Padding="12,9"
@@ -24,6 +24,10 @@
<Setter Property="Foreground" Value="#D97706"/>
<Setter Property="FontWeight" Value="SemiBold"/>
</Style>
<Style Selector="TextBlock.overdue">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontWeight" Value="SemiBold"/>
</Style>
<Style Selector="Button.cardLink">
<Setter Property="FontSize" Value="11"/>
<Setter Property="Padding" Value="0"/>
@@ -165,6 +169,40 @@
<Button Content="Zur Mitarbeit " Classes="cardLink" Command="{Binding NavigateToParticipationCommand}"/>
</StackPanel>
</Border>
<!-- Anstehende Aufgaben für diese Klasse (pädagogische Erinnerungen/Aufgaben, Nutzer-
Feedback: "dürfen gerne auch im passenden Kurs-Dashboard stehen") — anders als die
übrigen Karten dieser Reihe bewusst immer sichtbar (statt Has…-gated), da sie zugleich
der Anlege-Einstieg für die erste Aufgabe dieser Gruppe ist. -->
<Border Classes="card" MinWidth="340" MaxWidth="420">
<StackPanel>
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Text="ANSTEHENDE AUFGABEN" Classes="cardTitle"/>
<Button Grid.Column="1" Content="" FontSize="12" Padding="8,2" Margin="0,-4,0,0"
ToolTip.Tip="Aufgabe/Erinnerung für diese Gruppe anlegen"
Command="{Binding AddGroupTaskCommand}"/>
</Grid>
<ItemsControl ItemsSource="{Binding GroupTasks}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:GroupTaskItem">
<Grid ColumnDefinitions="4,Auto,*,Auto" Margin="0,4">
<Border Grid.Column="0" Background="{Binding PriorityColorHex}" CornerRadius="2"
Margin="0,0,6,0" IsVisible="{Binding IsHighPriority}"/>
<TextBlock Grid.Column="1" Text="🔔" FontSize="12" Margin="0,0,4,0"
IsVisible="{Binding IsReminder}" VerticalAlignment="Center"/>
<TextBlock Grid.Column="2" Text="{Binding Title}" FontSize="13"
TextTrimming="CharacterEllipsis" VerticalAlignment="Center"/>
<TextBlock Grid.Column="3" Text="{Binding DueDateDisplay}" FontSize="12"
VerticalAlignment="Center" Classes.overdue="{Binding IsOverdue}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock Text="Keine anstehenden Aufgaben für diese Gruppe." Classes="emptyhint"
IsVisible="{Binding !HasGroupTasks}"/>
<Button Content="Zu den Aufgaben " Classes="cardLink" Command="{Binding NavigateToWorkloadCommand}"/>
</StackPanel>
</Border>
</WrapPanel>
</StackPanel>
</ScrollViewer>