- Сервер: /api/me отдаёт retailPointIds (точки, к которым привязан сотрудник). - Касса: DeviceRegistration (чистая логика, 5 unit-тестов) — первый запуск: админ выбирает точку из списка активных (сохраняется на устройстве, kv); кассир на незарегистрированном устройстве → «обратитесь к администратору»; кассир, не привязанный к точке устройства → «вы не привязаны к этой кассе»; админ работает на любой точке. Смена точки — кнопка-сброс (новую выберет только админ). Экран входа: шаг выбора точки (ComboBox активных точек). - Заменяет прежний «берётся первая активная» (ошибка при двух точках). - Тесты: unit (5 решений гейта) + integration (/api/me retailPointIds кассира). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
40 lines
2.9 KiB
XML
40 lines
2.9 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="#0f172a">
|
|
<Border Background="#1e293b" CornerRadius="12" Width="440" Padding="28" VerticalAlignment="Center" HorizontalAlignment="Center">
|
|
<StackPanel Spacing="14">
|
|
<TextBlock Text="FOOD MARKET" Foreground="#22c55e" FontWeight="Bold" FontSize="22" HorizontalAlignment="Center"/>
|
|
<TextBlock Text="Вход кассира" Foreground="#f8fafc" FontSize="18" HorizontalAlignment="Center"/>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Text="Адрес сервера" Foreground="#94a3b8"/>
|
|
<TextBox Classes="pos" Text="{Binding ServerUrl}" FontSize="16"/>
|
|
</StackPanel>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Text="Логин кассира" Foreground="#94a3b8"/>
|
|
<TextBox Classes="pos" Text="{Binding Username}" FontSize="18"/>
|
|
</StackPanel>
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Text="PIN / пароль" Foreground="#94a3b8"/>
|
|
<TextBox Classes="pos" Text="{Binding Pin}" PasswordChar="●" FontSize="18"/>
|
|
</StackPanel>
|
|
<TextBlock Text="{Binding Error}" Foreground="#fca5a5" TextWrapping="Wrap" IsVisible="{Binding Error, Converter={x:Static ObjectConverters.IsNotNull}}"/>
|
|
<Button Classes="pos primary" HorizontalAlignment="Stretch" Height="56" FontSize="18" Content="Войти" Command="{Binding LoginCommand}" IsDefault="True" IsEnabled="{Binding !Busy}" IsVisible="{Binding !RequirePointSelection}"/>
|
|
|
|
<!-- Регистрация устройства: выбор точки продаж (только администратор) -->
|
|
<StackPanel Spacing="8" IsVisible="{Binding RequirePointSelection}">
|
|
<TextBlock Text="Регистрация кассы — выберите точку продаж:" Foreground="#f8fafc"/>
|
|
<ComboBox ItemsSource="{Binding Points}" SelectedItem="{Binding SelectedPoint}" HorizontalAlignment="Stretch" FontSize="16"/>
|
|
<Button Classes="pos primary" HorizontalAlignment="Stretch" Height="52" Content="Зарегистрировать на этой точке" Command="{Binding ConfirmPointCommand}"/>
|
|
</StackPanel>
|
|
|
|
<Button Classes="pos" HorizontalAlignment="Stretch" Height="40" FontSize="13" Command="{Binding ResetDeviceCommand}" ToolTip.Tip="Сбросить регистрацию устройства. Новую точку выберет только администратор.">
|
|
<TextBlock Text="Сменить точку продаж (админ)" TextWrapping="Wrap" TextAlignment="Center"/>
|
|
</Button>
|
|
</StackPanel>
|
|
</Border>
|
|
</Grid>
|
|
</UserControl>
|