Add Buy Box Lost detection feature with visual warning badges

This commit is contained in:
Christian Vidal Wolf
2026-01-29 09:42:39 +01:00
parent e4fbdb60b1
commit 04b208969d
7 changed files with 138 additions and 8 deletions
+8 -2
View File
@@ -6,6 +6,7 @@ import { StockBadge } from './StockBadge';
import { WarehouseIcon, AmazonSmileIcon, CoverageIcon } from './Icons';
import { Top50Badge } from './Top50Badge';
import { VendorStockBadge } from './VendorStockBadge';
import { BuyBoxWarningBadge } from './BuyBoxWarningBadge';
import { InColumnStockFilter } from './InColumnStockFilter';
import { PAN_EU_COUNTRIES } from '../services/dataProcessor';
import {
@@ -26,6 +27,7 @@ interface ForecastViewProps {
onVendorStockFilterChange: (newFilters: string[]) => void;
wocFilter: string[];
onWocFilterChange: (newFilters: string[]) => void;
buyBoxLostMap?: Map<string, { countries: string[]; reasons: Record<string, string> }>;
}
const MONTH_ORDER = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
@@ -37,7 +39,8 @@ const ForecastRow: React.FC<{
top50Mode: 'eu' | 'uk';
stockMap?: Map<string, number>;
vendorStockMap?: Map<string, { eu: number; uk: number }>;
}> = React.memo(({ item, activeMonths, top50Ranking, top50Mode, stockMap, vendorStockMap }) => {
buyBoxLostMap?: Map<string, { countries: string[]; reasons: Record<string, string> }>;
}> = React.memo(({ item, activeMonths, top50Ranking, top50Mode, stockMap, vendorStockMap, buyBoxLostMap }) => {
const asin = item.asin.trim().toUpperCase();
const ranks: { rank: number; label: string; theme: 'amber' | 'blue' | 'indigo' }[] = [];
@@ -105,6 +108,7 @@ const ForecastRow: React.FC<{
)}
{/* WOC Indicator preserved */}
<VendorStockBadge asin={item.asin} vendorStockMap={vendorStockMap} mode={top50Mode} avgWeeklySales={item.avgWeeklySales} />
<BuyBoxWarningBadge asin={asin} buyBoxLostMap={buyBoxLostMap} />
</div>
</div>
</td>
@@ -174,7 +178,8 @@ const ForecastView: React.FC<ForecastViewProps> = ({
onVendorStockFilterChange,
wocFilter,
onWocFilterChange,
top50Mode
top50Mode,
buyBoxLostMap
}) => {
const [searchTerm, setSearchTerm] = useState('');
const [debouncedSearch, setDebouncedSearch] = useState('');
@@ -504,6 +509,7 @@ const ForecastView: React.FC<ForecastViewProps> = ({
top50Mode={top50Mode}
stockMap={stockMap}
vendorStockMap={vendorStockMap}
buyBoxLostMap={buyBoxLostMap}
/>
))}
</tbody>