Utopia-Canteen-System/Views/SettingsView.xaml

468 lines
31 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<UserControl x:Class="UtopiaCanteenSystem.Views.SettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis" />
<SolidColorBrush x:Key="AppBackground" Color="#F0F2F5"/>
<SolidColorBrush x:Key="CardBackground" Color="#FFFFFF"/>
<SolidColorBrush x:Key="PrimaryText" Color="#2D3748"/>
<SolidColorBrush x:Key="MutedText" Color="#718096"/>
<SolidColorBrush x:Key="PrimaryAccent" Color="#5BA3A0"/>
<SolidColorBrush x:Key="PrimaryHover" Color="#4a918e"/>
<SolidColorBrush x:Key="SuccessBrush" Color="#38A169"/>
<SolidColorBrush x:Key="ErrorBrush" Color="#E53E3E"/>
<SolidColorBrush x:Key="BorderBrush" Color="#E2E8F0"/>
<SolidColorBrush x:Key="FocusRingBrush" Color="#335BA3A0"/>
<Style x:Key="ModernTextBoxStyle" TargetType="TextBox">
<Setter Property="MinHeight" Value="50"/>
<Setter Property="Background" Value="White"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="#E2E8F0"/>
<Setter Property="Foreground" Value="#0A1628"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="Padding" Value="16,0"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid>
<Border x:Name="FocusRing"
CornerRadius="8"
BorderThickness="3"
BorderBrush="{StaticResource FocusRingBrush}"
Opacity="0"/>
<Border x:Name="InputBorder"
CornerRadius="8"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<Border.BorderBrush>
<SolidColorBrush x:Name="InputBorderBrush" Color="#E2E8F0"/>
</Border.BorderBrush>
<ScrollViewer x:Name="PART_ContentHost" Margin="{TemplateBinding Padding}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="InputBorderBrush"
Storyboard.TargetProperty="Color"
To="#995BA3A0"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="InputBorderBrush"
Storyboard.TargetProperty="Color"
To="#E2E8F0"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="FocusRing" Property="Opacity" Value="1"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="InputBorderBrush"
Storyboard.TargetProperty="Color"
To="#5BA3A0"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="InputBorder" Property="Background" Value="#F8FAFC"/>
<Setter Property="Foreground" Value="#94A3B8"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Save Button Style - Green/Teal Theme -->
<Style x:Key="PrimaryButtonStyle" TargetType="Button">
<Setter Property="Background" Value="{StaticResource PrimaryAccent}"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Padding" Value="24,14"/>
<Setter Property="MinHeight" Value="50"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="ButtonBorder"
Background="{TemplateBinding Background}"
CornerRadius="8">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ButtonBorder" Property="Background" Value="{StaticResource PrimaryHover}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="ButtonBorder" Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="0.98" ScaleY="0.98" />
</Setter.Value>
</Setter>
<Setter TargetName="ButtonBorder" Property="Background" Value="#3f7f7c"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Cancel Button Style - Gray Outline Theme -->
<Style x:Key="OutlineButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{StaticResource PrimaryText}"/>
<Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Padding" Value="24,14"/>
<Setter Property="MinHeight" Value="50"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="ButtonBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="8">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ButtonBorder" Property="Background" Value="#f4f7f7"/>
<Setter TargetName="ButtonBorder" Property="BorderBrush" Value="#5BA3A0"/>
<Setter Property="Foreground" Value="#5BA3A0"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="ButtonBorder" Property="Background" Value="#eef2f2"/>
<Setter TargetName="ButtonBorder" Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="0.98" ScaleY="0.98" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid Background="{StaticResource AppBackground}" MinHeight="0" MinWidth="0">
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
Padding="16"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid MinHeight="{Binding ViewportHeight, RelativeSource={RelativeSource AncestorType=ScrollViewer}}"
HorizontalAlignment="Stretch">
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="{Binding ViewportWidth, RelativeSource={RelativeSource AncestorType=ScrollViewer}}"
MaxWidth="1200"
MinWidth="280">
<!-- Title section -->
<StackPanel Orientation="Horizontal" Margin="0,0,0,24">
<Border Width="48" Height="48" Background="#eef2f2" CornerRadius="24" Margin="0,0,16,0">
<Viewbox Margin="10">
<Canvas Width="28" Height="28">
<Ellipse Width="28" Height="28" Stroke="{StaticResource PrimaryAccent}" StrokeThickness="2"/>
<Line X1="14" Y1="14" X2="14" Y2="7" Stroke="{StaticResource PrimaryAccent}" StrokeThickness="2" StrokeStartLineCap="Round" StrokeEndLineCap="Round"/>
<Line X1="14" Y1="14" X2="20" Y2="14" Stroke="{StaticResource PrimaryAccent}" StrokeThickness="2" StrokeStartLineCap="Round" StrokeEndLineCap="Round"/>
</Canvas>
</Viewbox>
</Border>
<TextBlock Text="Settings"
FontSize="32"
FontWeight="Bold"
Foreground="{StaticResource PrimaryText}"
VerticalAlignment="Center" />
</StackPanel>
<!-- Card container -->
<Border Background="{StaticResource CardBackground}"
CornerRadius="12"
BorderBrush="{StaticResource BorderBrush}"
BorderThickness="1">
<Border.Effect>
<DropShadowEffect BlurRadius="24" ShadowDepth="0" Opacity="0.08" Color="#000000" />
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Card header -->
<StackPanel Grid.Row="0" Margin="24,20,24,12">
<TextBlock Text="Configuration"
FontSize="24"
FontWeight="Bold"
Foreground="{StaticResource PrimaryText}" />
<TextBlock Text="Manage scan settings and admin access."
FontSize="16"
Foreground="{StaticResource MutedText}"
Margin="0,8,0,0" />
</StackPanel>
<!-- Form fields -->
<StackPanel Grid.Row="1" Margin="24,0,24,0">
<TextBlock Text="Scan interval (minimum time between scans)" FontSize="16" Foreground="{StaticResource PrimaryText}" FontWeight="SemiBold" />
<Grid Margin="0,8,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="8" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="8" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="8" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="Days (0365)" FontSize="13" Foreground="{StaticResource MutedText}" Margin="0,0,0,4"/>
<TextBox Text="{Binding ScanIntervalDays, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" />
</StackPanel>
<StackPanel Grid.Column="2">
<TextBlock Text="Hours (023)" FontSize="13" Foreground="{StaticResource MutedText}" Margin="0,0,0,4"/>
<TextBox Text="{Binding ScanIntervalHours, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" />
</StackPanel>
<StackPanel Grid.Column="4">
<TextBlock Text="Minutes (059)" FontSize="13" Foreground="{StaticResource MutedText}" Margin="0,0,0,4"/>
<TextBox Text="{Binding ScanIntervalMinutes, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" />
</StackPanel>
<StackPanel Grid.Column="6">
<TextBlock Text="Seconds (059)" FontSize="13" Foreground="{StaticResource MutedText}" Margin="0,0,0,4"/>
<TextBox Text="{Binding ScanIntervalSeconds, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" />
</StackPanel>
</Grid>
<TextBlock Text="The minimum time between scans to prevent duplicates. At least 1 second required."
FontSize="14"
Foreground="{StaticResource MutedText}"
Margin="0,0,0,20" />
<TextBlock Text="Admin Employee ID" FontSize="16" Foreground="{StaticResource PrimaryText}" FontWeight="SemiBold" />
<TextBox Text="{Binding AdminCardId, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" Margin="0,8,0,8" />
<TextBlock Text="Card ID with admin access to settings."
FontSize="14"
Foreground="{StaticResource MutedText}"
Margin="0,0,0,20" />
<TextBlock Text="Application mode" FontSize="16" Foreground="{StaticResource PrimaryText}" FontWeight="SemiBold" />
<TextBlock Text="Server: this PC hosts SQLite, sync jobs, and the local HTTP API for scanners. Client: this PC only sends scans to the central server."
FontSize="14"
Foreground="{StaticResource MutedText}"
Margin="0,4,0,8" />
<ComboBox ItemsSource="{Binding AppModeOptions}"
SelectedItem="{Binding SelectedAppMode, Mode=TwoWay}"
MinHeight="44"
FontSize="16"
Margin="0,0,0,12"
Padding="12,8"/>
<TextBlock Text="Central server base URL (client PCs)" FontSize="16" Foreground="{StaticResource PrimaryText}" FontWeight="SemiBold" />
<TextBox Text="{Binding CentralServerBaseUrl, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" Margin="0,8,0,4" />
<TextBlock Text="Example: http://192.168.1.10:5000 — used when this PC is in Client mode."
FontSize="14"
Foreground="{StaticResource MutedText}"
Margin="0,0,0,12" />
<TextBlock Text="Local API listen URL(s) (central server only)" FontSize="16" Foreground="{StaticResource PrimaryText}" FontWeight="SemiBold" />
<TextBox Text="{Binding LocalServerListenUrls, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" Margin="0,8,0,4" />
<TextBlock Text="Example: http://0.0.0.0:5000 — Kestrel bind address on the server PC."
FontSize="14"
Foreground="{StaticResource MutedText}"
Margin="0,0,0,20" />
<StackPanel Visibility="{Binding IsCentralServerMode, Converter={StaticResource BoolToVis}}">
<!--<TextBlock Text="Sync API Endpoint (UIND)" FontSize="16" Foreground="{StaticResource PrimaryText}" FontWeight="SemiBold" />
<TextBox Text="{Binding SyncApiEndpoint, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" Margin="0,8,0,8" />
<TextBlock Text="Endpoint used to sync scan records."
FontSize="14"
Foreground="{StaticResource MutedText}"
Margin="0,0,0,20" />-->
<TextBlock Text="Sync Data To (UIND)"
FontSize="16"
Foreground="{StaticResource PrimaryText}"
FontWeight="SemiBold" />
<Grid Margin="0,8,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="16" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="Post data to production"
FontSize="18"
Foreground="{StaticResource PrimaryText}"
VerticalAlignment="Center"
Margin="4,0,0,0" />
<!-- Post button right next to textbox -->
<Button Grid.Column="2"
Content="{Binding PostButtonText}"
Command="{Binding PostDataNowCommand}"
Style="{StaticResource PrimaryButtonStyle}"
MinWidth="150"
IsEnabled="{Binding CanPostNow}" />
</Grid>
<TextBlock Text="Download employee RFID tags, meal schedules, and menu data for offline scanning."
FontSize="14"
Foreground="{StaticResource MutedText}"
Margin="0,0,0,8" />
<Button Content="{Binding SyncCacheButtonText}"
Command="{Binding SyncEmployeeAndMenuCacheNowCommand}"
Style="{StaticResource PrimaryButtonStyle}"
MinWidth="280"
HorizontalAlignment="Left"
Margin="0,0,0,8"
IsEnabled="{Binding CanSyncCacheNow}" />
<TextBlock Text="{Binding LastEmployeeRfidCacheSyncDisplay, StringFormat=Last employee RFID cache sync: {0}}"
FontSize="14"
Foreground="{StaticResource MutedText}"
Margin="0,0,0,4" />
<TextBlock Text="{Binding LastMealMenuCacheSyncDisplay, StringFormat=Last meal/menu cache sync: {0}}"
FontSize="14"
Foreground="{StaticResource MutedText}"
Margin="0,0,0,20" />
</StackPanel>
<!-- Message area -->
<Border Margin="0,0,0,20" Padding="16" CornerRadius="8">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="#dcfce7" />
<Setter Property="BorderBrush" Value="#86efac" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding SaveMessage}" Value="">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding SaveMessage}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding IsError}" Value="True">
<Setter Property="Background" Value="#fee2e2" />
<Setter Property="BorderBrush" Value="#fca5a5" />
</DataTrigger>
<Trigger Property="IsVisible" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="0" To="1" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SaveIcon}"
FontFamily="Segoe MDL2 Assets"
FontSize="16"
FontWeight="SemiBold"
VerticalAlignment="Center"
Margin="0,0,12,0">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value=""/>
<Setter Property="Foreground" Value="{StaticResource SuccessBrush}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsError}" Value="True">
<Setter Property="Text" Value=""/>
<Setter Property="Foreground" Value="{StaticResource ErrorBrush}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock Text="{Binding SaveMessage}"
FontSize="16"
FontWeight="SemiBold"
VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource SuccessBrush}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsError}" Value="True">
<Setter Property="Foreground" Value="{StaticResource ErrorBrush}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</Border>
</StackPanel>
<!-- Button row -->
<Border Grid.Row="2" BorderBrush="{StaticResource BorderBrush}" BorderThickness="0,1,0,0" Padding="24,20" Background="#f9fbfb">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="0"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<WrapPanel Grid.Column="1" HorizontalAlignment="Right">
<Button Content="Meal Schedules"
Command="{Binding OpenMealSchedulesCommand}"
Style="{StaticResource OutlineButtonStyle}"
MinWidth="120"
Margin="0,0,16,0"
Visibility="{Binding IsCentralServerMode, Converter={StaticResource BoolToVis}}" />
<Button Content="Back"
Command="{Binding BackCommand}"
Style="{StaticResource OutlineButtonStyle}"
MinWidth="120"
Margin="0,0,16,0" />
<Button Content="Save"
Command="{Binding SaveCommand}"
Style="{StaticResource PrimaryButtonStyle}"
MinWidth="120" />
</WrapPanel>
</Grid>
</Border>
</Grid>
</Border>
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
</UserControl>