feat: Relist button pre-populates form with aspects and shipping from saved listing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Peter Foster
2026-04-15 09:57:32 +01:00
parent 18bd3b910f
commit 4cf5f11c9f
3 changed files with 86 additions and 1 deletions

View File

@@ -39,6 +39,11 @@ public partial class MainWindow : MetroWindow
// Saved Listings tab // Saved Listings tab
SavedView.Initialise(_savedService, _priceLookupService); SavedView.Initialise(_savedService, _priceLookupService);
SavedView.RelistRequested += listing =>
{
SingleView.PopulateFromSavedListing(listing);
SwitchToNewListingTab();
};
// New Listing + Bulk tabs // New Listing + Bulk tabs
SingleView.Initialise(_listingService, _categoryService, _aiService, _auth, _aspectsService, _savedService); SingleView.Initialise(_listingService, _categoryService, _aiService, _auth, _aspectsService, _savedService);

View File

@@ -806,6 +806,7 @@ public partial class SavedListingsView : UserControl
private void RelistBtn_Click(object sender, RoutedEventArgs e) private void RelistBtn_Click(object sender, RoutedEventArgs e)
{ {
// TODO: implement in Task 5 if (_selected != null)
RelistRequested?.Invoke(_selected);
} }
} }

View File

@@ -874,4 +874,83 @@ public partial class SingleItemView : UserControl
AspectsItemsControl.ItemsSource = panels; AspectsItemsControl.ItemsSource = panels;
AspectsPanel.Visibility = _currentAspects.Count > 0 ? Visibility.Visible : Visibility.Collapsed; AspectsPanel.Visibility = _currentAspects.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
} }
/// <summary>Pre-fills the form from a saved listing for relisting.</summary>
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);
}
}
} }