По просьбе владельца («фон мрачный — сделай светлее, стильнее, удобнее»). - Дизайн-система на токенах: Styles/Tokens.axaml (ThemeDictionaries Light/Dark) + Styles/PosStyles.axaml (карточки/кнопки/чипы/клавиши/сегменты). RequestedThemeVariant=Light. Палитра: фон #F4F6F5, карточки белые, бренд-зелёный #16A34A, опасное — красный контур, предупреждение — янтарь. Inter, крупная иерархия, скругления 12–14, мягкие тени, сетка 8px. - Экран продажи: белая верхняя полоса (лого/точка/кассир + чипы смены и связи), поиск со скан-иконкой, корзина-карточки со степпером [−]N[+] и удалением, скидка в строке зелёным, пустая корзина-заглушка, правая карточка чека с крупным зелёным ИТОГО и «Оплатить · F12», вторичные кнопки-контуры, капсулы горячих клавиш. - Оплата (светлое модальное): сегменты Наличные/Карта/Смешанная, быстрые суммы, цифровая клавиатура, крупная «Сдача». - Вход (логин + PIN-пад), смена/Z-отчёт (разница цветом), возврат (степперы) — в том же стиле. - Кнопки ≥48px, клавиши крупные. Скорость не ухудшилась (старт 149мс, скан 11мс, поиск 33мс). --uitest OK, 43 unit зелёные. Галерея: разделы «Стало»/«Было». Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
70 lines
6.4 KiB
XML
70 lines
6.4 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||
xmlns:vm="clr-namespace:foodmarket.Pos.ViewModels"
|
||
x:Class="foodmarket.Pos.Views.LoginView"
|
||
x:DataType="vm:LoginViewModel">
|
||
<Grid Background="{DynamicResource PosBg}">
|
||
<Border Classes="card" Width="440" Padding="28" VerticalAlignment="Center" HorizontalAlignment="Center" CornerRadius="18">
|
||
<StackPanel Spacing="16">
|
||
<StackPanel Spacing="4" HorizontalAlignment="Center">
|
||
<Border Background="{DynamicResource PosBrand}" CornerRadius="12" Width="48" Height="48" HorizontalAlignment="Center">
|
||
<TextBlock Text="FM" Foreground="White" FontWeight="Bold" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||
</Border>
|
||
<TextBlock Text="Food Market · Касса" Foreground="{DynamicResource PosText}" FontWeight="Bold" FontSize="18" HorizontalAlignment="Center" Margin="0,8,0,0"/>
|
||
<TextBlock Text="Вход кассира" Foreground="{DynamicResource PosTextMuted}" FontSize="14" HorizontalAlignment="Center"/>
|
||
</StackPanel>
|
||
|
||
<!-- PIN -->
|
||
<StackPanel Spacing="12" IsVisible="{Binding PinMode}">
|
||
<Border Background="{DynamicResource PosSubtle}" CornerRadius="12" Height="56">
|
||
<TextBlock Text="{Binding PinMasked}" Foreground="{DynamicResource PosText}" FontSize="30" LetterSpacing="8" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||
</Border>
|
||
<TextBlock Text="{Binding Error}" Foreground="{DynamicResource PosDanger}" TextWrapping="Wrap" HorizontalAlignment="Center" IsVisible="{Binding Error, Converter={x:Static ObjectConverters.IsNotNull}}"/>
|
||
<Grid ColumnDefinitions="*,*,*" RowDefinitions="Auto,Auto,Auto,Auto">
|
||
<Button Grid.Row="0" Grid.Column="0" Classes="key" Margin="4" Height="58" Content="1" Command="{Binding PinDigitCommand}" CommandParameter="1"/>
|
||
<Button Grid.Row="0" Grid.Column="1" Classes="key" Margin="4" Height="58" Content="2" Command="{Binding PinDigitCommand}" CommandParameter="2"/>
|
||
<Button Grid.Row="0" Grid.Column="2" Classes="key" Margin="4" Height="58" Content="3" Command="{Binding PinDigitCommand}" CommandParameter="3"/>
|
||
<Button Grid.Row="1" Grid.Column="0" Classes="key" Margin="4" Height="58" Content="4" Command="{Binding PinDigitCommand}" CommandParameter="4"/>
|
||
<Button Grid.Row="1" Grid.Column="1" Classes="key" Margin="4" Height="58" Content="5" Command="{Binding PinDigitCommand}" CommandParameter="5"/>
|
||
<Button Grid.Row="1" Grid.Column="2" Classes="key" Margin="4" Height="58" Content="6" Command="{Binding PinDigitCommand}" CommandParameter="6"/>
|
||
<Button Grid.Row="2" Grid.Column="0" Classes="key" Margin="4" Height="58" Content="7" Command="{Binding PinDigitCommand}" CommandParameter="7"/>
|
||
<Button Grid.Row="2" Grid.Column="1" Classes="key" Margin="4" Height="58" Content="8" Command="{Binding PinDigitCommand}" CommandParameter="8"/>
|
||
<Button Grid.Row="2" Grid.Column="2" Classes="key" Margin="4" Height="58" Content="9" Command="{Binding PinDigitCommand}" CommandParameter="9"/>
|
||
<Button Grid.Row="3" Grid.Column="0" Classes="key" Margin="4" Height="58" FontSize="18" Content="⌫" Command="{Binding PinBackCommand}"/>
|
||
<Button Grid.Row="3" Grid.Column="1" Classes="key" Margin="4" Height="58" Content="0" Command="{Binding PinDigitCommand}" CommandParameter="0"/>
|
||
<Button Grid.Row="3" Grid.Column="2" Classes="key primary" Margin="4" Height="58" FontSize="17" Content="Войти" Command="{Binding PinLoginCommand}" IsEnabled="{Binding !Busy}"/>
|
||
</Grid>
|
||
<Button Classes="pos ghost" HorizontalAlignment="Stretch" Height="42" FontSize="13" Content="Вход по логину и паролю" Command="{Binding UsePasswordCommand}"/>
|
||
</StackPanel>
|
||
|
||
<!-- Логин/пароль -->
|
||
<StackPanel Spacing="14" IsVisible="{Binding !PinMode}">
|
||
<StackPanel Spacing="4">
|
||
<TextBlock Text="Адрес сервера" Foreground="{DynamicResource PosTextMuted}" FontSize="13"/>
|
||
<TextBox Classes="pos" Text="{Binding ServerUrl}" FontSize="15"/>
|
||
</StackPanel>
|
||
<StackPanel Spacing="4">
|
||
<TextBlock Text="Логин кассира" Foreground="{DynamicResource PosTextMuted}" FontSize="13"/>
|
||
<TextBox Classes="pos" Text="{Binding Username}" FontSize="17"/>
|
||
</StackPanel>
|
||
<StackPanel Spacing="4">
|
||
<TextBlock Text="PIN / пароль" Foreground="{DynamicResource PosTextMuted}" FontSize="13"/>
|
||
<TextBox Classes="pos" Text="{Binding Pin}" PasswordChar="●" FontSize="17"/>
|
||
</StackPanel>
|
||
<TextBlock Text="{Binding Error}" Foreground="{DynamicResource PosDanger}" TextWrapping="Wrap" IsVisible="{Binding Error, Converter={x:Static ObjectConverters.IsNotNull}}"/>
|
||
<Button Classes="pos primary" HorizontalAlignment="Stretch" Height="54" FontSize="18" Content="Войти" Command="{Binding LoginCommand}" IsDefault="True" IsEnabled="{Binding !Busy}" IsVisible="{Binding !RequirePointSelection}"/>
|
||
|
||
<StackPanel Spacing="8" IsVisible="{Binding RequirePointSelection}">
|
||
<TextBlock Text="Регистрация кассы — выберите точку продаж:" Foreground="{DynamicResource PosText}" FontSize="14"/>
|
||
<ComboBox ItemsSource="{Binding Points}" SelectedItem="{Binding SelectedPoint}" HorizontalAlignment="Stretch" FontSize="15"/>
|
||
<Button Classes="pos primary" HorizontalAlignment="Stretch" Height="50" Content="Зарегистрировать на этой точке" Command="{Binding ConfirmPointCommand}"/>
|
||
</StackPanel>
|
||
|
||
<Button Classes="pos ghost" HorizontalAlignment="Stretch" Height="40" FontSize="13" Content="Быстрый вход по PIN" Command="{Binding UsePinCommand}" IsVisible="{Binding DeviceRegistered}"/>
|
||
<Button Classes="pos ghost" HorizontalAlignment="Stretch" Height="38" FontSize="12.5" Content="Сменить точку продаж (админ)" Command="{Binding ResetDeviceCommand}" ToolTip.Tip="Сбросить регистрацию устройства. Новую точку выберет только администратор."/>
|
||
</StackPanel>
|
||
</StackPanel>
|
||
</Border>
|
||
</Grid>
|
||
</UserControl>
|