Utopia-Canteen-System/UtopiaCanteen.Client/Views/ClientSettingsView.xaml

364 lines
26 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="UtopiaCanteen.Client.Views.ClientSettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
<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="OrangeAccent" Color="#ED8936"/>
<SolidColorBrush x:Key="CardHeaderBg" Color="#F7FAFC"/>
<Style x:Key="SectionCardStyle" TargetType="Border">
<Setter Property="Background" Value="{StaticResource CardBackground}"/>
<Setter Property="CornerRadius" Value="12"/>
<Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="24"/>
<Setter Property="Margin" Value="0,0,0,16"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
<Style x:Key="ModernTextBoxStyle" TargetType="TextBox">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="MinHeight" Value="48"/>
<Setter Property="Background" Value="White"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="#E2E8F0"/>
<Setter Property="Foreground" Value="#0A1628"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Padding" Value="14,0"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
<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="15"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Padding" Value="20,10"/>
<Setter Property="MinHeight" Value="42"/>
<Setter Property="Cursor" Value="Hand"/>
</Style>
<Style x:Key="OutlineButtonStyle" TargetType="Button">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="{StaticResource PrimaryText}"/>
<Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Padding" Value="20,10"/>
<Setter Property="MinHeight" Value="42"/>
<Setter Property="Cursor" Value="Hand"/>
</Style>
<Style x:Key="SyncSubCardStyle" TargetType="Border">
<Setter Property="Background" Value="{StaticResource CardHeaderBg}"/>
<Setter Property="CornerRadius" Value="10"/>
<Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="20"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</UserControl.Resources>
<Grid Background="{StaticResource AppBackground}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollViewer Grid.Row="0"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Padding="32,24,32,16">
<Grid HorizontalAlignment="Stretch"
Width="{Binding ViewportWidth, RelativeSource={RelativeSource AncestorType=ScrollViewer}}"
MinWidth="320">
<StackPanel HorizontalAlignment="Stretch">
<!-- Page header -->
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Border Width="48" Height="48" Background="#E6F4F3" CornerRadius="24" Margin="0,0,16,0">
<Viewbox Margin="10">
<Canvas Width="24" Height="24">
<Path Data="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11.03L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.26C16.04,5.86 15.48,5.51 14.87,5.23L14.5,2.58C14.46,2.34 14.25,2.17 14,2.17H10C9.75,2.17 9.54,2.34 9.5,2.58L9.13,5.23C8.52,5.51 7.96,5.86 7.44,6.26L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.22,8.95 2.27,9.22 2.46,9.37L4.57,11.03C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.22,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.74C7.96,18.14 8.52,18.49 9.13,18.77L9.5,21.42C9.54,21.66 9.75,21.83 10,21.83H14C14.25,21.83 14.46,21.66 14.5,21.42L14.87,18.77C15.48,18.49 16.04,18.14 16.56,17.74L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"
Fill="{StaticResource PrimaryAccent}" Stretch="Uniform"/>
</Canvas>
</Viewbox>
</Border>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="Settings" FontSize="32" FontWeight="Bold" Foreground="{StaticResource PrimaryText}"/>
<TextBlock Text="Configure scanning, access, connectivity, and sync settings."
FontSize="15" Foreground="{StaticResource MutedText}" Margin="0,4,0,0"/>
</StackPanel>
</StackPanel>
<!-- 1. Scan Interval -->
<Border Style="{StaticResource SectionCardStyle}">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,12">
<Border Width="36" Height="36" Background="#E6F4F3" CornerRadius="18" Margin="0,0,12,0">
<TextBlock Text="&#xE121;" FontFamily="Segoe MDL2 Assets" FontSize="16"
Foreground="{StaticResource PrimaryAccent}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="Scan Interval" FontSize="20" FontWeight="Bold" Foreground="{StaticResource PrimaryText}"/>
<TextBlock Text="Set the minimum time between scans to prevent duplicates."
FontSize="14" Foreground="{StaticResource MutedText}"/>
</StackPanel>
</StackPanel>
<Grid Margin="0,8,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/><ColumnDefinition Width="12"/>
<ColumnDefinition Width="*"/><ColumnDefinition Width="12"/>
<ColumnDefinition Width="*"/><ColumnDefinition Width="12"/>
<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>
<StackPanel Orientation="Horizontal" Margin="0,12,0,0">
<TextBlock Text="&#xE946;" FontFamily="Segoe MDL2 Assets" FontSize="14"
Foreground="{StaticResource MutedText}" Margin="0,2,8,0"/>
<TextBlock Text="The minimum time between scans to prevent duplicates. At least 1 second required."
FontSize="13" Foreground="{StaticResource MutedText}" TextWrapping="Wrap"/>
</StackPanel>
</StackPanel>
</Border>
<!-- 2. Admin Access -->
<Border Style="{StaticResource SectionCardStyle}">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,12">
<Border Width="36" Height="36" Background="#E6F4F3" CornerRadius="18" Margin="0,0,12,0">
<TextBlock Text="&#xE77B;" FontFamily="Segoe MDL2 Assets" FontSize="16"
Foreground="{StaticResource PrimaryAccent}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<TextBlock Text="Admin Access" FontSize="20" FontWeight="Bold" Foreground="{StaticResource PrimaryText}" VerticalAlignment="Center"/>
</StackPanel>
<TextBlock Text="Admin Employee ID" FontSize="14" FontWeight="SemiBold" Foreground="{StaticResource PrimaryText}"/>
<TextBox Text="{Binding AdminCardId, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" Margin="0,8,0,4"/>
<TextBlock Text="Card ID with admin access to settings." FontSize="13" Foreground="{StaticResource MutedText}"/>
</StackPanel>
</Border>
<!-- 3. Application Mode & Connectivity -->
<Border Style="{StaticResource SectionCardStyle}">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,12">
<Border Width="36" Height="36" Background="#E6F4F3" CornerRadius="18" Margin="0,0,12,0">
<TextBlock Text="&#xE968;" FontFamily="Segoe MDL2 Assets" FontSize="16"
Foreground="{StaticResource PrimaryAccent}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="Application Mode &amp; Connectivity" FontSize="20" FontWeight="Bold" Foreground="{StaticResource PrimaryText}"/>
<TextBlock Text="Configure how this application connects to servers."
FontSize="14" Foreground="{StaticResource MutedText}"/>
</StackPanel>
</StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0">
<TextBlock Text="Application Mode" FontSize="14" FontWeight="SemiBold" Foreground="{StaticResource PrimaryText}"/>
<TextBox Text="{Binding ApplicationModeDisplay}" IsReadOnly="True" IsTabStop="False"
Style="{StaticResource ModernTextBoxStyle}" Margin="0,8,0,4" Background="#F8FAFC"/>
<TextBlock Text="Client: this PC sends scans to the central backend server."
FontSize="12" Foreground="{StaticResource MutedText}" TextWrapping="Wrap"/>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="2">
<TextBlock Text="Backend Server Base URL" FontSize="14" FontWeight="SemiBold" Foreground="{StaticResource PrimaryText}"/>
<TextBox Text="{Binding BackendBaseUrl, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" Margin="0,8,0,4"/>
<TextBlock Text="Example: http://192.168.1.10:5000" FontSize="12" Foreground="{StaticResource MutedText}"/>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="4">
<TextBlock Text="Device ID" FontSize="14" FontWeight="SemiBold" Foreground="{StaticResource PrimaryText}"/>
<TextBox Text="{Binding DeviceId, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" Margin="0,8,0,4"/>
<TextBlock Text="Identifies this scanner PC in scan records." FontSize="12" Foreground="{StaticResource MutedText}"/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Margin="0,16,0,0">
<TextBlock Text="Site ID" FontSize="14" FontWeight="SemiBold" Foreground="{StaticResource PrimaryText}"/>
<TextBox Text="{Binding SiteId, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource ModernTextBoxStyle}" Margin="0,8,0,4" MaxWidth="480" HorizontalAlignment="Left"/>
<TextBlock Text="Canteen location site code sent with each scan." FontSize="12" Foreground="{StaticResource MutedText}"/>
</StackPanel>
</Grid>
<Border Margin="0,16,0,0" Padding="12" CornerRadius="8" Background="#EDF2F7">
<StackPanel Orientation="Horizontal">
<Ellipse Width="10" Height="10" Margin="0,4,10,0" VerticalAlignment="Top">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="{StaticResource ErrorBrush}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsBackendOnline}" Value="True">
<Setter Property="Fill" Value="{StaticResource SuccessBrush}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<TextBlock Text="{Binding BackendHealthDisplay}" FontSize="13" Foreground="{StaticResource PrimaryText}" TextWrapping="Wrap"/>
</StackPanel>
</Border>
</StackPanel>
</Border>
<!-- 4. Data Sync -->
<Border Style="{StaticResource SectionCardStyle}" Margin="0,0,0,8">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,16">
<Border Width="36" Height="36" Background="#E6F4F3" CornerRadius="18" Margin="0,0,12,0">
<TextBlock Text="&#xE895;" FontFamily="Segoe MDL2 Assets" FontSize="16"
Foreground="{StaticResource PrimaryAccent}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="Data Sync" FontSize="20" FontWeight="Bold" Foreground="{StaticResource PrimaryText}"/>
<TextBlock Text="Keep your offline data up to date and send transactions to production."
FontSize="14" Foreground="{StaticResource MutedText}"/>
</StackPanel>
</StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/><ColumnDefinition Width="16"/><ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Download Offline Data -->
<Border Grid.Column="0" Style="{StaticResource SyncSubCardStyle}">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<TextBlock Text="&#xE896;" FontFamily="Segoe MDL2 Assets" FontSize="18"
Foreground="{StaticResource PrimaryAccent}" Margin="0,0,8,0"/>
<TextBlock Text="Download Offline Data" FontSize="17" FontWeight="SemiBold" Foreground="{StaticResource PrimaryText}"/>
</StackPanel>
<TextBlock Text="Download employee RFID tags, meal schedules, and menu data for offline scanning."
FontSize="13" Foreground="{StaticResource MutedText}" TextWrapping="Wrap" Margin="0,0,0,16"/>
<Button Content="{Binding SyncCacheButtonText}"
Command="{Binding SyncEmployeeAndMenuCacheNowCommand}"
Style="{StaticResource PrimaryButtonStyle}"
HorizontalAlignment="Left"
IsEnabled="{Binding CanSyncCacheNow}"/>
</StackPanel>
</Border>
<!-- Post Data to Production -->
<Border Grid.Column="2" Style="{StaticResource SyncSubCardStyle}">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<TextBlock Text="&#xE898;" FontFamily="Segoe MDL2 Assets" FontSize="18"
Foreground="{StaticResource OrangeAccent}" Margin="0,0,8,0"/>
<TextBlock Text="Post Data to Production" FontSize="17" FontWeight="SemiBold" Foreground="{StaticResource PrimaryText}"/>
</StackPanel>
<TextBlock Text="Post captured scan and transaction data to the production server."
FontSize="13" Foreground="{StaticResource MutedText}" TextWrapping="Wrap" Margin="0,0,0,16"/>
<Button Content="{Binding PostButtonText}"
Command="{Binding PostDataNowCommand}"
Style="{StaticResource PrimaryButtonStyle}"
HorizontalAlignment="Left"
IsEnabled="{Binding CanPostNow}"/>
</StackPanel>
</Border>
</Grid>
<TextBlock Text="{Binding LastEmployeeRfidCacheSyncDisplay, StringFormat=Last employee RFID cache sync: {0}}"
FontSize="13" Foreground="{StaticResource MutedText}" Margin="0,16,0,4"/>
<TextBlock Text="{Binding LastMealMenuCacheSyncDisplay, StringFormat=Last meal/menu cache sync: {0}}"
FontSize="13" Foreground="{StaticResource MutedText}"/>
</StackPanel>
</Border>
<!-- Status message -->
<Border Padding="14" CornerRadius="8" Margin="0,0,0,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 IsError}" Value="True">
<Setter Property="Background" Value="#fee2e2"/>
<Setter Property="BorderBrush" Value="#fca5a5"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="{Binding SaveMessage}" FontSize="15" FontWeight="SemiBold" TextWrapping="Wrap">
<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>
</Border>
</StackPanel>
</Grid>
</ScrollViewer>
<!-- Sticky bottom action bar (full width) -->
<Border Grid.Row="1" Background="#F9FBFB" BorderBrush="{StaticResource BorderBrush}" BorderThickness="0,1,0,0" Padding="32,16">
<Grid HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Command="{Binding OpenMealSchedulesCommand}" Style="{StaticResource OutlineButtonStyle}" MinWidth="160" Margin="0,0,12,0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="&#xE787;" FontFamily="Segoe MDL2 Assets" FontSize="14" Margin="0,0,8,0" VerticalAlignment="Center"/>
<TextBlock Text="Meal Schedules" VerticalAlignment="Center"/>
</StackPanel>
</Button>
<Button Content="Back" Command="{Binding BackCommand}" Style="{StaticResource OutlineButtonStyle}" MinWidth="100" Margin="0,0,12,0"/>
<Button Command="{Binding SaveCommand}" Style="{StaticResource PrimaryButtonStyle}" MinWidth="100">
<StackPanel Orientation="Horizontal">
<TextBlock Text="&#xE74E;" FontFamily="Segoe MDL2 Assets" FontSize="14" Margin="0,0,8,0" VerticalAlignment="Center"/>
<TextBlock Text="Save" VerticalAlignment="Center"/>
</StackPanel>
</Button>
</StackPanel>
</Grid>
</Border>
</Grid>
</UserControl>