From a6b7503c82a6a0ca0a127af3ef1a29f712bc573c Mon Sep 17 00:00:00 2001 From: "christian.vidal" Date: Mon, 2 Mar 2026 20:16:27 +0100 Subject: [PATCH] fix(vendor): replace ASIN text input with MultiSelectDropdown for proper filtering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The free-text ASIN search was unclear and not working as expected. Replace it with a proper MultiSelectDropdown (same as Market/Category filters) — selecting an ASIN now strictly filters chart data to that ASIN only. Co-Authored-By: Claude Sonnet 4.6 --- components/VendorDataView.tsx | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/components/VendorDataView.tsx b/components/VendorDataView.tsx index 4fb9493..98b0151 100644 --- a/components/VendorDataView.tsx +++ b/components/VendorDataView.tsx @@ -24,24 +24,27 @@ interface ChartPoint { const VendorDataView: React.FC = ({ bsrData }) => { // Filters const [selectedMarkets, setSelectedMarkets] = useState([]); + const [selectedAsins, setSelectedAsins] = useState([]); const [selectedTopCats, setSelectedTopCats] = useState([]); const [selectedDetailCats, setSelectedDetailCats] = useState([]); - const [asinSearch, setAsinSearch] = useState(''); // Extract available filter options from the dataset - const { availableMarkets, availableTopCats, availableDetailCats } = useMemo(() => { + const { availableMarkets, availableAsins, availableTopCats, availableDetailCats } = useMemo(() => { const markets = new Set(); + const asins = new Set(); const topCats = new Set(); const detailCats = new Set(); bsrData.forEach(r => { if (r.market) markets.add(r.market); + if (r.asin) asins.add(r.asin); if (r.topLevelName) topCats.add(r.topLevelName); if (r.detailLevelName) detailCats.add(r.detailLevelName); }); return { availableMarkets: Array.from(markets).sort(), + availableAsins: Array.from(asins).sort(), availableTopCats: Array.from(topCats).sort(), availableDetailCats: Array.from(detailCats).sort() }; @@ -54,19 +57,18 @@ const VendorDataView: React.FC = ({ bsrData }) => { if (selectedMarkets.length > 0) { result = result.filter(r => selectedMarkets.includes(r.market)); } + if (selectedAsins.length > 0) { + result = result.filter(r => selectedAsins.includes(r.asin)); + } if (selectedTopCats.length > 0) { result = result.filter(r => r.topLevelName && selectedTopCats.includes(r.topLevelName)); } if (selectedDetailCats.length > 0) { result = result.filter(r => r.detailLevelName && selectedDetailCats.includes(r.detailLevelName)); } - if (asinSearch.trim()) { - const terms = asinSearch.toLowerCase().split(',').map(t => t.trim()).filter(Boolean); - result = result.filter(r => terms.some(t => r.asin.toLowerCase().includes(t))); - } return result; - }, [bsrData, selectedMarkets, selectedTopCats, selectedDetailCats, asinSearch]); + }, [bsrData, selectedMarkets, selectedAsins, selectedTopCats, selectedDetailCats]); // Determine active markets in filtered data for series generation const activeMarkets = useMemo(() => { @@ -172,6 +174,12 @@ const VendorDataView: React.FC = ({ bsrData }) => { selected={selectedMarkets} onChange={setSelectedMarkets} /> + = ({ bsrData }) => { selected={selectedDetailCats} onChange={setSelectedDetailCats} /> - setAsinSearch(e.target.value)} - className="bg-slate-900 border border-slate-700 rounded-lg px-3 py-2 text-sm text-slate-200 placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 w-64" - /> - {(selectedMarkets.length > 0 || selectedTopCats.length > 0 || selectedDetailCats.length > 0 || asinSearch) && ( + {(selectedMarkets.length > 0 || selectedAsins.length > 0 || selectedTopCats.length > 0 || selectedDetailCats.length > 0) && (