Files
LehrerApp/LehrerApp.Desktop/Views/Groups/SeatingPlanTabView.axaml
adminandClaude Sonnet 5 1215d4ac22
CI / build-and-test (push) Canceled after 0s
Tagesflagge im Sitzplan, Leistungsüberblick mit Zielnoten-Rechner
- Mitarbeit: Tagesflagge (👑 Spitzentag / 😴 Schlaftag /  Schlechter Tag)
  je Schüler und Sitzung. Primär im Sitzplatz-Dialog (⇧1/2/3, ⇧X) mit
  Badge auf der Sitzplatz-Kachel; Fallback in der Schnelleingabe für
  Lerngruppen ohne Sitzplan.
- Noten: neuer Dialog "Überblick" in der Notenübersicht zeigt Klausuren,
  Mitarbeit- und sonstige Noten eines Schülers samt berechneter
  Zeugnisnote. Zielnoten-Rechner (ReportGradeTargetCalculator) beantwortet
  "was brauche ich noch für Note X", ein Was-wäre-wenn-Rechner simuliert
  eine zusätzliche Klausurnote. Bewerter-/Schülermodus per Umschalter im
  selben Fenster — Bewertermodus zeigt zusätzlich Kursdurchschnitt je
  Klausur und erlaubt das Bearbeiten von Mitarbeit-/Sonstige-Noten.
  Klausurverlauf als Balken-Sparkline wie die bestehende Notenentwicklung.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 11:43:47 +02:00

244 lines
15 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.Groups"
xmlns:groups="clr-namespace:LehrerApp.Desktop.Views.Groups"
x:Class="LehrerApp.Desktop.Views.Groups.SeatingPlanTabView"
x:DataType="vm:SeatingPlanTabViewModel">
<UserControl.Styles>
<Style Selector="Border.seat">
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundAltHighBrush}"/>
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlForegroundBaseLowBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
</Style>
<Style Selector="Border.seat.occupied">
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColor}"/>
</Style>
<Style Selector="Border.seat.droptarget">
<Setter Property="Background" Value="{DynamicResource SystemAccentColorLight2}"/>
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColor}"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
<Style Selector="Border.seat.hidden">
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlForegroundBaseLowBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Background" Value="Transparent"/>
</Style>
</UserControl.Styles>
<Grid ColumnDefinitions="260,*">
<Border Grid.Column="0" BorderBrush="{DynamicResource SystemControlForegroundBaseLowBrush}"
BorderThickness="0,0,1,0" Padding="16">
<Grid RowDefinitions="Auto,*,Auto">
<StackPanel Grid.Row="0" Spacing="4" Margin="0,0,0,12">
<TextBlock Text="Sitzpläne" FontSize="18" FontWeight="SemiBold"/>
<TextBlock Text="Mehrere Pläne, z. B. für verschiedene Räume" FontSize="12"
Opacity="0.6" TextWrapping="Wrap"/>
</StackPanel>
<ListBox Grid.Row="1" ItemsSource="{Binding Plans}" SelectedItem="{Binding SelectedPlan}">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="vm:SeatingPlanSummary">
<StackPanel Margin="4,6" Spacing="2">
<TextBlock Text="{Binding Name}" FontWeight="SemiBold"/>
<TextBlock Text="{Binding RoomDisplay}" FontSize="12" Opacity="0.6"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Grid.Row="2" Spacing="8" Margin="0,12,0,0" IsVisible="{Binding IsEditMode}">
<Button Content=" Sitzplan" Command="{Binding AddPlanCommand}" HorizontalAlignment="Stretch"/>
<Grid ColumnDefinitions="*,8,*" IsVisible="{Binding HasSelectedPlan}">
<Button Grid.Column="0" Content="Bearbeiten" Command="{Binding EditPlanCommand}"
HorizontalAlignment="Stretch"/>
<Button Grid.Column="2" Content="Löschen" Command="{Binding DeletePlanCommand}"
HorizontalAlignment="Stretch"/>
</Grid>
<Button Content="🎲 Plätze für Klausur mischen" Command="{Binding ShuffleSeatsCommand}"
HorizontalAlignment="Stretch" IsVisible="{Binding HasSelectedPlan}"
ToolTip.Tip="Legt einen neuen, unabhängigen Sitzplan mit demselben Raster an, in dem die belegten Plätze zufällig neu vertauscht sind. Der ursprüngliche Plan bleibt unverändert erhalten."/>
</StackPanel>
</Grid>
</Border>
<Grid Grid.Column="1">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="10"
IsVisible="{Binding HasPlans, Converter={x:Static BoolConverters.Not}}">
<TextBlock Text="Noch kein Sitzplan" FontSize="20" FontWeight="SemiBold"
HorizontalAlignment="Center"/>
<TextBlock Text="Lege einen Plan an und ordne die Schüler den Plätzen zu."
Opacity="0.6" TextAlignment="Center"/>
<Button Content="Ersten Sitzplan anlegen" Command="{Binding AddPlanCommand}"
HorizontalAlignment="Center"/>
</StackPanel>
<Grid RowDefinitions="Auto,*" ColumnDefinitions="*,Auto" IsVisible="{Binding HasSelectedPlan}" Margin="24">
<Grid Grid.Row="0" Grid.ColumnSpan="2" ColumnDefinitions="*,Auto" Margin="0,0,0,18">
<StackPanel Spacing="3">
<TextBlock Text="{Binding PlanTitle}" FontSize="22" FontWeight="SemiBold"/>
<TextBlock Text="{Binding PlanSubtitle}" Opacity="0.65"/>
<StackPanel Orientation="Horizontal" Spacing="8" Margin="0,6,0,0"
IsVisible="{Binding IsEditMode, Converter={x:Static BoolConverters.Not}}">
<TextBlock Text="Unterricht:" VerticalAlignment="Center" FontSize="12" Opacity="0.65"/>
<ComboBox ItemsSource="{Binding TodaySessions}" SelectedItem="{Binding SelectedSession}"
DisplayMemberBinding="{Binding DisplayName}" MinWidth="210"/>
</StackPanel>
</StackPanel>
<StackPanel Grid.Column="1" VerticalAlignment="Bottom" Spacing="4">
<StackPanel Orientation="Horizontal" Spacing="10" HorizontalAlignment="Right">
<Button Content="Als PDF" Click="OnExportPdfClick" VerticalAlignment="Center"/>
<ToggleSwitch Content="Bearbeitungsmodus" IsChecked="{Binding IsEditMode}"
IsVisible="{Binding IsEditable}"/>
</StackPanel>
<TextBlock Text="{Binding AssignmentSummary}" HorizontalAlignment="Right" FontSize="12" Opacity="0.6"/>
<TextBlock Text="Ziehen: Platz ändern · Klicken: bewerten" HorizontalAlignment="Right"
FontSize="11" Opacity="0.5" IsVisible="{Binding IsEditMode}"/>
<TextBlock Text="Klicken: bewerten" HorizontalAlignment="Right"
FontSize="11" Opacity="0.5" IsVisible="{Binding IsEditMode, Converter={x:Static BoolConverters.Not}}"/>
</StackPanel>
</Grid>
<ScrollViewer x:Name="RoomScrollViewer" Grid.Row="1" Grid.Column="0"
Margin="0,0,16,0"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
DragDrop.AllowDrop="True"
DragDrop.DragOver="OnRoomDragOver"
DragDrop.DragLeave="OnRoomDragLeave">
<StackPanel Spacing="14" HorizontalAlignment="Center">
<Border Background="{DynamicResource SystemControlBackgroundChromeMediumLowBrush}"
CornerRadius="6" Padding="36,8" HorizontalAlignment="Center"
IsVisible="{Binding IsBoardAtTop}">
<TextBlock Text="Tafel / Vorderseite" FontWeight="SemiBold" Opacity="0.75"/>
</Border>
<ItemsControl ItemsSource="{Binding Seats}" HorizontalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<groups:SeatingPlanPanel Columns="{Binding PlanColumns}"
ColumnGapWidths="{Binding ColumnGapWidths}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:SeatCellViewModel">
<Border Classes="seat" Classes.occupied="{Binding IsOccupied}"
Classes.droptarget="{Binding IsDropTarget}"
Classes.hidden="{Binding IsHidden}"
IsVisible="{Binding ShowSeat}"
Width="190" MinHeight="76" Margin="5" Padding="10"
CornerRadius="7"
DragDrop.AllowDrop="True"
DragDrop.DragEnter="OnSeatDragEnter"
DragDrop.DragLeave="OnSeatDragLeave"
DragDrop.DragOver="OnSeatDragOver"
DragDrop.Drop="OnSeatDrop"
PointerPressed="OnDragSourcePressed"
PointerMoved="OnDragSourceMoved"
PointerReleased="OnDragSourceReleased"
Tapped="OnSeatTapped" Opacity="{Binding DisplayOpacity}">
<StackPanel Spacing="5">
<Grid ColumnDefinitions="*,Auto">
<TextBlock Text="{Binding PositionLabel}" FontSize="10" Opacity="0.5"/>
<TextBlock Grid.Column="1" Text="⠿" Opacity="0.45" IsVisible="{Binding CanEdit}"/>
</Grid>
<TextBlock Text="{Binding StudentName}" FontWeight="SemiBold" FontSize="13"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button Content="{Binding HiddenToggleLabel}"
Command="{Binding ToggleHiddenCommand}" FontSize="9" Padding="6,2"
HorizontalAlignment="Center" IsVisible="{Binding CanToggleHidden}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="5"
IsVisible="{Binding ShowLessonOverview}">
<Border Background="#1976D2" CornerRadius="8" Padding="6,1"
IsVisible="{Binding HasAttendanceBadge}">
<TextBlock Text="{Binding AttendanceBadge}" Foreground="White" FontSize="10"
ToolTip.Tip="Anwesenheit"/>
</Border>
<Border Background="#FB8C00" CornerRadius="8" Padding="6,1"
IsVisible="{Binding HasHomeworkBadge}">
<TextBlock Text="{Binding HomeworkBadge}" Foreground="White" FontSize="10"
ToolTip.Tip="Hausaufgabe"/>
</Border>
<TextBlock Text="{Binding DayHighlightBadge}" FontSize="14"
IsVisible="{Binding HasDayHighlightBadge}"
ToolTip.Tip="Tagesflagge"/>
</StackPanel>
<!-- Strichliste Meldungen (Nutzer-Feedback): schnelles Mitzählen ohne den
vollen Bewertungsdialog zu öffnen -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="5"
IsVisible="{Binding ShowLessonOverview}">
<Button Padding="6,2" FontSize="10"
Command="{Binding TallyRaisedHandCommand}"
ToolTip.Tip="Meldung zählen">
<TextBlock Text="{Binding RaisedHandCount, StringFormat='✋ {0}'}"/>
</Button>
<Button Padding="6,2" FontSize="10"
Command="{Binding TallyCalledOnCommand}"
ToolTip.Tip="Meldung + drangekommen zählen">
<TextBlock Text="{Binding CalledOnCount, StringFormat='✋✓ {0}'}"/>
</Button>
</StackPanel>
<Expander Header=" Situation" FontSize="10"
IsVisible="{Binding CanRecordLesson}">
<ItemsControl ItemsSource="{Binding SituationTags}" Margin="0,4,0,0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate><WrapPanel ItemSpacing="3" LineSpacing="3"/></ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vm:SituationTagChoice">
<ToggleButton Content="{Binding Text}" IsChecked="{Binding IsSelected, Mode=OneWay}"
Command="{Binding ToggleCommand}" FontSize="9" Padding="5,2"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Expander>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Border Background="{DynamicResource SystemControlBackgroundChromeMediumLowBrush}"
CornerRadius="6" Padding="36,8" HorizontalAlignment="Center"
IsVisible="{Binding IsBoardAtBottom}">
<TextBlock Text="Tafel / Vorderseite" FontWeight="SemiBold" Opacity="0.75"/>
</Border>
</StackPanel>
</ScrollViewer>
<!-- Die Schülerliste hat einen eigenen Scrollbereich und bleibt dadurch auch bei
großen Räumen neben den aktuell sichtbaren Sitzplätzen erreichbar. -->
<Border Grid.Row="1" Grid.Column="1"
Width="220" IsVisible="{Binding IsEditMode}"
DragDrop.AllowDrop="True" DragDrop.DragOver="OnUnassignedDragOver"
DragDrop.Drop="OnUnassignedDrop"
BorderBrush="{DynamicResource SystemControlForegroundBaseLowBrush}"
BorderThickness="1" CornerRadius="7" Padding="12">
<Grid RowDefinitions="Auto,Auto,*">
<TextBlock Grid.Row="0" Text="NICHT ZUGEORDNET" FontSize="10"
FontWeight="Bold" Opacity="0.5"/>
<TextBlock Grid.Row="1" Margin="0,5,0,10"
Text="Schüler auf einen Platz ziehen. Belegte Plätze hierher ziehen, um sie zu leeren."
TextWrapping="Wrap" FontSize="11" Opacity="0.5"/>
<ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<StackPanel Spacing="6">
<ItemsControl ItemsSource="{Binding UnassignedStudents}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:StudentSeatOption">
<Border Background="{DynamicResource SystemAccentColorLight2}" CornerRadius="5"
Padding="9,7"
PointerPressed="OnDragSourcePressed"
PointerMoved="OnDragSourceMoved"
PointerReleased="OnDragSourceReleased">
<TextBlock Text="{Binding DisplayName}" FontSize="12" TextTrimming="CharacterEllipsis"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock Text="Alle Schüler sind zugeordnet." Classes="emptyhint"
TextWrapping="Wrap"
IsVisible="{Binding !UnassignedStudents.Count}"/>
</StackPanel>
</ScrollViewer>
</Grid>
</Border>
</Grid>
</Grid>
</Grid>
</UserControl>