Kapitel 7 abgeschlossen.
This commit is contained in:
@@ -72,6 +72,9 @@
|
||||
<Button Grid.Column="4" Content="×" Padding="6,2"
|
||||
Command="{Binding RemoveCommand}" FontSize="14"/>
|
||||
</Grid>
|
||||
<TextBox Text="{Binding LetterSalutation}"
|
||||
PlaceholderText="Briefanrede, z.B. Sehr geehrte Frau Mustermann,"
|
||||
FontSize="12"/>
|
||||
<!-- Zeile 2: Telefon + E-Mail -->
|
||||
<Grid ColumnDefinitions="*,10,*">
|
||||
<TextBox Grid.Column="0" Text="{Binding Phone}"
|
||||
|
||||
@@ -28,6 +28,14 @@
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Briefanrede" FontSize="12" Opacity="0.7"/>
|
||||
<TextBox Text="{Binding LetterSalutation}"
|
||||
PlaceholderText="z.B. Sehr geehrte Frau Mustermann,"/>
|
||||
<TextBlock Text="Wird unverändert in Word-Vorlagen für Letter.Salutation eingesetzt."
|
||||
FontSize="11" Opacity="0.55" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
|
||||
<Grid ColumnDefinitions="*,10,*">
|
||||
<StackPanel Grid.Column="0" Spacing="4">
|
||||
<TextBlock Text="Telefon" FontSize="12" Opacity="0.7"/>
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.Students"
|
||||
x:Class="LehrerApp.Desktop.Views.Students.CreateLetterDialog"
|
||||
x:DataType="vm:CreateLetterDialogViewModel"
|
||||
Title="Word-Brief erstellen" Width="580" Height="650"
|
||||
MinWidth="500" MinHeight="540" CanResize="True"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
<Grid RowDefinitions="*,Auto" Margin="24,20">
|
||||
<ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Spacing="15">
|
||||
<TextBlock Text="Word-Brief erstellen" Classes="dialogtitle"/>
|
||||
<TextBlock FontSize="12" Opacity="0.65" TextWrapping="Wrap"
|
||||
Text="Die Vorlage wird vor der Erzeugung erneut geprüft. Das Original bleibt unverändert; gespeichert wird eine frei bearbeitbare DOCX-Kopie."/>
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Schüler" FontSize="12" Opacity="0.7"/>
|
||||
<TextBlock Text="{Binding StudentName}" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Vorlage *" FontSize="12" Opacity="0.7"/>
|
||||
<ComboBox ItemsSource="{Binding Templates}" SelectedItem="{Binding SelectedTemplate}"
|
||||
DisplayMemberBinding="{Binding Name}" HorizontalAlignment="Stretch"/>
|
||||
<TextBlock Text="Noch keine Vorlage. Bitte unter Einstellungen → Briefvorlagen importieren."
|
||||
Classes="emptyhint" IsVisible="{Binding HasNoTemplates}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Kontakt *" FontSize="12" Opacity="0.7"/>
|
||||
<ComboBox ItemsSource="{Binding Contacts}" SelectedItem="{Binding SelectedContact}"
|
||||
DisplayMemberBinding="{Binding Display}" HorizontalAlignment="Stretch"/>
|
||||
<TextBlock Text="Kein aktueller Kontakt vorhanden." Classes="emptyhint"
|
||||
IsVisible="{Binding HasNoContacts}"/>
|
||||
</StackPanel>
|
||||
<Grid ColumnDefinitions="*,12,*">
|
||||
<StackPanel Grid.Column="0" Spacing="4">
|
||||
<TextBlock Text="Lerngruppe" FontSize="12" Opacity="0.7"/>
|
||||
<ComboBox ItemsSource="{Binding Groups}" SelectedItem="{Binding SelectedGroup}"
|
||||
DisplayMemberBinding="{Binding Display}" PlaceholderText="Optional"
|
||||
HorizontalAlignment="Stretch"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="2" Spacing="4">
|
||||
<TextBlock Text="Briefdatum *" FontSize="12" Opacity="0.7"/>
|
||||
<CalendarDatePicker SelectedDate="{Binding LetterDate}" HorizontalAlignment="Stretch"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<Border BorderBrush="#D97706" BorderThickness="1" CornerRadius="6" Padding="10"
|
||||
IsVisible="{Binding HasIssues}">
|
||||
<StackPanel Spacing="5">
|
||||
<TextBlock Text="Vor dem Erzeugen korrigieren" FontWeight="SemiBold" Foreground="#D97706"/>
|
||||
<ItemsControl ItemsSource="{Binding Issues}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:LetterGenerationIssue">
|
||||
<Grid ColumnDefinitions="24,*" Margin="0,2">
|
||||
<TextBlock Grid.Column="0" Text="{Binding Icon}" Foreground="{Binding Color}"/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding Message}" Foreground="{Binding Color}"
|
||||
FontSize="12" TextWrapping="Wrap"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<TextBlock Text="{Binding GenerationError}" Foreground="Red" FontSize="12" TextWrapping="Wrap"
|
||||
IsVisible="{Binding GenerationError, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<Grid Grid.Row="1" ColumnDefinitions="*,10,*" Margin="0,18,0,0">
|
||||
<Button Grid.Column="0" Content="Abbrechen" HorizontalAlignment="Stretch" Click="OnCancel"/>
|
||||
<Button Grid.Column="2" Content="DOCX speichern …" HorizontalAlignment="Stretch"
|
||||
IsEnabled="{Binding CanGenerate}" Click="OnGenerate"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,27 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Platform.Storage;
|
||||
using LehrerApp.Desktop.ViewModels.Students;
|
||||
|
||||
namespace LehrerApp.Desktop.Views.Students;
|
||||
|
||||
public partial class CreateLetterDialog : Window
|
||||
{
|
||||
public CreateLetterDialog() => InitializeComponent();
|
||||
|
||||
private async void OnGenerate(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not CreateLetterDialogViewModel vm) return;
|
||||
var file = await StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
|
||||
{
|
||||
Title = "Word-Brief speichern",
|
||||
SuggestedFileName = vm.SuggestedFileName,
|
||||
DefaultExtension = "docx",
|
||||
FileTypeChoices = [new FilePickerFileType("Word-Dokumente") { Patterns = ["*.docx"] }],
|
||||
});
|
||||
if (file is null || !vm.Generate(file.Path.LocalPath)) return;
|
||||
Close(file.Path.LocalPath);
|
||||
}
|
||||
|
||||
private void OnCancel(object? sender, RoutedEventArgs e) => Close(null);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.Students"
|
||||
x:Class="LehrerApp.Desktop.Views.Students.ManageStudentDialog"
|
||||
x:DataType="vm:ManageStudentDialogViewModel"
|
||||
Title="Schüler verwalten"
|
||||
Width="500" Height="500"
|
||||
CanResize="False" WindowStartupLocation="CenterOwner">
|
||||
|
||||
<Grid RowDefinitions="*,Auto" Margin="24">
|
||||
<StackPanel Grid.Row="0" Spacing="14">
|
||||
<TextBlock Text="Schüler verwalten" Classes="dialogtitle"/>
|
||||
<TextBlock Text="{Binding StudentName}" FontSize="15" FontWeight="SemiBold"/>
|
||||
|
||||
<Border Background="{DynamicResource SystemControlBackgroundAltHighBrush}"
|
||||
CornerRadius="6" Padding="14">
|
||||
<StackPanel Spacing="8">
|
||||
<TextBlock Text="Deaktivieren blendet den Schüler aus den normalen Listen aus. Alle historischen Daten bleiben erhalten."
|
||||
TextWrapping="Wrap" FontSize="12"/>
|
||||
<TextBlock Text="Der Schüler ist bereits deaktiviert und kann wieder aktiviert werden."
|
||||
TextWrapping="Wrap" FontSize="12" IsVisible="{Binding IsInactive}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<StackPanel Spacing="8" IsVisible="{Binding HasReferences}">
|
||||
<TextBlock Text="Verknüpfte Daten" FontWeight="SemiBold"/>
|
||||
<ItemsControl ItemsSource="{Binding ReferenceItems}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:StudentReferenceItem">
|
||||
<Grid ColumnDefinitions="*,Auto" Margin="0,2">
|
||||
<TextBlock Grid.Column="0" Text="{Binding Label}"/>
|
||||
<TextBlock Grid.Column="1" Text="{Binding CountDisplay}" FontWeight="SemiBold"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<TextBlock Text="Eine endgültige Löschung ist deshalb gesperrt. Verwende stattdessen Deaktivieren."
|
||||
Foreground="#D97706" TextWrapping="Wrap" FontSize="12"/>
|
||||
</StackPanel>
|
||||
|
||||
<Border IsVisible="{Binding CanDelete}" BorderBrush="#C62828" BorderThickness="1"
|
||||
CornerRadius="6" Padding="12">
|
||||
<TextBlock Text="Es bestehen keine Verknüpfungen. Der Schüler kann endgültig gelöscht werden. Stammdaten und Kontakte gehen dabei unwiderruflich verloren."
|
||||
Foreground="#C62828" TextWrapping="Wrap" FontSize="12"/>
|
||||
</Border>
|
||||
|
||||
<TextBlock Text="{Binding ErrorMessage}" Foreground="Red" FontSize="12"
|
||||
IsVisible="{Binding ErrorMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
||||
</StackPanel>
|
||||
|
||||
<Grid Grid.Row="1" ColumnDefinitions="Auto,Auto,*,Auto" ColumnSpacing="8" Margin="0,18,0,0">
|
||||
<Button Grid.Column="0" Content="Deaktivieren" Click="OnDeactivate" IsVisible="{Binding IsActive}"/>
|
||||
<Button Grid.Column="0" Content="Wieder aktivieren" Click="OnReactivate" IsVisible="{Binding IsInactive}"/>
|
||||
<Button Grid.Column="1" Content="Endgültig löschen" Click="OnDeletePermanently"
|
||||
IsEnabled="{Binding CanDelete}"/>
|
||||
<Button Grid.Column="3" Content="Schließen" Click="OnCancel"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,33 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using LehrerApp.Desktop.ViewModels.Students;
|
||||
|
||||
namespace LehrerApp.Desktop.Views.Students;
|
||||
|
||||
public partial class ManageStudentDialog : Window
|
||||
{
|
||||
public ManageStudentDialog() => InitializeComponent();
|
||||
|
||||
private void OnDeactivate(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not ManageStudentDialogViewModel vm) return;
|
||||
vm.DeactivateCommand.Execute(null);
|
||||
Close(vm.Result);
|
||||
}
|
||||
|
||||
private void OnReactivate(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not ManageStudentDialogViewModel vm) return;
|
||||
vm.ReactivateCommand.Execute(null);
|
||||
Close(vm.Result);
|
||||
}
|
||||
|
||||
private void OnDeletePermanently(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not ManageStudentDialogViewModel vm) return;
|
||||
vm.DeletePermanentlyCommand.Execute(null);
|
||||
if (vm.Result == StudentManagementResult.Deleted) Close(vm.Result);
|
||||
}
|
||||
|
||||
private void OnCancel(object? sender, RoutedEventArgs e) => Close(StudentManagementResult.Cancelled);
|
||||
}
|
||||
@@ -11,16 +11,29 @@
|
||||
BorderBrush="{DynamicResource SystemControlForegroundBaseLowBrush}"
|
||||
BorderThickness="0,0,0,1">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<shared:PageHeader Grid.Column="0" IsVisible="{Binding !IsEditing}" Title="{Binding StudentTitle}"/>
|
||||
<Border Grid.Column="0" Width="38" Height="38" CornerRadius="19"
|
||||
Background="{Binding StudentAvatarColor}" HorizontalAlignment="Left"
|
||||
ToolTip.Tip="{Binding StudentAvatarTooltip}" IsVisible="{Binding !IsEditing}">
|
||||
<TextBlock Text="{Binding StudentAvatarLabel}" Foreground="White" FontWeight="Bold" FontSize="15"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<shared:PageHeader Grid.Column="0" Margin="50,0,0,0" IsVisible="{Binding !IsEditing}" Title="{Binding StudentTitle}"/>
|
||||
<StackPanel Grid.Column="0" Spacing="6" IsVisible="{Binding IsEditing}">
|
||||
<Grid ColumnDefinitions="*,8,*">
|
||||
<Grid ColumnDefinitions="*,8,*,8,170">
|
||||
<TextBox Grid.Column="0" Text="{Binding EditFirstName}" PlaceholderText="Vorname"/>
|
||||
<TextBox Grid.Column="2" Text="{Binding EditLastName}" PlaceholderText="Nachname"/>
|
||||
<ComboBox Grid.Column="4" ItemsSource="{Binding GenderOptions}"
|
||||
SelectedItem="{Binding EditGender}" PlaceholderText="Geschlecht"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="8" VerticalAlignment="Top">
|
||||
<TextBlock Text="{Binding StudentStatus}" VerticalAlignment="Center" Opacity="0.65"/>
|
||||
<Button Content="Word-Brief" Command="{Binding CreateLetterCommand}"
|
||||
IsVisible="{Binding !IsEditing}"/>
|
||||
<Button Content="Bearbeiten" Command="{Binding StartEditCommand}"
|
||||
IsVisible="{Binding !IsEditing}"/>
|
||||
<Button Content="Schüler verwalten" Command="{Binding ManageStudentCommand}"
|
||||
IsVisible="{Binding !IsEditing}"/>
|
||||
<Button Content="Speichern" Command="{Binding SaveEditCommand}"
|
||||
IsVisible="{Binding IsEditing}"/>
|
||||
<Button Content="Abbrechen" Command="{Binding CancelEditCommand}"
|
||||
@@ -88,6 +101,9 @@
|
||||
CornerRadius="4" Padding="6,2" HorizontalAlignment="Left">
|
||||
<TextBlock Text="{Binding Relation}" FontSize="11" Opacity="0.7"/>
|
||||
</Border>
|
||||
<TextBlock Text="{Binding LetterSalutation}" FontSize="11" Opacity="0.6"
|
||||
TextWrapping="Wrap"
|
||||
IsVisible="{Binding LetterSalutation, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="1" Grid.Row="0" Orientation="Horizontal" Spacing="8">
|
||||
|
||||
@@ -23,6 +23,8 @@ public partial class StudentDetailView : UserControl
|
||||
vm.OnConfirmDeleteDocumentation = ShowDeleteDocumentationDialog;
|
||||
vm.OnSaveExportFile = SaveExportFile;
|
||||
vm.OnConductParentCall = ShowParentCallSessionDialog;
|
||||
vm.OnManageStudent = ShowManageStudentDialog;
|
||||
vm.OnCreateLetter = ShowCreateLetterDialog;
|
||||
}
|
||||
|
||||
private async Task<Contact?> ShowContactDialog(Contact? contact)
|
||||
@@ -36,6 +38,32 @@ public partial class StudentDetailView : UserControl
|
||||
return saved ? vm.Result : null;
|
||||
}
|
||||
|
||||
private async Task<StudentManagementResult> ShowManageStudentDialog(Student student)
|
||||
{
|
||||
var owner = TopLevel.GetTopLevel(this) as Window;
|
||||
if (owner is null) return StudentManagementResult.Cancelled;
|
||||
|
||||
var vm = new ManageStudentDialogViewModel(
|
||||
App.Services.GetRequiredService<IStudentRepository>(), student);
|
||||
var dialog = new ManageStudentDialog { DataContext = vm };
|
||||
return await dialog.ShowDialog<StudentManagementResult>(owner);
|
||||
}
|
||||
|
||||
private async Task ShowCreateLetterDialog()
|
||||
{
|
||||
var owner = TopLevel.GetTopLevel(this) as Window;
|
||||
if (owner is null || DataContext is not StudentDetailViewModel { Student: { } student }) return;
|
||||
|
||||
var vm = new CreateLetterDialogViewModel(student,
|
||||
App.Services.GetRequiredService<LehrerApp.Core.Services.LetterTemplateService>(),
|
||||
App.Services.GetRequiredService<IGroupMembershipRepository>(),
|
||||
App.Services.GetRequiredService<IGroupRepository>());
|
||||
var dialog = new CreateLetterDialog { DataContext = vm };
|
||||
var path = await dialog.ShowDialog<string?>(owner);
|
||||
if (!string.IsNullOrEmpty(path) && File.Exists(path))
|
||||
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(path) { UseShellExecute = true });
|
||||
}
|
||||
|
||||
private void ShowAddressViewer(ContactItem contact)
|
||||
{
|
||||
if (!contact.HasAddress) return;
|
||||
|
||||
@@ -19,13 +19,25 @@
|
||||
</Border>
|
||||
<DockPanel Grid.Row="1">
|
||||
<TextBox DockPanel.Dock="Top" Text="{Binding SearchText}"
|
||||
PlaceholderText="Name suchen…" Margin="16,10,16,4"/>
|
||||
PlaceholderText="Name oder Lerngruppe suchen…" Margin="16,10,16,4"/>
|
||||
<DataGrid ItemsSource="{Binding Students}"
|
||||
SelectedItem="{Binding SelectedStudent}"
|
||||
AutoGenerateColumns="False" IsReadOnly="True"
|
||||
GridLinesVisibility="Horizontal"
|
||||
CanUserReorderColumns="False" Margin="16,4">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="" Width="48">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="vm:StudentListItem">
|
||||
<Border Width="30" Height="30" CornerRadius="15" Background="{Binding AvatarColor}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
ToolTip.Tip="{Binding AvatarTooltip}">
|
||||
<TextBlock Text="{Binding AvatarLabel}" Foreground="White" FontWeight="Bold"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<DataGridTextColumn Header="Name" Binding="{Binding FullName}" Width="*"/>
|
||||
<DataGridTextColumn Header="Geburtsdatum" Binding="{Binding DateOfBirth}" Width="130"/>
|
||||
</DataGrid.Columns>
|
||||
|
||||
Reference in New Issue
Block a user