feat: rewrite MainWindow to 2-tab layout with File menu

This commit is contained in:
2026-04-16 01:58:52 +01:00
parent 987c778ae2
commit bb5cd09ce2
2 changed files with 73 additions and 184 deletions

View File

@@ -4,7 +4,7 @@
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:local="clr-namespace:EbayListingTool.Views"
Title="eBay Listing Tool UK"
Title="eBay Listing Tool - UK"
Height="820" Width="1180"
MinHeight="600" MinWidth="900"
WindowStartupLocation="CenterScreen"
@@ -61,101 +61,49 @@
</Style>
</mah:MetroWindow.Resources>
<mah:MetroWindow.RightWindowCommands>
<mah:WindowCommands>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="0,0,8,0">
<Border CornerRadius="10" Padding="8,3" Margin="0,0,8,0"
Background="#22FFFFFF" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<Ellipse x:Name="StatusDot" Style="{StaticResource ConnectedDotStyle}" Fill="#777"/>
<TextBlock x:Name="StatusLabel" Text="eBay: not connected"
Foreground="White" VerticalAlignment="Center"
FontSize="11" FontWeight="SemiBold"/>
</StackPanel>
</Border>
<Button x:Name="ConnectBtn" Click="ConnectBtn_Click"
Style="{DynamicResource MahApps.Styles.Button.Square.Accent}"
Height="28" Padding="10,0">
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="Link" Width="12" Height="12"
Margin="0,0,4,0" VerticalAlignment="Center"/>
<TextBlock Text="Connect to eBay" VerticalAlignment="Center" FontSize="12"/>
</StackPanel>
</Button>
<Button x:Name="DisconnectBtn" Visibility="Collapsed"
Margin="6,0,0,0" Click="DisconnectBtn_Click"
Style="{DynamicResource MahApps.Styles.Button.Square}"
Height="28" Padding="8,0">
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="LinkVariantOff" Width="12" Height="12"
Margin="0,0,4,0" VerticalAlignment="Center"/>
<TextBlock Text="Disconnect" VerticalAlignment="Center" FontSize="12"/>
</StackPanel>
</Button>
</StackPanel>
</mah:WindowCommands>
</mah:MetroWindow.RightWindowCommands>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TabControl x:Name="MainTabs" Grid.Row="0"
<!-- Menu bar -->
<Menu Grid.Row="0"
Background="{DynamicResource MahApps.Brushes.Gray9}"
BorderThickness="0,0,0,1"
BorderBrush="{DynamicResource MahApps.Brushes.Gray7}">
<MenuItem Header="_File">
<MenuItem x:Name="BulkImportMenuItem" Header="Bulk Import..."
Click="BulkImport_Click">
<MenuItem.Icon>
<iconPacks:PackIconMaterial Kind="TableMultiple" Width="14" Height="14"/>
</MenuItem.Icon>
</MenuItem>
<Separator/>
<MenuItem Header="E_xit" Click="Exit_Click"/>
</MenuItem>
</Menu>
<!-- 2 tabs -->
<TabControl x:Name="MainTabs" Grid.Row="1"
Style="{DynamicResource MahApps.Styles.TabControl.Animated}">
<!-- ① Photo Analysis — always available, no eBay login needed -->
<TabItem Style="{StaticResource AppTabItem}">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="Camera" Width="15" Height="15"
Margin="0,0,7,0" VerticalAlignment="Center"/>
<TextBlock Text="Photo Analyser" VerticalAlignment="Center"/>
</StackPanel>
</TabItem.Header>
<!-- Tab content: welcome banner + actual view stacked -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Welcome banner — only shown when no photo loaded yet (PhotoView sets Visibility via x:Name) -->
<Border x:Name="WelcomeBanner" Grid.Row="0"
Background="{DynamicResource MahApps.Brushes.Accent}"
Padding="14,7" Visibility="Visible">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<iconPacks:PackIconMaterial Kind="Camera" Width="14" Height="14"
Margin="0,0,8,0" VerticalAlignment="Center"
Foreground="White"/>
<TextBlock Text="Drop a photo to identify any item and get an instant eBay price"
Foreground="White" FontSize="12" FontWeight="SemiBold"
VerticalAlignment="Center"/>
</StackPanel>
</Border>
<local:PhotoAnalysisView x:Name="PhotoView" Grid.Row="1"/>
</Grid>
</TabItem>
<!-- ② New Listing — requires eBay connection -->
<!-- New Listing tab -->
<TabItem x:Name="NewListingTab" Style="{StaticResource AppTabItem}">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="TagPlusOutline" Width="15" Height="15"
<iconPacks:PackIconMaterial Kind="CameraPlus" Width="15" Height="15"
Margin="0,0,7,0" VerticalAlignment="Center"/>
<TextBlock Text="New Listing" VerticalAlignment="Center"/>
</StackPanel>
</TabItem.Header>
<Grid>
<local:SingleItemView x:Name="SingleView"/>
<!-- Overlay shown when not connected -->
<local:NewListingView x:Name="NewListingView"/>
<!-- Overlay when not connected to eBay -->
<Border x:Name="NewListingOverlay" Visibility="Visible"
Background="{DynamicResource MahApps.Brushes.ThemeBackground}">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"
MaxWidth="340">
<!-- eBay logo circle -->
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" MaxWidth="340">
<Border Width="72" Height="72" CornerRadius="36"
HorizontalAlignment="Center" Margin="0,0,0,18">
<Border.Background>
@@ -169,16 +117,15 @@
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<TextBlock Text="Connect to eBay"
FontSize="20" FontWeight="Bold"
<TextBlock Text="Connect to eBay" FontSize="20" FontWeight="Bold"
HorizontalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.ThemeForeground}"
Margin="0,0,0,8"/>
<TextBlock Text="Sign in with your eBay account to start posting listings and managing your inventory."
<TextBlock Text="Sign in with your eBay account to identify items, get prices, and post listings."
FontSize="13" TextWrapping="Wrap" TextAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Gray5}"
Margin="0,0,0,24"/>
<Button Click="ConnectBtn_Click"
<Button x:Name="ConnectBtn" Click="ConnectBtn_Click"
Style="{StaticResource LockConnectButton}"
HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal">
@@ -192,73 +139,21 @@
</Grid>
</TabItem>
<!-- ③ Saved Listings — always available -->
<TabItem x:Name="SavedTab" Style="{StaticResource AppTabItem}">
<!-- Drafts tab -->
<TabItem x:Name="DraftsTab" Style="{StaticResource AppTabItem}">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="BookmarkMultiple" Width="15" Height="15"
Margin="0,0,7,0" VerticalAlignment="Center"/>
<TextBlock Text="Saved Listings" VerticalAlignment="Center"/>
<TextBlock Text="Drafts" VerticalAlignment="Center"/>
</StackPanel>
</TabItem.Header>
<local:SavedListingsView x:Name="SavedView"/>
</TabItem>
<!-- ④ Bulk Import — requires eBay connection -->
<TabItem x:Name="BulkTab" Style="{StaticResource AppTabItem}">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="TableMultiple" Width="15" Height="15"
Margin="0,0,7,0" VerticalAlignment="Center"/>
<TextBlock Text="Bulk Import" VerticalAlignment="Center"/>
</StackPanel>
</TabItem.Header>
<Grid>
<local:BulkImportView x:Name="BulkView"/>
<Border x:Name="BulkOverlay" Visibility="Visible"
Background="{DynamicResource MahApps.Brushes.ThemeBackground}">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"
MaxWidth="340">
<!-- eBay logo circle -->
<Border Width="72" Height="72" CornerRadius="36"
HorizontalAlignment="Center" Margin="0,0,0,18">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#7C3AED" Offset="0"/>
<GradientStop Color="#4F46E5" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<iconPacks:PackIconMaterial Kind="TableArrowUp" Width="32" Height="32"
Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<TextBlock Text="Connect to eBay"
FontSize="20" FontWeight="Bold"
HorizontalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.ThemeForeground}"
Margin="0,0,0,8"/>
<TextBlock Text="Sign in with your eBay account to bulk import and post multiple listings at once."
FontSize="13" TextWrapping="Wrap" TextAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Gray5}"
Margin="0,0,0,24"/>
<Button Click="ConnectBtn_Click"
Style="{StaticResource LockConnectButton}"
HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterial Kind="Link" Width="14" Height="14"
Margin="0,0,7,0" VerticalAlignment="Center"/>
<TextBlock Text="Connect to eBay" VerticalAlignment="Center"/>
</StackPanel>
</Button>
</StackPanel>
</Border>
</Grid>
</TabItem>
</TabControl>
<!-- Status bar -->
<Border Grid.Row="1"
<Border Grid.Row="2"
Background="{DynamicResource MahApps.Brushes.Gray9}"
BorderThickness="0,1,0,0"
BorderBrush="{DynamicResource MahApps.Brushes.Gray7}">
@@ -282,6 +177,13 @@
<TextBlock x:Name="StatusBarEbay" Text="eBay: disconnected"
FontSize="11" VerticalAlignment="Center"
Foreground="{DynamicResource MahApps.Brushes.Gray3}"/>
<!-- Disconnect button shown when connected -->
<Button x:Name="DisconnectBtn" Click="DisconnectBtn_Click"
Visibility="Collapsed"
Style="{StaticResource MahApps.Styles.Button.Square}"
Padding="6,2" Margin="8,0,0,0" FontSize="10">
<TextBlock Text="Disconnect"/>
</Button>
</StackPanel>
</Grid>
</Border>

View File

@@ -31,18 +31,13 @@ public partial class MainWindow : MetroWindow
_priceService = new EbayPriceResearchService(_auth);
_priceLookupService = new PriceLookupService(_priceService, _savedService, _aiService);
// Photo Analysis tab — no eBay needed
PhotoView.Initialise(_aiService, _savedService, _priceService);
PhotoView.UseDetailsRequested += OnUseDetailsRequested;
var defaultPostcode = config["Ebay:DefaultPostcode"] ?? "";
// Saved Listings tab
SavedView.Initialise(_savedService, _priceLookupService);
NewListingView.Initialise(_listingService, _categoryService, _aiService, _auth,
_savedService, defaultPostcode);
// New Listing + Bulk tabs
SingleView.Initialise(_listingService, _categoryService, _aiService, _auth);
BulkView.Initialise(_listingService, _categoryService, _aiService, _bulkService, _auth);
SavedView.Initialise(_savedService, _priceLookupService, _listingService, _auth);
// Try to restore saved eBay session
_auth.TryLoadSavedToken();
UpdateConnectionState();
}
@@ -52,7 +47,7 @@ public partial class MainWindow : MetroWindow
private async void ConnectBtn_Click(object sender, RoutedEventArgs e)
{
ConnectBtn.IsEnabled = false;
SetStatus("Connecting to eBay");
SetStatus("Connecting to eBay...");
try
{
var username = await _auth.LoginAsync();
@@ -68,14 +63,14 @@ public partial class MainWindow : MetroWindow
finally
{
ConnectBtn.IsEnabled = true;
UpdateConnectionState(); // always sync UI to actual auth state
UpdateConnectionState();
}
}
private void DisconnectBtn_Click(object sender, RoutedEventArgs e)
{
_auth.Disconnect();
_listingService.ClearCache(); // clear cached policy/location IDs for next login
_listingService.ClearCache();
UpdateConnectionState();
SetStatus("Disconnected from eBay.");
}
@@ -83,50 +78,42 @@ public partial class MainWindow : MetroWindow
private void UpdateConnectionState()
{
var connected = _auth.IsConnected;
// Per-tab overlays (Photo Analysis tab has no overlay)
NewListingOverlay.Visibility = connected ? Visibility.Collapsed : Visibility.Visible;
BulkOverlay.Visibility = connected ? Visibility.Collapsed : Visibility.Visible;
ConnectBtn.Visibility = connected ? Visibility.Collapsed : Visibility.Visible;
DisconnectBtn.Visibility = connected ? Visibility.Visible : Visibility.Collapsed;
if (connected)
{
StatusDot.Fill = new SolidColorBrush(Colors.LimeGreen);
StatusLabel.Text = $"eBay: {_auth.ConnectedUsername}";
StatusBarDot.Fill = new SolidColorBrush(Colors.LimeGreen);
StatusBarEbay.Text = $"eBay: {_auth.ConnectedUsername}";
StatusBarEbay.Foreground = new SolidColorBrush(Colors.LimeGreen);
DisconnectBtn.Visibility = Visibility.Visible;
}
else
{
StatusDot.Fill = new SolidColorBrush(Colors.Gray);
StatusLabel.Text = "eBay: not connected";
StatusBarDot.Fill = new SolidColorBrush(Color.FromRgb(0x88, 0x88, 0x88));
StatusBarEbay.Text = "eBay: disconnected";
StatusBarEbay.Foreground = (Brush)FindResource("MahApps.Brushes.Gray5");
DisconnectBtn.Visibility = Visibility.Collapsed;
}
}
// ---- Photo Analysis → New Listing handoff ----
// ---- File menu ----
private void OnUseDetailsRequested(PhotoAnalysisResult result, IReadOnlyList<string> photoPaths, decimal price)
private void BulkImport_Click(object sender, RoutedEventArgs e)
{
SingleView.PopulateFromAnalysis(result, photoPaths, price); // Q1: forward all photos
// BulkImportWindow is created in Task 7; placeholder for now
MessageBox.Show("Bulk Import coming in the next step.", "Bulk Import",
MessageBoxButton.OK, MessageBoxImage.Information);
}
public void SwitchToNewListingTab()
{
MainTabs.SelectedItem = NewListingTab;
}
private void Exit_Click(object sender, RoutedEventArgs e) => Close();
public void RefreshSavedListings()
{
SavedView.RefreshList();
}
// ---- Helpers ----
// ---- Public interface for child views ----
public void SetStatus(string message) => StatusBar.Text = message;
public void SwitchToNewListingTab() => MainTabs.SelectedItem = NewListingTab;
public void RefreshDrafts() => SavedView.RefreshList();
public void RefreshSavedListings() => RefreshDrafts(); // backwards compat for NewListingView
}