Правки по замечаниям на windows11-sale.png (VM 1280×800 maximized — высоты меньше, чем в headless): 1. Адаптив правой панели по высоте (SaleView.axaml.cs, подписка на Bounds): уровни normal/compact/tiny — сжимаются отступы, ИТОГО, кнопки; скрывается блок «Последний чек»; ClipToBounds, чтобы ничего не уходило под полосу клавиш. 2. Шапка — Grid вместо StackPanel: чипы в отдельной колонке и не обрезаются; адаптив по ширине (MainWindow.axaml.cs): <1400 короткие чипы, <1100 без «Магазин…». BadgesCompact во VM переключает тексты ShiftBadge/QueueBadge. 3. Иконка «Выплата» (одиночная горизонталь) схлопывалась при Stretch=Uniform → Stretch=None; «Внесение» выровнял так же. 4. Hover строки корзины — светлый #F7FBF8 вместо тёмного из темы. 5. Плитки избранного — Grid *,Auto: цена прибита к низу, у всех на одной линии. 6. Полоса горячих клавиш — выравнивание влево (как в макете). 7. --density: рендер экрана продажи в 1280×720/800, 1366×768, 1920×1080 для проверки. --uitest OK, 82 unit зелёные, smoke OK, скорость не хуже. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
202 lines
17 KiB
XML
202 lines
17 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.SaleView"
|
||
x:DataType="vm:SaleViewModel">
|
||
<Grid ColumnDefinitions="*,440" Background="{DynamicResource PosBg}">
|
||
|
||
<!-- ЛЕВО -->
|
||
<Grid Grid.Column="0" RowDefinitions="Auto,Auto,Auto,*" Margin="24,16,8,16">
|
||
|
||
<!-- Поиск / скан -->
|
||
<Border Grid.Row="0" Height="64" Background="{DynamicResource PosCard}" BorderBrush="{DynamicResource PosBrand}" BorderThickness="2" CornerRadius="14"
|
||
BoxShadow="0 0 0 4 #1F16A34A" Margin="0,0,0,16">
|
||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||
<Path Grid.Column="0" Width="24" Height="24" Margin="20,0,14,0" Stretch="Uniform" Stroke="{DynamicResource PosBrand}" StrokeThickness="2" StrokeLineCap="Round"
|
||
Data="M3 5v14M7 5v14M11 5v14M15 5v14M19 5v14"/>
|
||
<TextBox Grid.Column="1" BorderThickness="0" FontSize="19" Background="Transparent" VerticalContentAlignment="Center"
|
||
Watermark="Отсканируйте товар или начните вводить название" Text="{Binding ScanInput}">
|
||
<TextBox.KeyBindings><KeyBinding Gesture="Enter" Command="{Binding ScanCommand}"/></TextBox.KeyBindings>
|
||
</TextBox>
|
||
<Border Grid.Column="2" Classes="kbd" Margin="0,0,16,0"><TextBlock Text="F2"/></Border>
|
||
</Grid>
|
||
</Border>
|
||
|
||
<!-- Заголовок избранного -->
|
||
<Grid Grid.Row="1" ColumnDefinitions="*,Auto" Margin="0,0,0,12" IsVisible="{Binding HasFavorites}">
|
||
<TextBlock Text="ИЗБРАННОЕ" FontSize="15" FontWeight="Bold" Foreground="{DynamicResource PosTextMuted}" VerticalAlignment="Center"/>
|
||
<Button Grid.Column="1" Background="Transparent" BorderThickness="0" Padding="0" Command="{Binding ToggleFavoritesCommand}" HorizontalAlignment="Right">
|
||
<Panel>
|
||
<TextBlock FontSize="14" FontWeight="SemiBold" Foreground="{DynamicResource PosBrandDark}" Text="Скрыть ▴" IsVisible="{Binding FavoritesOpen}"/>
|
||
<TextBlock FontSize="14" FontWeight="SemiBold" Foreground="{DynamicResource PosBrandDark}" Text="Показать ▾" IsVisible="{Binding !FavoritesOpen}"/>
|
||
</Panel>
|
||
</Button>
|
||
</Grid>
|
||
|
||
<!-- Избранное -->
|
||
<ItemsControl Grid.Row="2" ItemsSource="{Binding Favorites}" Margin="0,0,0,16" IsVisible="{Binding FavoritesOpen}">
|
||
<ItemsControl.ItemsPanel><ItemsPanelTemplate><UniformGrid Columns="6"/></ItemsPanelTemplate></ItemsControl.ItemsPanel>
|
||
<ItemsControl.ItemTemplate>
|
||
<DataTemplate>
|
||
<Button Height="84" Margin="6" Padding="8,10" Background="{DynamicResource PosCard}" BorderBrush="{DynamicResource PosBorder}" BorderThickness="1" CornerRadius="12"
|
||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
|
||
Command="{Binding $parent[ItemsControl].((vm:SaleViewModel)DataContext).AddFavoriteCommand}" CommandParameter="{Binding}">
|
||
<Grid RowDefinitions="*,Auto">
|
||
<TextBlock Grid.Row="0" Text="{Binding Name}" FontSize="15" FontWeight="SemiBold" TextAlignment="Center" TextWrapping="Wrap" MaxLines="2" TextTrimming="CharacterEllipsis"
|
||
HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{DynamicResource PosText}"/>
|
||
<TextBlock Grid.Row="1" Text="{Binding PriceText}" FontSize="15" FontWeight="Bold" TextAlignment="Center" HorizontalAlignment="Center" Margin="0,4,0,0" Foreground="{DynamicResource PosBrandDark}"/>
|
||
</Grid>
|
||
</Button>
|
||
</DataTemplate>
|
||
</ItemsControl.ItemTemplate>
|
||
</ItemsControl>
|
||
|
||
<!-- Корзина -->
|
||
<Border Grid.Row="3" Background="{DynamicResource PosCard}" BorderBrush="{DynamicResource PosBorder}" BorderThickness="1" CornerRadius="14">
|
||
<Grid RowDefinitions="Auto,*">
|
||
<Border Grid.Row="0" Height="48" BorderBrush="{DynamicResource PosBorder}" BorderThickness="0,0,0,1">
|
||
<Grid ColumnDefinitions="*,200,160,56" Margin="20,0">
|
||
<TextBlock Text="Товар" Foreground="{DynamicResource PosTextMuted}" FontSize="14" FontWeight="SemiBold" VerticalAlignment="Center"/>
|
||
<TextBlock Grid.Column="1" Text="Количество" Foreground="{DynamicResource PosTextMuted}" FontSize="14" FontWeight="SemiBold" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||
<TextBlock Grid.Column="2" Text="Сумма" Foreground="{DynamicResource PosTextMuted}" FontSize="14" FontWeight="SemiBold" HorizontalAlignment="Right" VerticalAlignment="Center"/>
|
||
</Grid>
|
||
</Border>
|
||
|
||
<StackPanel Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" Spacing="10" IsVisible="{Binding IsCartEmpty}">
|
||
<Border Background="{DynamicResource PosSubtle}" CornerRadius="999" Width="72" Height="72">
|
||
<Path Width="34" Height="34" Stretch="Uniform" Stroke="{DynamicResource PosTextMuted}" StrokeThickness="1.6" StrokeLineCap="Round" StrokeJoin="Round"
|
||
Data="M6 6h15l-1.5 9h-12zM6 6l-2 -3M9 20a1 1 0 100 .01M18 20a1 1 0 100 .01"/>
|
||
</Border>
|
||
<TextBlock Text="Отсканируйте первый товар" Foreground="{DynamicResource PosTextMuted}" FontSize="16"/>
|
||
</StackPanel>
|
||
|
||
<ListBox Grid.Row="1" ItemsSource="{Binding Lines}" SelectedItem="{Binding SelectedLine}"
|
||
Background="Transparent" BorderThickness="0" Padding="0" IsVisible="{Binding !IsCartEmpty}">
|
||
<ListBox.Styles>
|
||
<Style Selector="ListBoxItem">
|
||
<Setter Property="Padding" Value="0"/><Setter Property="Margin" Value="0"/><Setter Property="CornerRadius" Value="0"/>
|
||
<Setter Property="Background" Value="Transparent"/>
|
||
</Style>
|
||
<Style Selector="ListBoxItem:selected /template/ ContentPresenter"><Setter Property="Background" Value="Transparent"/></Style>
|
||
<Style Selector="ListBoxItem:pointerover /template/ ContentPresenter"><Setter Property="Background" Value="Transparent"/></Style>
|
||
<Style Selector="Border.row"><Setter Property="Background" Value="Transparent"/></Style>
|
||
<Style Selector="Rectangle.accent"><Setter Property="IsVisible" Value="False"/></Style>
|
||
<!-- Светлая подсветка строки (как в макете #F7FBF8), а не тёмная из темы -->
|
||
<Style Selector="ListBoxItem:pointerover Border.row"><Setter Property="Background" Value="{DynamicResource PosSelRow}"/></Style>
|
||
<Style Selector="ListBoxItem:selected Border.row"><Setter Property="Background" Value="{DynamicResource PosSelRow}"/></Style>
|
||
<Style Selector="ListBoxItem:selected Rectangle.accent"><Setter Property="IsVisible" Value="True"/></Style>
|
||
</ListBox.Styles>
|
||
<ListBox.ItemTemplate>
|
||
<DataTemplate x:DataType="vm:SaleLineVm">
|
||
<Border Classes="row" Height="76" BorderBrush="{DynamicResource PosBorder}" BorderThickness="0,0,0,1">
|
||
<Grid ColumnDefinitions="4,*,200,160,56">
|
||
<Rectangle Grid.Column="0" Classes="accent" Fill="{DynamicResource PosBrand}"/>
|
||
<StackPanel Grid.Column="1" VerticalAlignment="Center" Margin="16,0,0,0">
|
||
<TextBlock Text="{Binding Name}" Foreground="{DynamicResource PosText}" FontSize="18" FontWeight="SemiBold" TextTrimming="CharacterEllipsis"/>
|
||
<TextBlock Text="{Binding DiscountText}" Foreground="{DynamicResource PosBrandDark}" FontSize="14" FontWeight="Medium" Margin="0,4,0,0" IsVisible="{Binding HasDiscount}"/>
|
||
<TextBlock Text="{Binding UnitPriceText}" Foreground="{DynamicResource PosTextMuted}" FontSize="14" Margin="0,4,0,0" IsVisible="{Binding !HasDiscount}"/>
|
||
</StackPanel>
|
||
<Border Grid.Column="2" Height="44" Margin="16,0" BorderBrush="{DynamicResource PosBorder}" BorderThickness="1" CornerRadius="10" ClipToBounds="True">
|
||
<Grid ColumnDefinitions="44,*,44">
|
||
<Button Classes="stepbtn" Content="−" Command="{Binding $parent[ItemsControl].((vm:SaleViewModel)DataContext).DecLineCommand}" CommandParameter="{Binding}"/>
|
||
<TextBlock Grid.Column="1" Text="{Binding QtyText}" Foreground="{DynamicResource PosText}" FontSize="17" FontWeight="SemiBold" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||
<Button Grid.Column="2" Classes="stepbtn" FontSize="20" Content="+" Command="{Binding $parent[ItemsControl].((vm:SaleViewModel)DataContext).IncLineCommand}" CommandParameter="{Binding}"/>
|
||
</Grid>
|
||
</Border>
|
||
<TextBlock Grid.Column="3" Text="{Binding LineTotal, StringFormat='{}{0:N0} ₸'}" Foreground="{DynamicResource PosText}" FontSize="20" FontWeight="Bold" HorizontalAlignment="Right" VerticalAlignment="Center"/>
|
||
<Button Grid.Column="4" Width="44" Height="44" Background="Transparent" BorderThickness="0" HorizontalAlignment="Right" VerticalAlignment="Center"
|
||
Command="{Binding $parent[ItemsControl].((vm:SaleViewModel)DataContext).RemoveLineCommand}" CommandParameter="{Binding}" ToolTip.Tip="Удалить">
|
||
<Path Width="20" Height="20" Stretch="Uniform" Stroke="#9AA7A1" StrokeThickness="2" StrokeLineCap="Round" StrokeJoin="Round"
|
||
Data="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/>
|
||
</Button>
|
||
</Grid>
|
||
</Border>
|
||
</DataTemplate>
|
||
</ListBox.ItemTemplate>
|
||
</ListBox>
|
||
</Grid>
|
||
</Border>
|
||
</Grid>
|
||
|
||
<!-- ПРАВО -->
|
||
<Border Grid.Column="1" Background="{DynamicResource PosCard}" BorderBrush="{DynamicResource PosBorder}" BorderThickness="1" CornerRadius="14" Margin="8,16,24,16" ClipToBounds="True">
|
||
<Grid x:Name="RightInner" RowDefinitions="Auto,*,Auto" Margin="24">
|
||
<StackPanel x:Name="SummaryStack" Grid.Row="0" Spacing="16">
|
||
<Grid ColumnDefinitions="*,Auto"><TextBlock Text="Позиций" Foreground="{DynamicResource PosTextMuted}" FontSize="17"/><TextBlock Grid.Column="1" Text="{Binding ItemCount}" Foreground="{DynamicResource PosText}" FontSize="17" FontWeight="SemiBold"/></Grid>
|
||
<Grid ColumnDefinitions="*,Auto"><TextBlock Text="Подытог" Foreground="{DynamicResource PosTextMuted}" FontSize="17"/><TextBlock Grid.Column="1" Text="{Binding Subtotal, StringFormat='{}{0:N0} ₸'}" Foreground="{DynamicResource PosText}" FontSize="17" FontWeight="SemiBold"/></Grid>
|
||
<Grid ColumnDefinitions="*,Auto" IsVisible="{Binding HasAnyDiscount}"><TextBlock Text="Скидка" Foreground="{DynamicResource PosTextMuted}" FontSize="17"/><TextBlock Grid.Column="1" Text="{Binding Discount, StringFormat='−{0:N0} ₸'}" Foreground="{DynamicResource PosBrandDark}" FontSize="17" FontWeight="SemiBold"/></Grid>
|
||
<Border x:Name="ItogoBorder" Background="{DynamicResource PosBrandSoft}" CornerRadius="12" Padding="22,20">
|
||
<Grid ColumnDefinitions="*,Auto">
|
||
<TextBlock Text="ИТОГО" Foreground="{DynamicResource PosBrandDark}" FontSize="18" FontWeight="Bold" VerticalAlignment="Bottom"/>
|
||
<TextBlock x:Name="ItogoValue" Grid.Column="1" Text="{Binding Total, StringFormat='{}{0:N0} ₸'}" Foreground="{DynamicResource PosBrandDark}" FontSize="52" FontWeight="ExtraBold"/>
|
||
</Grid>
|
||
</Border>
|
||
<Border x:Name="LastCheckBlock" BorderBrush="{DynamicResource PosBorder}" BorderThickness="0,1,0,0" Padding="0,16,0,0">
|
||
<StackPanel Spacing="10">
|
||
<Grid ColumnDefinitions="*,Auto"><TextBlock Foreground="{DynamicResource PosTextMuted}" FontSize="14"><Run Text="Последний чек "/><Run Text="{Binding LastReceiptNumber}"/></TextBlock><TextBlock Grid.Column="1" Text="{Binding LastReceiptInfo}" Foreground="{DynamicResource PosText}" FontSize="14" FontWeight="SemiBold"/></Grid>
|
||
<Grid ColumnDefinitions="*,Auto"><TextBlock Text="Чеков за смену" Foreground="{DynamicResource PosTextMuted}" FontSize="14"/><TextBlock Grid.Column="1" Text="{Binding ReceiptsInShift}" Foreground="{DynamicResource PosText}" FontSize="14" FontWeight="SemiBold"/></Grid>
|
||
</StackPanel>
|
||
</Border>
|
||
</StackPanel>
|
||
|
||
<StackPanel Grid.Row="2" Spacing="12">
|
||
<Button x:Name="PayButton" Classes="pos primary" HorizontalAlignment="Stretch" Height="76" Command="{Binding PayCommand}">
|
||
<StackPanel Orientation="Horizontal" Spacing="12" HorizontalAlignment="Center">
|
||
<TextBlock Text="Оплатить" FontSize="24" FontWeight="Bold" Foreground="White" VerticalAlignment="Center"/>
|
||
<Border Classes="kbd onbrand"><TextBlock Text="F12"/></Border>
|
||
</StackPanel>
|
||
</Button>
|
||
<Grid x:Name="ActionsGrid" ColumnDefinitions="*,*" RowDefinitions="Auto,Auto,Auto,Auto">
|
||
<Button Grid.Row="0" Grid.Column="0" Classes="pos ghost" Height="52" Margin="0,0,5,10">
|
||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||
<Path Width="18" Height="18" Stretch="Uniform" Stroke="{DynamicResource PosTextMuted}" StrokeThickness="2" StrokeLineCap="Round" Data="M19 5L5 19M7 7h.01M17 17h.01"/>
|
||
<TextBlock Text="Скидка" VerticalAlignment="Center"/><Border Classes="kbd"><TextBlock Text="F4"/></Border>
|
||
</StackPanel>
|
||
</Button>
|
||
<Button Grid.Row="0" Grid.Column="1" Classes="pos ghost" Height="52" Margin="5,0,0,10" Command="{Binding ParkCommand}">
|
||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||
<Path Width="18" Height="18" Stretch="Uniform" Stroke="{DynamicResource PosTextMuted}" StrokeThickness="2" StrokeJoin="Round" Data="M6 4h12v16l-6-4-6 4z"/>
|
||
<TextBlock Text="Отложить" VerticalAlignment="Center"/><Border Classes="kbd"><TextBlock Text="F7"/></Border>
|
||
</StackPanel>
|
||
</Button>
|
||
<Button Grid.Row="1" Grid.Column="0" Classes="pos ghost" Height="52" Margin="0,0,5,10" Command="{Binding ResumeCommand}">
|
||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||
<Path Width="18" Height="18" Stretch="Uniform" Stroke="{DynamicResource PosTextMuted}" StrokeThickness="2" StrokeLineCap="Round" Data="M4 6h16M4 12h16M4 18h10"/>
|
||
<TextBlock Text="Отложенные" VerticalAlignment="Center"/>
|
||
<Border CornerRadius="999" MinWidth="22" Height="22" Padding="7,0" Background="{DynamicResource PosWarnSoft}" VerticalAlignment="Center" IsVisible="{Binding HasParked}">
|
||
<TextBlock Text="{Binding ParkedCount}" FontSize="13" FontWeight="Bold" Foreground="{DynamicResource PosWarn}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||
</Border>
|
||
</StackPanel>
|
||
</Button>
|
||
<Button Grid.Row="1" Grid.Column="1" Classes="pos ghost" Height="52" Margin="5,0,0,10" Command="{Binding GoReturnCommand}">
|
||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||
<Path Width="18" Height="18" Stretch="Uniform" Stroke="{DynamicResource PosTextMuted}" StrokeThickness="2" StrokeLineCap="Round" StrokeJoin="Round" Data="M9 14L4 9l5-5M4 9h11a5 5 0 010 10h-3"/>
|
||
<TextBlock Text="Возврат" VerticalAlignment="Center"/><Border Classes="kbd"><TextBlock Text="F9"/></Border>
|
||
</StackPanel>
|
||
</Button>
|
||
<Button Grid.Row="2" Grid.Column="0" Classes="pos ghost" Height="52" Margin="0,0,5,10" Command="{Binding GoShiftCommand}">
|
||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||
<Path Width="18" Height="18" Stretch="None" Stroke="{DynamicResource PosTextMuted}" StrokeThickness="2" StrokeLineCap="Round" Data="M9 3v12M3 9h12"/>
|
||
<TextBlock Text="Внесение" VerticalAlignment="Center"/>
|
||
</StackPanel>
|
||
</Button>
|
||
<Button Grid.Row="2" Grid.Column="1" Classes="pos ghost" Height="52" Margin="5,0,0,10" Command="{Binding GoShiftCommand}">
|
||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||
<!-- Минус: Stretch=None — одиночная горизонталь при Uniform схлопывается в точку -->
|
||
<Path Width="18" Height="18" Stretch="None" Stroke="{DynamicResource PosTextMuted}" StrokeThickness="2" StrokeLineCap="Round" Data="M3 9h12"/>
|
||
<TextBlock Text="Выплата" VerticalAlignment="Center"/>
|
||
</StackPanel>
|
||
</Button>
|
||
<Button Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Classes="pos danger" Height="52" Command="{Binding ClearCommand}">
|
||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||
<Path Width="18" Height="18" Stretch="Uniform" Stroke="{DynamicResource PosDanger}" StrokeThickness="2" StrokeLineCap="Round" Data="M6 6l12 12M18 6L6 18"/>
|
||
<TextBlock Text="Очистить чек" VerticalAlignment="Center"/><Border Classes="kbd"><TextBlock Text="Esc"/></Border>
|
||
</StackPanel>
|
||
</Button>
|
||
</Grid>
|
||
</StackPanel>
|
||
</Grid>
|
||
</Border>
|
||
</Grid>
|
||
</UserControl>
|