Files
LehrerApp/LehrerApp.Desktop/Views/Groups/AiAssistDialog.axaml
T
adminandClaude Sonnet 5 364df378f0 KI-Feature 4.5.21: didaktischer Hintergrund je Stunde, nur auf Nachfrage
Neuer Endpunkt ai-backend/explain.php mit eigenem statischen Systemprompt
(Begründung des Phasenaufbaus, mögliche Stolpersteine, Differenzierungsideen).
Bewusst als separater Endpunkt statt Zusatzfeld in jeder plan.php-Antwort,
damit die Erklärung nur bei tatsächlicher Nutzung abgerechnet wird statt bei
jeder Planungsanfrage mitgeneriert zu werden.

Die Guthaben-Abrechnung (SELECT-FOR-UPDATE, Transaktions-Insert) wurde aus
plan.php nach ai_backend_call_and_charge in db.php ausgelagert, damit sie
nicht an zwei Stellen gepflegt werden muss. Kein neues DB-Schema nötig.

Im AiAssistDialog erscheint je Stunde ein Button "Didaktischen Hintergrund
erklären", der nach dem Laden durch den Text ersetzt wird.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-16 22:32:36 +02:00

95 lines
6.0 KiB
XML

<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.Groups"
x:Class="LehrerApp.Desktop.Views.Groups.AiAssistDialog"
x:DataType="vm:AiAssistDialogViewModel"
Title="KI-Unterstützung"
Width="480" Height="560" MinWidth="420" MinHeight="420"
CanResize="True" WindowStartupLocation="CenterOwner">
<Grid RowDefinitions="*,Auto" Margin="24">
<ScrollViewer Grid.Row="0">
<StackPanel Spacing="14" Margin="0,0,12,0">
<TextBlock Text="KI-Unterstützung" Classes="dialogtitle"/>
<TextBlock Text="{Binding UnitSummary}" FontSize="12" Opacity="0.6"/>
<StackPanel Spacing="10" IsVisible="{Binding HasResults}">
<TextBlock Text="{Binding Summary}" FontSize="12" TextWrapping="Wrap"
IsVisible="{Binding Summary, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
<TextBlock Text="Vorschläge (angehakt wird übernommen)" FontSize="12" Opacity="0.7"/>
<ItemsControl ItemsSource="{Binding ReviewItems}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:AiLessonReviewItem">
<StackPanel Margin="0,3" Spacing="2">
<CheckBox Content="{Binding DisplayLabel}" IsChecked="{Binding Accepted}"/>
<TextBlock Text="{Binding DiffText}" FontSize="11" Opacity="0.6" TextWrapping="Wrap"
Margin="24,0,0,0"
IsVisible="{Binding DiffText, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
<ItemsControl ItemsSource="{Binding MaterialPrompts}" Margin="24,2,0,0">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:MaterialPromptItem">
<Border Background="#14000000" CornerRadius="4" Padding="6" Margin="0,2">
<StackPanel Spacing="4">
<TextBlock Text="{Binding SuggestionText}" FontSize="11" TextWrapping="Wrap"/>
<Button Content="📋 Prompt kopieren (extern erzeugen)" FontSize="11"
Click="OnCopyMaterialPrompt"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Content="💡 Didaktischen Hintergrund erklären" FontSize="11" Margin="24,2,0,0"
HorizontalAlignment="Left"
Command="{Binding RequestExplanationCommand}"
IsVisible="{Binding ShowExplanationButton}"
IsEnabled="{Binding !IsLoadingExplanation}"/>
<TextBlock Text="Lädt…" FontSize="11" Opacity="0.6" Margin="24,0,0,0"
IsVisible="{Binding IsLoadingExplanation}"/>
<TextBlock Text="{Binding ExplanationError}" Foreground="Red" FontSize="11" TextWrapping="Wrap"
Margin="24,0,0,0"
IsVisible="{Binding ExplanationError, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
<Border Background="#0A000000" CornerRadius="4" Padding="6" Margin="24,2,0,0"
IsVisible="{Binding Explanation, Converter={x:Static StringConverters.IsNotNullOrEmpty}}">
<TextBlock Text="{Binding Explanation}" FontSize="11" TextWrapping="Wrap"/>
</Border>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock Text="Die KI hat keine Stunden vorgeschlagen." Opacity="0.6" FontSize="12"
IsVisible="{Binding !ReviewItems.Count}"/>
</StackPanel>
<StackPanel Spacing="8">
<TextBlock Text="Weitere Anweisung (nachfassen, baut auf den angehakten Vorschlägen oben auf)"
FontSize="12" Opacity="0.7" IsVisible="{Binding HasResults}"/>
<TextBlock Text="Anweisung" FontSize="12" Opacity="0.7" IsVisible="{Binding !HasResults}"/>
<TextBox Text="{Binding Instruction}" AcceptsReturn="True" TextWrapping="Wrap" Height="120"
PlaceholderText="z.B. Ergänze zwei weitere Stunden zum Thema Redoxreaktionen mit steigendem Anspruch."
IsEnabled="{Binding !IsBusy}"/>
<CheckBox Content="Auch bestehende Stundeninhalte anpassen" IsChecked="{Binding AllowModifyingExisting}"
IsEnabled="{Binding !IsBusy}"
ToolTip.Tip="Deaktivieren, um die Einheit nur um neue Stunden zu erweitern, ohne den Inhalt bereits vorhandener Stunden zu verändern."/>
</StackPanel>
<StackPanel Spacing="4" IsVisible="{Binding IsBusy}">
<TextBlock Text="Anfrage läuft…" FontSize="12" Opacity="0.6"/>
<ProgressBar IsIndeterminate="True" Height="4"/>
</StackPanel>
<TextBlock Text="{Binding ErrorMessage}" Foreground="Red" FontSize="12" TextWrapping="Wrap"
IsVisible="{Binding ErrorMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
</StackPanel>
</ScrollViewer>
<Grid Grid.Row="1" ColumnDefinitions="*,8,*,8,*" Margin="0,20,0,0">
<Button Grid.Column="0" Content="Abbrechen" HorizontalAlignment="Stretch" Click="OnCancel"/>
<Button Grid.Column="2" Content="Anfrage senden" HorizontalAlignment="Stretch" Click="OnSend"
IsVisible="{Binding !HasResults}" IsEnabled="{Binding !IsBusy}"/>
<Button Grid.Column="2" Content="Erneut anfragen" HorizontalAlignment="Stretch" Click="OnSend"
IsVisible="{Binding HasResults}" IsEnabled="{Binding !IsBusy}"/>
<Button Grid.Column="4" Content="Übernehmen" HorizontalAlignment="Stretch" Click="OnApply"
IsVisible="{Binding HasResults}"/>
</Grid>
</Grid>
</Window>