From acce14c00044db8befe8b6d2593c1983eafa5382 Mon Sep 17 00:00:00 2001 From: dlawler489 <104159223@student.swin.edu.au> Date: Sat, 13 Jun 2026 11:37:12 +1000 Subject: [PATCH] Add Resolve Items flow for unmatched Etsy sync titles Reuses the missing-products modal on the Settings page: each unmatched listing title can be aliased to an existing product or created with a printing cost, then orders re-sync automatically to fill in costs. Co-Authored-By: Claude Fable 5 --- client/src/pages/Settings.tsx | 38 +++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/client/src/pages/Settings.tsx b/client/src/pages/Settings.tsx index dd7d7c8..8b9ce3a 100644 --- a/client/src/pages/Settings.tsx +++ b/client/src/pages/Settings.tsx @@ -2,7 +2,8 @@ import { useState, useEffect } from 'react'; import { useDispatch } from 'react-redux'; import { DataManager } from '../utils/dataManager'; import { setOrders } from '../store/slices/orderSlice'; -import { Trash2, Download, RefreshCw, AlertTriangle, Database, Store, Link2, Unlink } from 'lucide-react'; +import { MissingProductsModal } from '../components/MissingProductsModal'; +import { Trash2, Download, RefreshCw, AlertTriangle, Database, Store, Link2, Unlink, Wrench } from 'lucide-react'; import toast from 'react-hot-toast'; import api from '../utils/api'; @@ -40,6 +41,7 @@ const Settings = () => { const [isConnecting, setIsConnecting] = useState(false); const [isSyncing, setIsSyncing] = useState(false); const [unmatchedItems, setUnmatchedItems] = useState([]); + const [showResolveModal, setShowResolveModal] = useState(false); useEffect(() => { updateStorageSummary(); @@ -230,17 +232,27 @@ const Settings = () => { {unmatchedItems.length > 0 && (
-

- {unmatchedItems.length} item title(s) couldn't be matched to your product catalog - (their orders were synced without cost data): -

+
+

+ {unmatchedItems.length} item title(s) couldn't be matched to your product catalog + (their orders were synced without cost data): +

+ +
    {unmatchedItems.map((title, idx) => (
  • {title}
  • ))}

- Add these as products (or aliases on existing products) and sync again to fill in costs. + Click Resolve Items to match each title to an existing product (saved as an alias) + or create it with a printing cost — then orders re-sync with costs automatically.

)} @@ -456,6 +468,20 @@ const Settings = () => {

Application Settings

Additional application settings will be available here in future updates.

+ + {/* Resolve unmatched Etsy items: map to existing products (alias) or create new */} + {showResolveModal && ( + ({ title, quantity: 1 }))} + onClose={() => setShowResolveModal(false)} + onComplete={() => { + setShowResolveModal(false); + setUnmatchedItems([]); + toast.success('Products resolved — re-syncing orders with costs…'); + handleEtsySync(); + }} + /> + )} ); };