krona-staff/apps/KronaStaffTerminal/MainPage.xaml
Ochenstarik 827d321a1a
Some checks failed
ci / verify (push) Has been cancelled
feat(terminal): add secure release updates and installer
2026-09-19 02:08:26 +07:00

256 lines
18 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="utf-8"?>
<Page
x:Class="KronaStaffTerminal.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="using:KronaStaffTerminal.Models"
Loaded="Page_Loaded"
Unloaded="Page_Unloaded"
mc:Ignorable="d">
<Grid Padding="24,16,24,24"
RowSpacing="12"
Background="{ThemeResource KronaAppBackgroundBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<InfoBar x:Name="StatusBar"
IsOpen="True"
IsClosable="False"
Severity="Informational"
Title="Подключение"
Message="Запуск терминала…"/>
<InfoBar x:Name="UpdateBar"
Grid.Row="1"
Margin="0,0,0,4"
IsOpen="False"
IsClosable="True"
Severity="Informational"
Title="Доступно обновление">
<InfoBar.ActionButton>
<Button Content="Обновить"
Click="InstallUpdate_Click"/>
</InfoBar.ActionButton>
</InfoBar>
<TabView x:Name="MainTabs"
Grid.Row="2"
Background="{ThemeResource KronaWorkspaceBrush}"
IsAddTabButtonVisible="False"
SelectionChanged="MainTabs_SelectionChanged">
<TabViewItem x:Name="TerminalTab" Header="Терминал" IsClosable="False">
<Grid Padding="4,16,4,4" ColumnSpacing="24">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Border Margin="8"
Padding="28"
Background="{ThemeResource KronaSurfaceBrush}"
BorderBrush="{ThemeResource KronaBorderBrush}"
BorderThickness="1"
CornerRadius="{StaticResource KronaRadiusLarge}">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Spacing="14">
<Grid Width="220" Height="220">
<Ellipse Fill="{ThemeResource KronaGoldSoftBrush}" />
<Image Margin="18"
Source="Assets/TrushenkoLogo.png"
Stretch="Uniform"
AutomationProperties.Name="Логотип Трушенко" />
<Border Width="54"
Height="54"
Margin="0,0,4,4"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Background="{ThemeResource KronaPrimaryBrush}"
CornerRadius="27">
<FontIcon Glyph="&#xE928;"
FontSize="27"
Foreground="{ThemeResource KronaTextInverseBrush}" />
</Border>
</Grid>
<TextBlock Text="Приложите палец"
Foreground="{ThemeResource KronaTextPrimaryBrush}"
Style="{StaticResource TitleTextBlockStyle}"
HorizontalAlignment="Center"/>
<TextBlock x:Name="TerminalMessage"
MaxWidth="360"
Foreground="{ThemeResource KronaTextSecondaryBrush}"
Text="Ожидание сканирования"
TextWrapping="Wrap"
TextAlignment="Center"/>
</StackPanel>
</Border>
<Grid Grid.Column="1" RowSpacing="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid ColumnSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="Последние отметки"
Foreground="{ThemeResource KronaTextPrimaryBrush}"
Style="{StaticResource SubtitleTextBlockStyle}"/>
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="8">
<Button Content="Экспорт CSV" Click="ExportAttendance_Click" />
<Button Content="Очистить журнал" Click="ClearAttendance_Click" />
</StackPanel>
</Grid>
<ListView x:Name="AttendanceList"
Grid.Row="1"
Background="{ThemeResource KronaRaisedSurfaceBrush}"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:AttendanceRecord">
<Grid Padding="4,10" ColumnSpacing="16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="90"/>
<ColumnDefinition Width="160"/>
<ColumnDefinition Width="120"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Bind EmployeeName}" FontWeight="SemiBold"/>
<TextBlock Grid.Column="1" Text="{x:Bind EventType}" FontWeight="SemiBold"/>
<TextBlock Grid.Column="2" Text="{x:Bind LocalTime}"/>
<TextBlock Grid.Column="3" Text="{x:Bind DeliveryStatus}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Grid>
</TabViewItem>
<TabViewItem x:Name="EmployeesTab" Header="Сотрудники" IsClosable="False">
<Grid Padding="4,16,4,4" RowSpacing="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Добавление и регистрация сотрудников" Foreground="{ThemeResource KronaTextPrimaryBrush}" Style="{StaticResource SubtitleTextBlockStyle}"/>
<CommandBar Grid.Row="1" Background="{ThemeResource KronaSurfaceBrush}" DefaultLabelPosition="Right">
<AppBarButton Icon="Add" Label="Добавить" Click="AddEmployee_Click"/>
<AppBarButton Icon="Edit" Label="Редактировать" Click="EditEmployee_Click"/>
<AppBarButton Icon="Contact" Label="Добавить отпечаток" Click="RegisterFingerprint_Click"/>
<AppBarButton Icon="Cancel" Label="Отменить регистрацию" Click="CancelRegistration_Click"/>
<AppBarButton Label="Удалить отпечатки" Click="DeleteFingerprints_Click">
<AppBarButton.Icon>
<FontIcon Glyph="&#xE928;" />
</AppBarButton.Icon>
</AppBarButton>
<AppBarButton Icon="Permissions" Label="Права администратора" Click="ToggleAdministrator_Click"/>
<AppBarButton Icon="Delete" Label="Удалить" Click="DeleteEmployee_Click"/>
<AppBarSeparator />
<AppBarButton Label="Заблокировать" Click="LogoutAdmin_Click">
<AppBarButton.Icon>
<FontIcon Glyph="&#xE72E;" />
</AppBarButton.Icon>
</AppBarButton>
</CommandBar>
<Grid Grid.Row="2" ColumnSpacing="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Spacing="10">
<TextBox x:Name="PersonnelNumberBox" Header="Табельный номер" PlaceholderText="Например, 001" AutomationProperties.Name="Табельный номер"/>
<TextBox x:Name="EmployeeNameBox" Header="Имя сотрудника" PlaceholderText="Иван Петров" AutomationProperties.Name="Имя сотрудника"/>
<TextBox x:Name="PositionBox" Header="Должность" PlaceholderText="Например, менеджер" AutomationProperties.Name="Должность"/>
<ComboBox x:Name="GenderComboBox" Header="Пол" SelectedIndex="0">
<ComboBoxItem Content="Не указан" />
<ComboBoxItem Content="Мужской" />
<ComboBoxItem Content="Женский" />
</ComboBox>
<CheckBox x:Name="AdministratorCheckBox" Content="Администратор терминала"/>
<TextBlock Text="Выберите сотрудника справа и нажмите «Добавить отпечаток». Для каждого нового пальца повторите регистрацию из трёх сканов." TextWrapping="Wrap" Opacity="0.75"/>
</StackPanel>
<ListView x:Name="EmployeesList" Grid.Column="1" Background="{ThemeResource KronaRaisedSurfaceBrush}" SelectionMode="Single" SelectionChanged="EmployeesList_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:EmployeeRecord">
<Grid Padding="4,10" ColumnSpacing="14">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="130"/>
<ColumnDefinition Width="90"/>
<ColumnDefinition Width="130"/>
<ColumnDefinition Width="170"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Bind PersonnelNumber}"/>
<TextBlock Grid.Column="1" Text="{x:Bind DisplayName}" FontWeight="SemiBold"/>
<TextBlock Grid.Column="2" Text="{x:Bind Position}"/>
<TextBlock Grid.Column="3" Text="{x:Bind GenderDisplay}"/>
<TextBlock Grid.Column="4" Text="{x:Bind AccessStatus}"/>
<TextBlock Grid.Column="5" Text="{x:Bind FingerprintStatus}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Grid>
</TabViewItem>
<TabViewItem x:Name="SettingsTab" Header="Уведомления и сканер" IsClosable="False">
<ScrollViewer>
<StackPanel Padding="4,16,20,24" Spacing="14" MaxWidth="720" HorizontalAlignment="Left">
<TextBlock Text="Сканер" Foreground="{ThemeResource KronaTextPrimaryBrush}" Style="{StaticResource SubtitleTextBlockStyle}"/>
<ComboBox x:Name="ReaderCombo" Header="Используемое устройство" MinWidth="320"/>
<ToggleSwitch x:Name="StartWithWindowsSwitch" Header="Автозагрузка" OffContent="Выключена" OnContent="Запускать вместе с Windows"/>
<NumberBox x:Name="DuplicateGuardBox" Header="Защита от повторного скана, секунд" Minimum="10" Maximum="3600" SpinButtonPlacementMode="Compact"/>
<NumberBox x:Name="MaximumShiftHoursBox" Header="Максимальная длительность смены, часов" Minimum="1" Maximum="48" SpinButtonPlacementMode="Compact"/>
<ToggleSwitch x:Name="ShowEmployeeNamesSwitch" Header="Имена в публичном журнале терминала" OffContent="Скрыты" OnContent="Показывать"/>
<PasswordBox x:Name="NewAdminPinBox" Header="Новый PIN администратора" PasswordRevealMode="Peek"/>
<Button Content="Установить новый PIN" HorizontalAlignment="Left" Click="SetAdminPin_Click"/>
<Border Height="1" Background="{ThemeResource DividerStrokeColorDefaultBrush}"/>
<ToggleSwitch x:Name="TelegramEnabledSwitch" Header="Telegram" OffContent="Выключен" OnContent="Включён"/>
<PasswordBox x:Name="TelegramTokenBox" Header="Токен Telegram-бота" PasswordRevealMode="Peek"/>
<TextBox x:Name="TelegramChatBox" Header="Chat ID Telegram"/>
<Border Height="1" Background="{ThemeResource DividerStrokeColorDefaultBrush}"/>
<ToggleSwitch x:Name="MaxEnabledSwitch" Header="MAX" OffContent="Выключен" OnContent="Включён"/>
<PasswordBox x:Name="MaxTokenBox" Header="Токен MAX-бота" PasswordRevealMode="Peek"/>
<TextBox x:Name="MaxChatBox" Header="Chat ID MAX"/>
<Border Height="1" Background="{ThemeResource DividerStrokeColorDefaultBrush}"/>
<TextBlock Text="Обновления программы" Foreground="{ThemeResource KronaTextPrimaryBrush}" Style="{StaticResource SubtitleTextBlockStyle}"/>
<TextBlock x:Name="CurrentVersionText" Opacity="0.75"/>
<ToggleSwitch x:Name="UpdateChecksSwitch"
Header="Автоматическая проверка"
OffContent="Выключена"
OnContent="Проверять при запуске и каждые 6 часов"/>
<TextBox x:Name="UpdateFeedBox"
Header="Адрес канала обновлений"
IsReadOnly="True"
PlaceholderText="HTTPS-адрес последнего релиза"/>
<PasswordBox x:Name="UpdateTokenBox"
Header="Токен чтения приватного репозитория"
PasswordRevealMode="Peek"/>
<TextBlock Text="Токен нужен только пока обновления берутся из приватного Forgejo. Позже этот канал можно заменить Бизнес Платформой без изменения установщика."
TextWrapping="Wrap"
Opacity="0.7"/>
<Button Content="Проверить обновления"
HorizontalAlignment="Left"
Click="CheckForUpdates_Click"/>
<StackPanel Orientation="Horizontal" Spacing="10">
<Button Content="Сохранить настройки"
Background="{ThemeResource KronaPrimaryBrush}"
Foreground="{ThemeResource KronaTextInverseBrush}"
Click="SaveSettings_Click"/>
<Button Content="Отправить тест" Click="TestNotification_Click"/>
<Button Content="Заблокировать" Click="LogoutAdmin_Click"/>
</StackPanel>
<TextBlock Text="Токены, сотрудники и шаблоны отпечатков хранятся в зашифрованном хранилище текущей учётной записи Windows." TextWrapping="Wrap" Opacity="0.7"/>
</StackPanel>
</ScrollViewer>
</TabViewItem>
</TabView>
</Grid>
</Page>