This commit is contained in:
2026-03-29 23:47:31 +02:00
commit 216d5d2280
75 changed files with 5702 additions and 0 deletions

View File

@@ -0,0 +1,185 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels"
x:Class="LehrerApp.Desktop.Views.DevicePairingDialog"
x:DataType="vm:DevicePairingViewModel"
Title="Gerät einrichten"
Width="480" Height="420"
CanResize="False"
WindowStartupLocation="CenterOwner">
<Grid Margin="28">
<!-- ── Modus: Auswahl ──────────────────────────────────────────────────── -->
<StackPanel Spacing="16"
IsVisible="{Binding Mode,
Converter={x:Static ObjectConverters.Equal},
ConverterParameter={x:Static vm:PairingMode.SelectMode}}">
<TextBlock Text="Gerät einrichten"
FontSize="20" FontWeight="SemiBold"/>
<TextBlock TextWrapping="Wrap" Opacity="0.7">
Möchtest du ein neues Gerät mit deinem bestehenden Datenbestand
verbinden, oder dieses Gerät als erstes Gerät einrichten?
</TextBlock>
<Button Content="Daten auf dieses Gerät übertragen"
HorizontalAlignment="Stretch"
Command="{Binding SelectReceiverCommand}"
Padding="12,10"/>
<Button Content="Von diesem Gerät Daten übertragen"
HorizontalAlignment="Stretch"
Command="{Binding SelectSenderCommand}"
Padding="12,10"/>
</StackPanel>
<!-- ── Modus: Sender ───────────────────────────────────────────────────── -->
<StackPanel Spacing="16"
IsVisible="{Binding Mode,
Converter={x:Static ObjectConverters.Equal},
ConverterParameter={x:Static vm:PairingMode.Sender}}">
<TextBlock Text="Daten übertragen"
FontSize="20" FontWeight="SemiBold"/>
<TextBlock TextWrapping="Wrap" Opacity="0.7">
Es wird ein verschlüsselter Snapshot deiner lokalen Datenbank erstellt
und kurzzeitig auf dem Server hinterlegt. Du erhältst einen Einmal-Code
der 24 Stunden gültig ist.
</TextBlock>
<!-- Fortschritt -->
<ProgressBar Value="{Binding ProgressPercent}"
Maximum="100" Height="6" CornerRadius="3"
IsVisible="{Binding IsBusy}"/>
<TextBlock Text="{Binding StatusMessage}"
FontSize="12" Opacity="0.7"
IsVisible="{Binding IsBusy}"/>
<!-- Fehler -->
<Border Background="#22FF0000" CornerRadius="6" Padding="12"
IsVisible="{Binding IsError}">
<TextBlock Text="{Binding StatusMessage}"
TextWrapping="Wrap" Foreground="Red"/>
</Border>
<Grid ColumnDefinitions="*,8,Auto" Margin="0,8,0,0">
<Button Grid.Column="0"
Content="← Zurück"
Command="{Binding BackCommand}"
IsEnabled="{Binding !IsBusy}"/>
<Button Grid.Column="2"
Content="Snapshot erstellen"
Command="{Binding CreateSnapshotCommand}"
IsEnabled="{Binding !IsBusy}"
Padding="16,8"/>
</Grid>
</StackPanel>
<!-- ── Modus: Sender zeigt Code ────────────────────────────────────────── -->
<StackPanel Spacing="16"
IsVisible="{Binding Mode,
Converter={x:Static ObjectConverters.Equal},
ConverterParameter={x:Static vm:PairingMode.SenderShowCode}}">
<TextBlock Text="Code bereit" FontSize="20" FontWeight="SemiBold"/>
<TextBlock TextWrapping="Wrap" Opacity="0.7">
Gib diesen Code auf dem Zielgerät ein. Der Code ist einmalig verwendbar.
</TextBlock>
<!-- Der Code prominent anzeigen -->
<Border Background="{DynamicResource SystemControlBackgroundAltHighBrush}"
CornerRadius="10" Padding="24,20">
<StackPanel HorizontalAlignment="Center" Spacing="8">
<TextBlock Text="{Binding GeneratedCode}"
FontSize="32" FontWeight="Bold"
FontFamily="Cascadia Code, Consolas, monospace"
HorizontalAlignment="Center"
LetterSpacing="4"/>
<TextBlock Text="{Binding CodeExpiresText}"
FontSize="12" Opacity="0.5"
HorizontalAlignment="Center"/>
</StackPanel>
</Border>
<TextBlock TextWrapping="Wrap" FontSize="12" Opacity="0.6">
Der Code wird nach dem ersten Abruf automatisch ungültig.
Der Server speichert nur verschlüsselte Daten kein Klartext.
</TextBlock>
<Button Content="Fertig" HorizontalAlignment="Right"
Click="OnClose" Padding="16,8"/>
</StackPanel>
<!-- ── Modus: Empfänger Code eingeben ────────────────────────────────── -->
<StackPanel Spacing="16"
IsVisible="{Binding Mode,
Converter={x:Static ObjectConverters.Equal},
ConverterParameter={x:Static vm:PairingMode.Receiver}}">
<TextBlock Text="Code eingeben"
FontSize="20" FontWeight="SemiBold"/>
<TextBlock TextWrapping="Wrap" Opacity="0.7">
Gib den Code ein der auf dem Quellgerät angezeigt wird.
Format: WORT-ZZ-WORT (z.B. TIGER-42-BLAU)
</TextBlock>
<TextBox Text="{Binding InputCode}"
Watermark="TIGER-42-BLAU"
FontSize="20"
FontFamily="Cascadia Code, Consolas, monospace"
TextAlignment="Center"
CharacterCasing="Upper"/>
<!-- Fortschritt -->
<ProgressBar Value="{Binding ProgressPercent}"
Maximum="100" Height="6" CornerRadius="3"
IsVisible="{Binding IsBusy}"/>
<TextBlock Text="{Binding StatusMessage}"
FontSize="12" Opacity="0.7"
IsVisible="{Binding IsBusy}"/>
<!-- Fehler -->
<Border Background="#22FF0000" CornerRadius="6" Padding="12"
IsVisible="{Binding IsError}">
<TextBlock Text="{Binding StatusMessage}"
TextWrapping="Wrap" Foreground="Red"/>
</Border>
<Grid ColumnDefinitions="*,8,Auto">
<Button Grid.Column="0" Content="← Zurück"
Command="{Binding BackCommand}"
IsEnabled="{Binding !IsBusy}"/>
<Button Grid.Column="2"
Content="Wiederherstellen"
Click="OnRestore"
IsEnabled="{Binding !IsBusy}"
Padding="16,8"/>
</Grid>
</StackPanel>
<!-- ── Modus: Empfänger Fertig ───────────────────────────────────────── -->
<StackPanel Spacing="16" HorizontalAlignment="Center"
VerticalAlignment="Center"
IsVisible="{Binding Mode,
Converter={x:Static ObjectConverters.Equal},
ConverterParameter={x:Static vm:PairingMode.ReceiverDone}}">
<TextBlock Text="✓" FontSize="48" HorizontalAlignment="Center"
Foreground="Green"/>
<TextBlock Text="Erfolgreich übertragen!"
FontSize="20" FontWeight="SemiBold"
HorizontalAlignment="Center"/>
<TextBlock Text="{Binding StatusMessage}"
Opacity="0.7" HorizontalAlignment="Center"
TextWrapping="Wrap" TextAlignment="Center"/>
<Button Content="App neu starten"
HorizontalAlignment="Center"
Click="OnRestartRequested"
Padding="16,8" Margin="0,8,0,0"/>
</StackPanel>
</Grid>
</Window>