Utopia-Canteen-System/Views/SettingsView.xaml

456 lines
30 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="Backend base URL" FontSize="16" Foreground="{StaticResource PrimaryText}" FontWeight="SemiBold" />
<TextBox Text="{Binding BackendBaseUrl, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" Margin="0,8,0,4" />
<TextBlock Text="Client: central server IP (e.g. http://192.168.1.10:5000). Server: leave blank to use http://localhost:5000 from listen URL below."
FontSize="14"
Foreground="{StaticResource MutedText}"
Margin="0,0,0,4" />
<TextBlock Text="{Binding EffectiveBackendUrlDisplay, StringFormat=API calls use: {0}}"
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" />
<TextBlock Text="Backend jobs (calls central API — same on server and client)" FontSize="16" Foreground="{StaticResource PrimaryText}" FontWeight="SemiBold" Margin="0,0,0,8" />
<TextBlock Text="Download employee RFID tags, meal schedules, and menu data to central SQLite (HRMS → backend)."
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,12" />
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="16" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="Post pending orders to production (UIND)"
FontSize="18"
Foreground="{StaticResource PrimaryText}"
VerticalAlignment="Center"
Margin="4,0,0,0" />
<Button Grid.Column="2"
Content="{Binding PostButtonText}"
Command="{Binding PostDataNowCommand}"
Style="{StaticResource PrimaryButtonStyle}"
MinWidth="200"
IsEnabled="{Binding CanPostNow}" />
</Grid>
<!-- 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>