mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 13:45:23 +02:00
fix(vendor): replace ASIN text input with MultiSelectDropdown for proper filtering
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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
7f5aa1b812
commit
a6b7503c82
@@ -24,24 +24,27 @@ interface ChartPoint {
|
|||||||
const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData }) => {
|
const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData }) => {
|
||||||
// Filters
|
// Filters
|
||||||
const [selectedMarkets, setSelectedMarkets] = useState<string[]>([]);
|
const [selectedMarkets, setSelectedMarkets] = useState<string[]>([]);
|
||||||
|
const [selectedAsins, setSelectedAsins] = useState<string[]>([]);
|
||||||
const [selectedTopCats, setSelectedTopCats] = useState<string[]>([]);
|
const [selectedTopCats, setSelectedTopCats] = useState<string[]>([]);
|
||||||
const [selectedDetailCats, setSelectedDetailCats] = useState<string[]>([]);
|
const [selectedDetailCats, setSelectedDetailCats] = useState<string[]>([]);
|
||||||
const [asinSearch, setAsinSearch] = useState('');
|
|
||||||
|
|
||||||
// Extract available filter options from the dataset
|
// Extract available filter options from the dataset
|
||||||
const { availableMarkets, availableTopCats, availableDetailCats } = useMemo(() => {
|
const { availableMarkets, availableAsins, availableTopCats, availableDetailCats } = useMemo(() => {
|
||||||
const markets = new Set<string>();
|
const markets = new Set<string>();
|
||||||
|
const asins = new Set<string>();
|
||||||
const topCats = new Set<string>();
|
const topCats = new Set<string>();
|
||||||
const detailCats = new Set<string>();
|
const detailCats = new Set<string>();
|
||||||
|
|
||||||
bsrData.forEach(r => {
|
bsrData.forEach(r => {
|
||||||
if (r.market) markets.add(r.market);
|
if (r.market) markets.add(r.market);
|
||||||
|
if (r.asin) asins.add(r.asin);
|
||||||
if (r.topLevelName) topCats.add(r.topLevelName);
|
if (r.topLevelName) topCats.add(r.topLevelName);
|
||||||
if (r.detailLevelName) detailCats.add(r.detailLevelName);
|
if (r.detailLevelName) detailCats.add(r.detailLevelName);
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
availableMarkets: Array.from(markets).sort(),
|
availableMarkets: Array.from(markets).sort(),
|
||||||
|
availableAsins: Array.from(asins).sort(),
|
||||||
availableTopCats: Array.from(topCats).sort(),
|
availableTopCats: Array.from(topCats).sort(),
|
||||||
availableDetailCats: Array.from(detailCats).sort()
|
availableDetailCats: Array.from(detailCats).sort()
|
||||||
};
|
};
|
||||||
@@ -54,19 +57,18 @@ const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData }) => {
|
|||||||
if (selectedMarkets.length > 0) {
|
if (selectedMarkets.length > 0) {
|
||||||
result = result.filter(r => selectedMarkets.includes(r.market));
|
result = result.filter(r => selectedMarkets.includes(r.market));
|
||||||
}
|
}
|
||||||
|
if (selectedAsins.length > 0) {
|
||||||
|
result = result.filter(r => selectedAsins.includes(r.asin));
|
||||||
|
}
|
||||||
if (selectedTopCats.length > 0) {
|
if (selectedTopCats.length > 0) {
|
||||||
result = result.filter(r => r.topLevelName && selectedTopCats.includes(r.topLevelName));
|
result = result.filter(r => r.topLevelName && selectedTopCats.includes(r.topLevelName));
|
||||||
}
|
}
|
||||||
if (selectedDetailCats.length > 0) {
|
if (selectedDetailCats.length > 0) {
|
||||||
result = result.filter(r => r.detailLevelName && selectedDetailCats.includes(r.detailLevelName));
|
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;
|
return result;
|
||||||
}, [bsrData, selectedMarkets, selectedTopCats, selectedDetailCats, asinSearch]);
|
}, [bsrData, selectedMarkets, selectedAsins, selectedTopCats, selectedDetailCats]);
|
||||||
|
|
||||||
// Determine active markets in filtered data for series generation
|
// Determine active markets in filtered data for series generation
|
||||||
const activeMarkets = useMemo(() => {
|
const activeMarkets = useMemo(() => {
|
||||||
@@ -172,6 +174,12 @@ const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData }) => {
|
|||||||
selected={selectedMarkets}
|
selected={selectedMarkets}
|
||||||
onChange={setSelectedMarkets}
|
onChange={setSelectedMarkets}
|
||||||
/>
|
/>
|
||||||
|
<MultiSelectDropdown
|
||||||
|
label="ASIN"
|
||||||
|
options={availableAsins}
|
||||||
|
selected={selectedAsins}
|
||||||
|
onChange={setSelectedAsins}
|
||||||
|
/>
|
||||||
<MultiSelectDropdown
|
<MultiSelectDropdown
|
||||||
label="Top Level Category"
|
label="Top Level Category"
|
||||||
options={availableTopCats}
|
options={availableTopCats}
|
||||||
@@ -184,20 +192,13 @@ const VendorDataView: React.FC<VendorDataViewProps> = ({ bsrData }) => {
|
|||||||
selected={selectedDetailCats}
|
selected={selectedDetailCats}
|
||||||
onChange={setSelectedDetailCats}
|
onChange={setSelectedDetailCats}
|
||||||
/>
|
/>
|
||||||
<input
|
{(selectedMarkets.length > 0 || selectedAsins.length > 0 || selectedTopCats.length > 0 || selectedDetailCats.length > 0) && (
|
||||||
type="text"
|
|
||||||
placeholder="Search ASINs (comma-separated)"
|
|
||||||
value={asinSearch}
|
|
||||||
onChange={e => 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) && (
|
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedMarkets([]);
|
setSelectedMarkets([]);
|
||||||
|
setSelectedAsins([]);
|
||||||
setSelectedTopCats([]);
|
setSelectedTopCats([]);
|
||||||
setSelectedDetailCats([]);
|
setSelectedDetailCats([]);
|
||||||
setAsinSearch('');
|
|
||||||
}}
|
}}
|
||||||
className="text-xs text-slate-400 hover:text-white underline"
|
className="text-xs text-slate-400 hover:text-white underline"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user