From 4cf5f11c9f675c270caa7134e50f5f68bfdf3703 Mon Sep 17 00:00:00 2001 From: Peter Foster Date: Wed, 15 Apr 2026 09:57:32 +0100 Subject: [PATCH] feat: Relist button pre-populates form with aspects and shipping from saved listing Co-Authored-By: Claude Sonnet 4.6 --- EbayListingTool/Views/MainWindow.xaml.cs | 5 ++ .../Views/SavedListingsView.xaml.cs | 3 +- EbayListingTool/Views/SingleItemView.xaml.cs | 79 +++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/EbayListingTool/Views/MainWindow.xaml.cs b/EbayListingTool/Views/MainWindow.xaml.cs index 1b817b5..50d24c2 100644 --- a/EbayListingTool/Views/MainWindow.xaml.cs +++ b/EbayListingTool/Views/MainWindow.xaml.cs @@ -39,6 +39,11 @@ public partial class MainWindow : MetroWindow // Saved Listings tab SavedView.Initialise(_savedService, _priceLookupService); + SavedView.RelistRequested += listing => + { + SingleView.PopulateFromSavedListing(listing); + SwitchToNewListingTab(); + }; // New Listing + Bulk tabs SingleView.Initialise(_listingService, _categoryService, _aiService, _auth, _aspectsService, _savedService); diff --git a/EbayListingTool/Views/SavedListingsView.xaml.cs b/EbayListingTool/Views/SavedListingsView.xaml.cs index d753eca..c9538e7 100644 --- a/EbayListingTool/Views/SavedListingsView.xaml.cs +++ b/EbayListingTool/Views/SavedListingsView.xaml.cs @@ -806,6 +806,7 @@ public partial class SavedListingsView : UserControl private void RelistBtn_Click(object sender, RoutedEventArgs e) { - // TODO: implement in Task 5 + if (_selected != null) + RelistRequested?.Invoke(_selected); } } diff --git a/EbayListingTool/Views/SingleItemView.xaml.cs b/EbayListingTool/Views/SingleItemView.xaml.cs index 4aa71bb..3aed1ef 100644 --- a/EbayListingTool/Views/SingleItemView.xaml.cs +++ b/EbayListingTool/Views/SingleItemView.xaml.cs @@ -874,4 +874,83 @@ public partial class SingleItemView : UserControl AspectsItemsControl.ItemsSource = panels; AspectsPanel.Visibility = _currentAspects.Count > 0 ? Visibility.Visible : Visibility.Collapsed; } + + /// Pre-fills the form from a saved listing for relisting. + public async void PopulateFromSavedListing(SavedListing listing) + { + _draft = new ListingDraft { Postcode = PostcodeBox.Text }; + _draft.Sku = Guid.NewGuid().ToString("N")[..12].ToUpper(); // fresh SKU — not a duplicate + _currentAspects = new(); + _lastAspectsCategoryId = ""; + + TitleBox.Text = ""; + DescriptionBox.Text = ""; + CategoryBox.Text = ""; + CategoryIdLabel.Text = "(no category)"; + PriceBox.Value = 0; + QuantityBox.Value = 1; + ConditionBox.SelectedIndex = 3; + FormatBox.SelectedIndex = 0; + PhotosPanel.Children.Clear(); + UpdatePhotoPanel(); + AspectsPanel.Visibility = Visibility.Collapsed; + SuccessPanel.Visibility = Visibility.Collapsed; + PriceSuggestionPanel.Visibility = Visibility.Collapsed; + + TitleBox.Text = listing.Title; + DescriptionBox.Text = listing.Description; + PriceBox.Value = (double)listing.Price; + + // Condition + ConditionBox.SelectedIndex = listing.Condition switch + { + ItemCondition.New => 0, + ItemCondition.OpenBox => 1, + ItemCondition.Refurbished => 2, + ItemCondition.Used => 3, + ItemCondition.ForPartsOrNotWorking => 4, + _ => 3 + }; + + // Postage + shipping cost + PostageBox.SelectedIndex = listing.Postage switch + { + PostageOption.RoyalMailFirstClass => 0, + PostageOption.RoyalMailSecondClass => 1, + PostageOption.RoyalMailTracked24 => 2, + PostageOption.RoyalMailTracked48 => 3, + PostageOption.FreePostage => 4, + PostageOption.CollectionOnly => 5, + _ => 3 + }; + ShippingCostBox.Value = (double)listing.ShippingCost; + _draft.ShippingCost = listing.ShippingCost; + + // Category + if (!string.IsNullOrEmpty(listing.CategoryId)) + { + _suppressCategoryLookup = true; + _draft.CategoryId = listing.CategoryId; + _draft.CategoryName = listing.Category; + CategoryBox.Text = listing.Category; + CategoryIdLabel.Text = $"ID: {listing.CategoryId}"; + _suppressCategoryLookup = false; + } + + // Restore saved aspects into draft BEFORE LoadAspectsAsync so they aren't wiped + foreach (var kv in listing.Aspects) + _draft.Aspects[kv.Key] = kv.Value; + + // Photos + var validPaths = listing.PhotoPaths.Where(p => File.Exists(p)).ToArray(); + if (validPaths.Length > 0) + AddPhotos(validPaths); + + // Load aspects from API — set _lastAspectsCategoryId first so Clear() is skipped + if (!string.IsNullOrEmpty(listing.CategoryId)) + { + _lastAspectsCategoryId = listing.CategoryId; + await LoadAspectsAsync(listing.CategoryId); + } + } }