Files
EbayListingTool/EbayListingTool/Views/PhotoAnalysisView.xaml
Peter Foster b3ef79e495 Add dyscalculia-friendly UI: card preview, verbal prices, relative dates
- NumberWords helper: decimal → "about seventeen pounds", DateTime → "3 days ago"
- PhotoAnalysisView: after analysis shows a card preview with large verbal price,
  photo dots, "Looks good ✓" to save instantly, "Change something ▼" to reveal
  a price slider (snaps to 50p, updates verbally as you drag) and title bar
- Card preview updates when live eBay price lookup completes
- SavedListingsView cards: verbal price as primary, £x.xx small beneath,
  relative date ("yesterday", "3 days ago") instead of raw timestamp
- Detail panel also shows relative date

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 03:00:36 +01:00

843 lines
50 KiB
XML
Raw 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.
<UserControl x:Class="EbayListingTool.Views.PhotoAnalysisView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks">
<UserControl.Resources>
<!-- ================================================================
Styles
================================================================ -->
<Style x:Key="SectionCard" TargetType="Border">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="6"/>
<Setter Property="Padding" Value="14,12"/>
<Setter Property="Margin" Value="0,0,0,10"/>
<Setter Property="BorderBrush" Value="{DynamicResource MahApps.Brushes.Gray8}"/>
<Setter Property="Background" Value="{DynamicResource MahApps.Brushes.Gray10}"/>
</Style>
<Style x:Key="SectionHeading" TargetType="TextBlock">
<Setter Property="FontSize" Value="10"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Foreground" Value="{DynamicResource MahApps.Brushes.Accent}"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style x:Key="FieldLabel" TargetType="TextBlock">
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="Margin" Value="0,0,0,4"/>
<Setter Property="Foreground" Value="{DynamicResource MahApps.Brushes.Gray2}"/>
</Style>
<Style x:Key="ResultValue" TargetType="TextBlock">
<Setter Property="FontSize" Value="13"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="Foreground" Value="{DynamicResource MahApps.Brushes.Gray1}"/>
</Style>
<Style x:Key="AiButton" TargetType="Button"
BasedOn="{StaticResource MahApps.Styles.Button.Square}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#7C3AED" Offset="0"/>
<GradientStop Color="#4F46E5" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#8B5CF6" Offset="0"/>
<GradientStop Color="#6366F1" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.45"/>
</Trigger>
</Style.Triggers>
</Style>
<!-- Small icon-only clipboard button -->
<Style x:Key="CopyButton" TargetType="Button"
BasedOn="{StaticResource MahApps.Styles.Button.Square}">
<Setter Property="Width" Value="28"/>
<Setter Property="Height" Value="28"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ToolTip" Value="Copy to clipboard"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<!-- ================================================================
Drop zone dashed border animation
================================================================ -->
<Style x:Key="DashedDropBorder" TargetType="Border">
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="CornerRadius" Value="10"/>
<Setter Property="Background" Value="{DynamicResource MahApps.Brushes.Gray10}"/>
<Setter Property="AllowDrop" Value="True"/>
<Setter Property="MinHeight" Value="320"/>
<Setter Property="Cursor" Value="Hand"/>
</Style>
<!-- ================================================================
Results reveal animation
================================================================ -->
<Storyboard x:Key="ResultsReveal">
<DoubleAnimation Storyboard.TargetName="ResultsPanel"
Storyboard.TargetProperty="Opacity"
From="0" To="1" Duration="0:0:0.25"/>
<DoubleAnimation Storyboard.TargetName="ResultsTranslate"
Storyboard.TargetProperty="Y"
From="20" To="0" Duration="0:0:0.25">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
<!-- Camera icon pulse animation — both axes target the same ScaleTransform -->
<Storyboard x:Key="CameraPulse" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="CameraScale"
Storyboard.TargetProperty="ScaleX">
<EasingDoubleKeyFrame KeyTime="0:0:0.0" Value="1.0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="1.08">
<EasingDoubleKeyFrame.EasingFunction><SineEase EasingMode="EaseInOut"/></EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:2.0" Value="1.0">
<EasingDoubleKeyFrame.EasingFunction><SineEase EasingMode="EaseInOut"/></EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="CameraScale"
Storyboard.TargetProperty="ScaleY">
<EasingDoubleKeyFrame KeyTime="0:0:0.0" Value="1.0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="1.08">
<EasingDoubleKeyFrame.EasingFunction><SineEase EasingMode="EaseInOut"/></EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:2.0" Value="1.0">
<EasingDoubleKeyFrame.EasingFunction><SineEase EasingMode="EaseInOut"/></EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<!-- Start animations when control loads -->
<UserControl.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource CameraPulse}"/>
</EventTrigger>
</UserControl.Triggers>
<Grid Margin="16,12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="340"/>
<ColumnDefinition Width="12"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- ================================================================
LEFT: Photo drop zone + analyse button
================================================================ -->
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Drop zone with dashed border drawn via Rectangle overlay -->
<Grid Grid.Row="0">
<!-- Dashed border rectangle -->
<Rectangle x:Name="DropBorderRect"
RadiusX="10" RadiusY="10"
StrokeDashArray="6,4"
StrokeThickness="2"
Stroke="{DynamicResource MahApps.Brushes.Gray6}"
Fill="Transparent"
IsHitTestVisible="False"/>
<Border x:Name="DropZone"
CornerRadius="10"
Background="{DynamicResource MahApps.Brushes.Gray10}"
AllowDrop="True"
Drop="DropZone_Drop"
DragOver="DropZone_DragOver"
DragEnter="DropZone_DragEnter"
DragLeave="DropZone_DragLeave"
MinHeight="320"
Cursor="Hand"
MouseLeftButtonUp="DropZone_Click">
<!-- Wrapper grid so Border has only one child; children overlap via shared cell -->
<Grid>
<!-- Empty state hint -->
<Grid x:Name="DropHint" VerticalAlignment="Center" HorizontalAlignment="Center">
<StackPanel HorizontalAlignment="Center">
<iconPacks:PackIconMaterial Kind="CameraPlus"
x:Name="CameraIcon"
Width="64" Height="64"
HorizontalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Accent}"
Margin="0,0,0,16"
RenderTransformOrigin="0.5,0.5">
<iconPacks:PackIconMaterial.RenderTransform>
<ScaleTransform x:Name="CameraScale" ScaleX="1" ScaleY="1"/>
</iconPacks:PackIconMaterial.RenderTransform>
</iconPacks:PackIconMaterial>
<TextBlock Text="Drop a photo here" FontSize="16" FontWeight="SemiBold"
HorizontalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Gray3}"/>
<TextBlock Text="or click to browse" FontSize="12" Margin="0,4,0,0"
HorizontalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Gray5}"/>
<TextBlock Text="JPG · PNG · GIF · WEBP" FontSize="11" Margin="0,14,0,0"
HorizontalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Gray7}"/>
</StackPanel>
</Grid>
<!-- Loaded photo with rounded clip and drop shadow -->
<Grid x:Name="PhotoPreviewContainer" Visibility="Collapsed">
<Grid.Effect>
<DropShadowEffect BlurRadius="12" ShadowDepth="3" Opacity="0.25" Color="Black"/>
</Grid.Effect>
<Image x:Name="PhotoPreview"
Stretch="Uniform"
Margin="4"
RenderOptions.BitmapScalingMode="HighQuality">
<Image.Clip>
<RectangleGeometry x:Name="PhotoClip" RadiusX="8" RadiusY="8"/>
</Image.Clip>
</Image>
</Grid>
</Grid>
</Border>
<!-- Clear photo button (top-right overlay) -->
<Button x:Name="ClearPhotoBtn"
Visibility="Collapsed"
Click="ClearPhoto_Click"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="0,8,8,0"
Width="24" Height="24"
Padding="3"
ToolTip="Remove photo"
Style="{DynamicResource MahApps.Styles.Button.Square}"
Background="#CC222222"
BorderThickness="0">
<iconPacks:PackIconMaterial Kind="Close" Width="12" Height="12" Foreground="White"/>
</Button>
</Grid>
<!-- Photo filename label -->
<TextBlock x:Name="PhotoFilename" Grid.Row="1"
Text="" FontSize="11" Margin="0,6,0,0"
Foreground="{DynamicResource MahApps.Brushes.Gray5}"
HorizontalAlignment="Center"
TextTrimming="CharacterEllipsis"/>
<!-- Thumbnail strip (hidden until 2+ photos loaded) -->
<ScrollViewer Grid.Row="2"
x:Name="ThumbStripScroller"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Disabled"
Visibility="Collapsed"
Margin="0,8,0,0">
<WrapPanel x:Name="PhotoThumbStrip"
Orientation="Horizontal"
HorizontalAlignment="Center"/>
</ScrollViewer>
<!-- Analyse button -->
<Button Grid.Row="3" x:Name="AnalyseBtn"
Click="Analyse_Click"
Style="{StaticResource AiButton}"
Height="42" FontSize="15" Margin="0,10,0,0"
IsEnabled="False">
<StackPanel Orientation="Horizontal">
<mah:ProgressRing x:Name="AnalyseSpinner"
Width="18" Height="18" Margin="0,0,8,0"
Foreground="White" Visibility="Collapsed"/>
<iconPacks:PackIconMaterial x:Name="AnalyseIcon"
Kind="Magnify" Width="18" Height="18"
Margin="0,0,8,0" VerticalAlignment="Center"/>
<TextBlock x:Name="AnalyseBtnText"
Text="Identify &amp; Price with AI"
VerticalAlignment="Center"/>
</StackPanel>
</Button>
</Grid>
<!-- ================================================================
RIGHT: Results panel
================================================================ -->
<ScrollViewer Grid.Column="2" VerticalScrollBarVisibility="Auto">
<StackPanel>
<!-- Idle state -->
<Border x:Name="IdlePanel" Style="{StaticResource SectionCard}"
MinHeight="400">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<iconPacks:PackIconMaterial Kind="TagOutline"
Width="52" Height="52"
HorizontalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Gray7}"
Margin="0,0,0,16"/>
<TextBlock Text="Drop a photo and click Identify"
FontSize="15" FontWeight="SemiBold"
HorizontalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Gray5}"/>
<TextBlock Text="Claude will identify the item, write a listing description&#10;and suggest a realistic eBay UK selling price."
FontSize="12" Margin="0,8,0,0"
HorizontalAlignment="Center" TextAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Gray7}"
TextWrapping="Wrap" MaxWidth="320"/>
</StackPanel>
</Border>
<!-- Loading state (shown during analysis) -->
<Border x:Name="LoadingPanel" Style="{StaticResource SectionCard}"
MinHeight="400" Visibility="Collapsed">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<mah:ProgressRing Width="48" Height="48"
Foreground="{DynamicResource MahApps.Brushes.Accent}"
HorizontalAlignment="Center"
Margin="0,0,0,20"/>
<TextBlock x:Name="LoadingStepText"
Text="Examining the photo…"
FontSize="15" FontWeight="SemiBold"
HorizontalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Gray3}"/>
<TextBlock Text="This usually takes 1020 seconds"
FontSize="11" Margin="0,8,0,0"
HorizontalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Gray7}"/>
</StackPanel>
</Border>
<!-- ============================================================
Card Preview — dyscalculia-friendly quick-approve flow
============================================================ -->
<StackPanel x:Name="CardPreviewPanel" Visibility="Collapsed">
<!-- Item card -->
<Border CornerRadius="10" Padding="16" Margin="0,0,0,12"
Background="{DynamicResource MahApps.Brushes.Gray10}"
BorderBrush="{DynamicResource MahApps.Brushes.Gray8}"
BorderThickness="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="110"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Cover photo -->
<Border Grid.Column="0" CornerRadius="7" ClipToBounds="True"
Width="110" Height="110">
<Image x:Name="CardPhoto" Stretch="UniformToFill"/>
</Border>
<!-- Details -->
<StackPanel Grid.Column="1" Margin="14,0,0,0"
VerticalAlignment="Center">
<TextBlock x:Name="CardItemName"
FontSize="17" FontWeight="Bold"
TextWrapping="Wrap"
Foreground="{DynamicResource MahApps.Brushes.Gray1}"/>
<TextBlock x:Name="CardCondition"
FontSize="11" Margin="0,3,0,0"
TextWrapping="Wrap"
Foreground="{DynamicResource MahApps.Brushes.Gray5}"/>
<!-- Photo dots (built in code-behind) -->
<StackPanel x:Name="CardPhotoDots"
Orientation="Horizontal" Margin="0,8,0,0"/>
<!-- Verbal price — primary -->
<TextBlock x:Name="CardPriceVerbal"
FontSize="24" FontWeight="Bold" Margin="0,10,0,2"
Foreground="{DynamicResource MahApps.Brushes.Accent}"/>
<!-- Digit price — secondary/small -->
<TextBlock x:Name="CardPriceDigit"
FontSize="11" Opacity="0.40"/>
<!-- Category pill -->
<Border CornerRadius="10" Padding="8,3" Margin="0,10,0,0"
Background="{DynamicResource MahApps.Brushes.Gray9}"
HorizontalAlignment="Left">
<TextBlock x:Name="CardCategory" FontSize="11"
Foreground="{DynamicResource MahApps.Brushes.Gray3}"/>
</Border>
</StackPanel>
</Grid>
</Border>
<!-- Live price note (updated async) -->
<TextBlock x:Name="CardLivePriceNote"
FontSize="10" Margin="0,0,0,10"
Foreground="{DynamicResource MahApps.Brushes.Gray5}"
TextWrapping="Wrap" Visibility="Collapsed"/>
<!-- Primary action buttons -->
<Grid Margin="0,0,0,6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="8"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" x:Name="LooksGoodBtn"
Click="LooksGood_Click"
Height="54" FontSize="15" FontWeight="SemiBold"
Style="{DynamicResource MahApps.Styles.Button.Square.Accent}">
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="Check" Width="17" Height="17"
Margin="0,0,8,0" VerticalAlignment="Center"/>
<TextBlock Text="Looks good" VerticalAlignment="Center"/>
</StackPanel>
</Button>
<Button Grid.Column="2" x:Name="ChangeSomethingBtn"
Click="ChangeSomething_Click"
Height="54" FontSize="13"
Style="{DynamicResource MahApps.Styles.Button.Square}">
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial x:Name="ChangeChevron"
Kind="ChevronDown" Width="13" Height="13"
Margin="0,0,6,0" VerticalAlignment="Center"/>
<TextBlock Text="Change something" VerticalAlignment="Center"/>
</StackPanel>
</Button>
</Grid>
<!-- Change panel (collapsed by default) -->
<StackPanel x:Name="CardChangePanel" Visibility="Collapsed" Margin="0,4,0,0">
<!-- Price slider -->
<Border Style="{StaticResource SectionCard}">
<StackPanel>
<TextBlock Text="PRICE" Style="{StaticResource SectionHeading}"
Margin="0,0,0,10"/>
<TextBlock x:Name="SliderVerbalLabel"
FontSize="22" FontWeight="Bold" Margin="0,0,0,2"
Foreground="{DynamicResource MahApps.Brushes.Accent}"/>
<TextBlock x:Name="SliderDigitLabel"
FontSize="11" Opacity="0.40" Margin="0,0,0,12"/>
<Slider x:Name="PriceSliderCard"
Minimum="0.50" Maximum="200"
SmallChange="0.5" LargeChange="5"
TickFrequency="0.5" IsSnapToTickEnabled="True"
ValueChanged="PriceSliderCard_ValueChanged"/>
<Grid Margin="0,3,0,0">
<TextBlock Text="cheaper" FontSize="10" Opacity="0.45"
HorizontalAlignment="Left"/>
<TextBlock Text="pricier" FontSize="10" Opacity="0.45"
HorizontalAlignment="Right"/>
</Grid>
</StackPanel>
</Border>
<!-- Title edit -->
<Border Style="{StaticResource SectionCard}">
<StackPanel>
<TextBlock Text="TITLE" Style="{StaticResource SectionHeading}"
Margin="0,0,0,8"/>
<TextBox x:Name="CardTitleBox"
TextWrapping="Wrap" AcceptsReturn="False"
MaxLength="80" FontSize="13"
TextChanged="CardTitleBox_TextChanged"/>
<!-- Colour bar — no digit counter -->
<Grid Margin="0,6,0,0" Height="4">
<Border CornerRadius="2" Background="{DynamicResource MahApps.Brushes.Gray8}"/>
<Border x:Name="CardTitleBar" CornerRadius="2"
HorizontalAlignment="Left" Width="0"
Background="{DynamicResource MahApps.Brushes.Accent}"/>
</Grid>
</StackPanel>
</Border>
<!-- Save with changes -->
<Button Content="Save with changes"
Click="SaveWithChanges_Click"
Style="{DynamicResource MahApps.Styles.Button.Square.Accent}"
Height="46" FontSize="14" FontWeight="SemiBold"
HorizontalAlignment="Stretch" Margin="0,4,0,8"/>
<Button Content="Analyse another item"
Click="AnalyseAnother_Click"
Style="{DynamicResource MahApps.Styles.Button.Square}"
Height="36" FontSize="12"
HorizontalAlignment="Stretch"/>
</StackPanel>
</StackPanel>
<!-- Results (hidden until analysis complete) -->
<StackPanel x:Name="ResultsPanel" Visibility="Collapsed" Opacity="0">
<StackPanel.RenderTransform>
<TranslateTransform x:Name="ResultsTranslate" Y="20"/>
</StackPanel.RenderTransform>
<!-- Identified item -->
<Border Style="{StaticResource SectionCard}">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,12">
<iconPacks:PackIconMaterial Kind="CartOutline" Width="13" Height="13"
Margin="0,0,6,0" VerticalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Accent}"/>
<TextBlock Text="ITEM IDENTIFIED" Style="{StaticResource SectionHeading}"/>
</StackPanel>
<!-- Item name — large bold -->
<TextBlock x:Name="ItemNameText"
FontSize="20" FontWeight="Bold"
TextWrapping="Wrap" Margin="0,0,0,8"
Foreground="{DynamicResource MahApps.Brushes.Gray1}"/>
<!-- Brand/model pill badge -->
<Border x:Name="BrandPill"
Background="{DynamicResource MahApps.Brushes.Accent}"
CornerRadius="12"
Padding="10,3"
HorizontalAlignment="Left"
Margin="0,0,0,10"
Visibility="Collapsed">
<TextBlock x:Name="BrandModelText"
FontSize="11" FontWeight="SemiBold"
Foreground="White"/>
</Border>
<!-- Condition notes — green tinted box with eye icon -->
<Border Background="#1A4CAF50" BorderBrush="#4CAF50"
BorderThickness="1" CornerRadius="5" Padding="10,8">
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="Eye" Width="13" Height="13"
Margin="0,0,8,0" VerticalAlignment="Top"
Foreground="#4CAF50"/>
<TextBlock x:Name="ConditionText"
FontSize="12" TextWrapping="Wrap"
Foreground="{DynamicResource MahApps.Brushes.Gray2}"
MaxWidth="340"/>
</StackPanel>
</Border>
<!-- Confidence badge (High / Medium / Low) -->
<Border x:Name="ConfidenceBadge"
CornerRadius="10" Padding="8,3"
HorizontalAlignment="Left"
Margin="0,10,0,0"
Visibility="Collapsed">
<TextBlock x:Name="ConfidenceText"
FontSize="10" FontWeight="SemiBold"
Foreground="White"/>
</Border>
<!-- Confidence notes -->
<TextBlock x:Name="ConfidenceNotesText"
FontSize="11" FontStyle="Italic"
TextWrapping="Wrap"
Margin="0,6,0,0"
Foreground="{DynamicResource MahApps.Brushes.Gray5}"
Visibility="Collapsed"/>
</StackPanel>
</Border>
<!-- Price -->
<Border Style="{StaticResource SectionCard}">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,12">
<iconPacks:PackIconMaterial Kind="CurrencyGbp" Width="13" Height="13"
Margin="0,0,6,0" VerticalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Accent}"/>
<TextBlock Text="SUGGESTED PRICE" Style="{StaticResource SectionHeading}"/>
</StackPanel>
<!-- Prominent price badge -->
<Border HorizontalAlignment="Left"
Background="{DynamicResource MahApps.Brushes.Accent}"
CornerRadius="10"
Padding="18,8"
Margin="0,0,0,10">
<TextBlock x:Name="PriceSuggestedText"
FontSize="38" FontWeight="Bold"
Foreground="White"/>
</Border>
<!-- Min · Suggested · Max visual bar -->
<Grid x:Name="PriceRangeBar" Margin="0,0,0,12" Visibility="Collapsed">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Connecting line -->
<Border Grid.Row="0" Height="2" Margin="12,0"
VerticalAlignment="Center"
Background="{DynamicResource MahApps.Brushes.Gray7}"
CornerRadius="1"/>
<!-- Three dots + labels -->
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Ellipse Grid.Column="0" Width="10" Height="10"
Fill="{DynamicResource MahApps.Brushes.Gray5}"
VerticalAlignment="Center"/>
<Ellipse Grid.Column="2" Width="14" Height="14"
Fill="{DynamicResource MahApps.Brushes.Accent}"
VerticalAlignment="Center"/>
<Ellipse Grid.Column="4" Width="10" Height="10"
Fill="{DynamicResource MahApps.Brushes.Gray5}"
VerticalAlignment="Center"/>
</Grid>
<!-- Labels row -->
<Grid Grid.Row="1" Margin="0,4,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" HorizontalAlignment="Center">
<TextBlock Text="MIN" FontSize="9" FontWeight="SemiBold"
Foreground="{DynamicResource MahApps.Brushes.Gray6}"
HorizontalAlignment="Center"/>
<TextBlock x:Name="PriceMinText" FontSize="11"
Foreground="{DynamicResource MahApps.Brushes.Gray6}"
HorizontalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Column="2" HorizontalAlignment="Center">
<TextBlock Text="SUGGESTED" FontSize="9" FontWeight="SemiBold"
Foreground="{DynamicResource MahApps.Brushes.Accent}"
HorizontalAlignment="Center"/>
</StackPanel>
<StackPanel Grid.Column="4" HorizontalAlignment="Center">
<TextBlock Text="MAX" FontSize="9" FontWeight="SemiBold"
Foreground="{DynamicResource MahApps.Brushes.Gray6}"
HorizontalAlignment="Center"/>
<TextBlock x:Name="PriceMaxText" FontSize="11"
Foreground="{DynamicResource MahApps.Brushes.Gray6}"
HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
</Grid>
<!-- Editable price override -->
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Text="Override price:" FontSize="11"
Foreground="{DynamicResource MahApps.Brushes.Gray5}"
VerticalAlignment="Center" Margin="0,0,8,0"/>
<mah:NumericUpDown x:Name="PriceOverride"
Width="110" Height="32"
Minimum="0" Maximum="99999"
StringFormat="F2" Interval="0.5"/>
</StackPanel>
<!-- Live eBay price status -->
<StackPanel x:Name="LivePriceRow" Orientation="Horizontal"
Margin="0,6,0,0" Visibility="Collapsed">
<mah:ProgressRing x:Name="LivePriceSpinner"
Width="11" Height="11" Margin="0,0,6,0"/>
<TextBlock x:Name="LivePriceStatus"
FontSize="10"
Foreground="{DynamicResource MahApps.Brushes.Gray5}"
VerticalAlignment="Center"
TextWrapping="Wrap"/>
</StackPanel>
<!-- Price reasoning -->
<TextBlock x:Name="PriceReasoningText"
FontSize="11" FontStyle="Italic"
TextWrapping="Wrap"
Margin="0,8,0,0"
Foreground="{DynamicResource MahApps.Brushes.Gray5}"
Visibility="Collapsed"/>
</StackPanel>
</Border>
<!-- Title -->
<Border Style="{StaticResource SectionCard}">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8"
HorizontalAlignment="Stretch">
<iconPacks:PackIconMaterial Kind="TagOutline" Width="13" Height="13"
Margin="0,0,6,0" VerticalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Accent}"/>
<TextBlock Text="LISTING TITLE" Style="{StaticResource SectionHeading}"
VerticalAlignment="Center"/>
<Button x:Name="CopyTitleBtn"
Style="{StaticResource CopyButton}"
Click="CopyTitle_Click"
Margin="8,0,0,0"
ToolTip="Copy title to clipboard">
<iconPacks:PackIconMaterial Kind="ContentCopy" Width="12" Height="12"/>
</Button>
</StackPanel>
<TextBox x:Name="TitleBox"
MaxLength="80"
mah:TextBoxHelper.Watermark="Listing title (max 80 chars)"
TextChanged="TitleBox_TextChanged"/>
<TextBlock x:Name="TitleCount" Text="0 / 80" FontSize="10"
HorizontalAlignment="Right" Margin="0,3,0,0"
Foreground="{DynamicResource MahApps.Brushes.Gray5}"/>
</StackPanel>
</Border>
<!-- Description -->
<Border Style="{StaticResource SectionCard}">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<iconPacks:PackIconMaterial Kind="TextBox" Width="13" Height="13"
Margin="0,0,6,0" VerticalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Accent}"/>
<TextBlock Text="DESCRIPTION" Style="{StaticResource SectionHeading}"
VerticalAlignment="Center"/>
<Button x:Name="CopyDescBtn"
Style="{StaticResource CopyButton}"
Click="CopyDescription_Click"
Margin="8,0,0,0"
ToolTip="Copy description to clipboard">
<iconPacks:PackIconMaterial Kind="ContentCopy" Width="12" Height="12"/>
</Button>
</StackPanel>
<TextBox x:Name="DescriptionBox"
Height="180" AcceptsReturn="True"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto"
Style="{DynamicResource MahApps.Styles.TextBox}"
FontSize="12"/>
</StackPanel>
</Border>
<!-- Corrections for AI refinement -->
<Border BorderThickness="1" CornerRadius="8" Padding="14,10"
Margin="0,0,0,10"
BorderBrush="{DynamicResource MahApps.Brushes.Gray7}"
Background="{DynamicResource MahApps.Brushes.Gray9}">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,6">
<iconPacks:PackIconMaterial Kind="Pencil" Width="12" Height="12"
Margin="0,0,6,0" VerticalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Accent}"/>
<TextBlock Text="CORRECTIONS" FontSize="10" FontWeight="SemiBold"
Foreground="{DynamicResource MahApps.Brushes.Accent}"
VerticalAlignment="Center"/>
</StackPanel>
<TextBox x:Name="CorrectionsBox"
AcceptsReturn="False"
TextWrapping="Wrap"
Height="52"
VerticalScrollBarVisibility="Auto"
Style="{DynamicResource MahApps.Styles.TextBox}"
FontSize="12"
mah:TextBoxHelper.Watermark="e.g. earrings are white gold with diamonds, not silver and zirconium"
Margin="0,0,0,8"/>
<Button x:Name="RefineBtn"
Click="Refine_Click"
Style="{DynamicResource MahApps.Styles.Button.Square}"
Height="32" Padding="12,0" HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial x:Name="RefineIcon" Kind="AutoFix" Width="13" Height="13"
Margin="0,0,6,0" VerticalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Accent}"/>
<mah:ProgressRing x:Name="RefineSpinner" Width="13" Height="13"
Margin="0,0,6,0" Visibility="Collapsed"/>
<TextBlock x:Name="RefineBtnText" Text="Refine with AI"
VerticalAlignment="Center" FontSize="12"/>
</StackPanel>
</Button>
</StackPanel>
</Border>
<!-- Actions + toast overlay -->
<Grid Margin="0,4,0,16" ClipToBounds="False">
<StackPanel Orientation="Horizontal">
<Button x:Name="UseDetailsBtn"
Content="Use for New Listing →"
Click="UseDetails_Click"
Style="{DynamicResource MahApps.Styles.Button.Square.Accent}"
Height="36" Padding="16,0" FontSize="13" FontWeight="SemiBold"/>
<Button x:Name="SaveListingBtn"
Click="SaveListing_Click"
Margin="8,0,0,0"
Style="{DynamicResource MahApps.Styles.Button.Square}"
Height="36" Padding="14,0">
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="BookmarkOutline" Width="14" Height="14"
Margin="0,0,6,0" VerticalAlignment="Center"
x:Name="SaveIcon"/>
<iconPacks:PackIconMaterial Kind="BookmarkCheck" Width="14" Height="14"
Margin="0,0,6,0" VerticalAlignment="Center"
x:Name="SavedIcon" Visibility="Collapsed"
Foreground="LimeGreen"/>
<TextBlock x:Name="SaveBtnText" Text="Save Listing"
VerticalAlignment="Center" FontSize="12"/>
</StackPanel>
</Button>
<Button x:Name="ReAnalyseBtn"
Click="ReAnalyse_Click"
Margin="8,0,0,0"
Style="{DynamicResource MahApps.Styles.Button.Square}"
Height="36" Padding="12,0"
ToolTip="Re-run AI analysis with the same photo(s)">
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="Refresh" Width="14" Height="14"
Margin="0,0,6,0" VerticalAlignment="Center"/>
<TextBlock Text="Re-analyse" VerticalAlignment="Center" FontSize="12"/>
</StackPanel>
</Button>
<Button Content="Analyse Another"
Click="AnalyseAnother_Click"
Margin="8,0,0,0"
Style="{DynamicResource MahApps.Styles.Button.Square}"
Height="36" Padding="12,0"/>
</StackPanel>
<!-- Save confirmation toast -->
<Border x:Name="SaveToast"
VerticalAlignment="Bottom"
HorizontalAlignment="Left"
Background="{DynamicResource MahApps.Brushes.Accent}"
CornerRadius="6"
Padding="14,8"
Margin="0,0,0,-48"
Visibility="Collapsed"
IsHitTestVisible="False">
<Border.RenderTransform>
<TranslateTransform x:Name="ToastTranslate" Y="40"/>
</Border.RenderTransform>
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="Check" Width="14" Height="14"
Margin="0,0,8,0" VerticalAlignment="Center"
Foreground="White"/>
<TextBlock Text="Saved to Saved Listings"
FontSize="12" FontWeight="SemiBold"
Foreground="White" VerticalAlignment="Center"/>
</StackPanel>
</Border>
</Grid>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
</UserControl>