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 <noreply@anthropic.com>
This commit is contained in:
parent
e09f082420
commit
acce14c000
1 changed files with 32 additions and 6 deletions
|
|
@ -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<string[]>([]);
|
||||
const [showResolveModal, setShowResolveModal] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
updateStorageSummary();
|
||||
|
|
@ -230,17 +232,27 @@ const Settings = () => {
|
|||
|
||||
{unmatchedItems.length > 0 && (
|
||||
<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
|
||||
<p className="text-yellow-800 font-medium text-sm mb-2">
|
||||
{unmatchedItems.length} item title(s) couldn't be matched to your product catalog
|
||||
(their orders were synced without cost data):
|
||||
</p>
|
||||
<div className="flex items-start justify-between gap-4 mb-2">
|
||||
<p className="text-yellow-800 font-medium text-sm">
|
||||
{unmatchedItems.length} item title(s) couldn't be matched to your product catalog
|
||||
(their orders were synced without cost data):
|
||||
</p>
|
||||
<button
|
||||
onClick={() => setShowResolveModal(true)}
|
||||
className="flex items-center gap-2 px-3 py-2 bg-yellow-600 text-white rounded-lg hover:bg-yellow-700 text-sm whitespace-nowrap"
|
||||
>
|
||||
<Wrench className="w-4 h-4" />
|
||||
Resolve Items
|
||||
</button>
|
||||
</div>
|
||||
<ul className="text-yellow-700 text-sm list-disc list-inside space-y-1">
|
||||
{unmatchedItems.map((title, idx) => (
|
||||
<li key={idx}>{title}</li>
|
||||
))}
|
||||
</ul>
|
||||
<p className="text-yellow-700 text-xs mt-2">
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -456,6 +468,20 @@ const Settings = () => {
|
|||
<h2 className="text-xl font-semibold text-gray-900 mb-4">Application Settings</h2>
|
||||
<p className="text-gray-600">Additional application settings will be available here in future updates.</p>
|
||||
</div>
|
||||
|
||||
{/* Resolve unmatched Etsy items: map to existing products (alias) or create new */}
|
||||
{showResolveModal && (
|
||||
<MissingProductsModal
|
||||
missingProducts={unmatchedItems.map(title => ({ title, quantity: 1 }))}
|
||||
onClose={() => setShowResolveModal(false)}
|
||||
onComplete={() => {
|
||||
setShowResolveModal(false);
|
||||
setUnmatchedItems([]);
|
||||
toast.success('Products resolved — re-syncing orders with costs…');
|
||||
handleEtsySync();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue