- Add Content-Language: en-US to CreateOfferAsync (eBay Inventory API requires it)
- Double thumbnail sizes in NewListingView (96→192, 100→200)
- Sync NewListingView.xaml/.cs from Windows (replaces SingleItemView)
- Sync latest AiAssistantService, SavedListingsService, MainWindow, SavedListingsView from Windows
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
eBay Inventory API rejects numeric condition IDs (e.g. "3000") and requires
string enums (e.g. "USED_VERY_GOOD"). Was causing 400 errors on every post attempt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Task 8: Convert aspects Dictionary<string,string> to Dictionary<string,string[]> in CreateInventoryItemAsync
- Task 9: Set Postage to RoyalMailTracked48 and ShippingCost to 3.49m on BulkImportRow.ToListingDraft()
Implements LoadAspectsAsync/RebuildAspectFields, real PostageBox and AiAspects
handlers, ShippingCostBox wiring, required-aspects validation, and aspects
reset on new listing. Also registers EbayAspectsService in MainWindow (Task 6).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Slider ValueChanged fires during XAML init before named controls exist.
Guard with IsLoaded check, same pattern as UpdateCardTitleBar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
Fixes Windows git showing modified files after Linux commits.
LF stored in repo; CRLF on Windows checkout for all source files.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PriceLookupService: eBay live data → saved listing history → AI estimate,
each result labelled by source so the user knows how reliable it is
- Revalue row: new "Check eBay" button fetches suggestion and pre-populates
the price field; shows source label beneath (or "No suggestion available")
- Category auto-fill: AutoFillCategoryAsync takes the top eBay category
suggestion and fills the field automatically after photo analysis or AI
title generation; dropdown stays visible so user can override
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Dark theme experiment abandoned due to persistent contrast issues.
All Gray3/Gray4 muted text reverted to Gray5/Gray6 (darker = readable
on light background). Gray2 headings reverted to Gray4/Gray5.
App.xaml switched back to Light.Indigo.xaml.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Price text changed from Accent brush (~3.4:1) to ThemeForeground (white)
for WCAG AA compliance. Date text changed from Gray5 (~3.2:1) to Gray3.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Indigo 500 (#3F51B5) is too dark on black backgrounds. Cobalt (#0050EF)
is a bright electric blue that meets contrast requirements on dark
surfaces without needing lighter fallback shades.
Replaced all hardcoded #9FA8DA (Indigo 200 workaround) with
{DynamicResource MahApps.Brushes.Accent} now that the accent is
naturally readable — section headings, price labels, detail labels,
listing URL link.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All text using Gray5/Gray6 (too dark — fails WCAG AA) promoted to
Gray3/Gray4 as appropriate. SectionHeading styles using Accent brush
(Indigo 500, ~2.8:1 on dark bg) changed to #9FA8DA (Indigo 200, ~7:1).
MainWindow: overlay body text Gray5→Gray3, status bar text Gray5→Gray3.
PhotoAnalysisView: SectionHeading Accent→#9FA8DA; 13 text nodes updated
from Gray5/Gray6 to Gray3/Gray4 (hints, labels, counters, live price
status, price reasoning, range bar labels).
SingleItemView: SectionHeading Accent→#9FA8DA; title/desc counters,
photo drop hint, listing URL all updated.
BulkImportView: empty state heading Gray4→Gray2; hint text Gray6→Gray4.
SavedListingsView: DetailLabel Accent→#9FA8DA; search icon, empty state
headings, meta row text/icons all promoted from Gray4-6 to Gray2-4.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Switch MahApps.Metro base theme from Light.Indigo to Dark.Indigo in
App.xaml. Fix hardcoded light-specific colours in all five views:
- MainWindow: overlay backgrounds from hardcoded light-blue gradients
to ThemeBackground; overlay text updated to ThemeForeground / Gray5
- SingleItemView: listing URL colour from hardcoded #1565C0 (invisible
on dark) to Accent brush
- PhotoAnalysisView / BulkImportView / SavedListingsView: dynamic
resource brushes already used; no structural changes needed
Semantic colours (green/red/amber indicators, AI gradient buttons,
white text on coloured backgrounds) left unchanged as they read
correctly on dark surfaces.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
App no longer crashes on startup when appsettings.json is absent (e.g.
fresh clone). Configuration is loaded from appsettings.json if present,
then overridden by appsettings.local.json if that exists. Both files
are gitignored to keep secrets out of the repo.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Business policies: EnsurePoliciesAndLocationAsync fetches fulfillment,
payment and return policy IDs from the seller's eBay Account API on
first post and caches them for the session. Uses the first policy of
each type; gives a clear error pointing to My eBay → Business policies
if none are configured.
Merchant location: checks for existing locations via
GET /sell/inventory/v1/location; if none found, creates a 'home'
location using the seller's postcode. Location key is cached so the
check only runs once. Cache cleared on disconnect so it works
correctly after switching accounts.
CreateOfferAsync now sends real fulfillmentPolicyId / paymentPolicyId /
returnPolicyId instead of hardcoded policy name strings, and uses the
resolved merchantLocationKey instead of the hardcoded "home" string.
Removed BuildListingPolicies (inline shipping service codes no longer
needed; shipping is governed by the fulfillment policy).
Shared HttpClient: replaced BuildClient() (which returned a new
HttpClient per call) with a static _http client and MakeRequest()
helper that creates a pre-authorised HttpRequestMessage. UploadSinglePhotoAsync
likewise uses a static _photoHttp client and HttpRequestMessage instead
of new HttpClient() per photo.
Removed placeholder ExternalPictureURL from Trading API SOAP body.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Photos can now be dragged to any position — cursor changes to a move
cursor to signal draggability, the drop target dims to show the
insertion point, and the list rebuilds immediately after the drop.
First photo gets a 'Cover' badge since eBay uses it as the gallery
hero image. All add/remove/clear operations now go through
RebuildPhotoThumbnails() so the panel always reflects the true order
in PhotoPaths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After photo analysis completes, fires a background request to the
eBay Browse API (app-level auth, no user login needed) to fetch
current Buy It Now prices for similar items on eBay UK.
- EbayAuthService.GetAppTokenAsync(): client credentials OAuth flow,
cached for the token lifetime
- EbayPriceResearchService: searches /buy/browse/v1/item_summary/search
filtered to FIXED_PRICE + EBAY_GB, returns min/max/median/suggested
(suggested = 40th percentile — competitive but not cheapest)
- PhotoAnalysisView: shows spinner + "Checking live eBay UK prices…",
then updates price badge, range bar and PriceOverride with real data,
plus a "Based on N live listings (£X – £Y)" label
Silently degrades if eBay credentials are not configured.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PriceSuggestedText was not being refreshed when Refine with AI ran,
so the badge still showed the original price even though PriceOverride
had been updated.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a Corrections box and "Refine with AI" button below the
description. User types what the AI got wrong (e.g. "earrings are
white gold with diamonds, not silver and zirconium") and clicks
Refine — the AI rewrites the title, description and price while
keeping all other analysis fields intact.
AiAssistantService.RefineWithCorrectionsAsync() sends the current
listing text + corrections as a single text prompt and parses the
JSON response back into the title/description/price fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
TableRowsPlusAfter, InformationOutline and LinkOff don't exist in
IconPacks 4.11.0. Replaced with TablePlus, AlertCircleOutline,
LinkVariantOff. Audited all XAML files via DLL reflection — no
further invalid icon names remain.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CameraSearch, ShoppingSearch, TagSearchOutline, ImagePlusOutline,
and FolderOpenOutline don't exist in this version of the package.
Replaced with valid equivalents: Camera, CartOutline, TagOutline,
ImagePlus, FolderOpen.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
C# WPF desktop app for creating eBay UK listings with AI-powered
photo analysis. Features: multi-photo vision analysis via OpenRouter
(Claude), local listing save/export, saved listings browser,
single item listing form, bulk import from CSV/Excel, and eBay
OAuth authentication.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>