import React, { useMemo } from 'react'; import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'; import { BSRRecord } from '../types'; import { BuyBoxWarningBadge } from './BuyBoxWarningBadge'; interface VendorDataViewProps { bsrData: BSRRecord[]; asinMetadata?: Map; buyBoxLostMap?: Map }>; } interface ChartPoint { label: string; sortKey: string; [key: string]: number | string | null; } const VendorDataView: React.FC = ({ bsrData = [], asinMetadata, buyBoxLostMap }) => { const activeMarkets = useMemo(() => { const m = new Set(bsrData.map(r => r.market)); return Array.from(m).sort(); }, [bsrData]); const useDailyResolution = useMemo(() => { const withDate = bsrData.filter(r => r.date).length; return withDate > bsrData.length / 2; }, [bsrData]); const uniqueAsins = useMemo(() => { const asinSet = new Set(bsrData.map(r => r.asin.trim().toUpperCase())); return Array.from(asinSet); }, [bsrData]); const productInfo = useMemo(() => { if (uniqueAsins.length !== 1) return null; const asin = uniqueAsins[0]; const metadata = asinMetadata?.get(asin); if (!metadata) return null; let topCategory = ''; let detailCategory = ''; for (const r of bsrData) { if (!topCategory && r.topLevelName) topCategory = r.topLevelName; if (!detailCategory && r.detailLevelName) detailCategory = r.detailLevelName; if (topCategory && detailCategory) break; } return { asin, sku: metadata.sku, title: metadata.title, line: metadata.line, topCategory, detailCategory }; }, [uniqueAsins, asinMetadata, bsrData]); const { topBsrChartData, detailBsrChartData, ratingChartData } = useMemo(() => { const byBucket = new Map(); bsrData.forEach(r => { const key = useDailyResolution && r.date ? r.date : `W${String(r.week).padStart(2, '0')}`; if (!byBucket.has(key)) byBucket.set(key, []); byBucket.get(key)!.push(r); }); const sortedKeys = Array.from(byBucket.keys()).sort(); const topBsrChartData: ChartPoint[] = []; const detailBsrChartData: ChartPoint[] = []; const ratingChartData: ChartPoint[] = []; sortedKeys.forEach(key => { const rows = byBucket.get(key)!; let label: string; if (useDailyResolution && key.includes('-')) { const d = new Date(key + 'T12:00:00Z'); label = d.toLocaleDateString('en-GB', { day: '2-digit', month: 'short' }); } else { label = key; } const topPoint: ChartPoint = { label, sortKey: key }; const detailPoint: ChartPoint = { label, sortKey: key }; const ratingPoint: ChartPoint = { label, sortKey: key }; activeMarkets.forEach(m => { const marketRows = rows.filter(r => r.market === m); const topBsrRows = marketRows.filter(r => r.topLevelBSR != null); topPoint[`${m}_bsr`] = topBsrRows.length > 0 ? Math.round(topBsrRows.reduce((sum, r) => sum + r.topLevelBSR!, 0) / topBsrRows.length) : null; const detailBsrRows = marketRows.filter(r => r.detailLevelBSR != null); detailPoint[`${m}_bsr`] = detailBsrRows.length > 0 ? Math.round(detailBsrRows.reduce((sum, r) => sum + r.detailLevelBSR!, 0) / detailBsrRows.length) : null; const ratingRows = marketRows.filter(r => r.avgRating != null); ratingPoint[`${m}_rating`] = ratingRows.length > 0 ? Math.round((ratingRows.reduce((sum, r) => sum + r.avgRating!, 0) / ratingRows.length) * 10) / 10 : null; }); topBsrChartData.push(topPoint); detailBsrChartData.push(detailPoint); ratingChartData.push(ratingPoint); }); return { topBsrChartData, detailBsrChartData, ratingChartData }; }, [bsrData, activeMarkets, useDailyResolution]); if (bsrData.length === 0) { return (

No BSR Data Yet

Ensure BSR.xlsx is present and loading to see Top Level BSR, Detail Level BSR, and Average Rating trends.

); } // Exact color values based on the screenshot const cardBg = '#161b24'; const orangeHex = '#f37526'; const cyanHex = '#2acbd6'; const purpleHex = '#7950f2'; const gridLineColor = '#ffffff'; return (
{/* Product Details Header Card */} {productInfo && (
PRODUCT DETAILS

{productInfo.title}

SKU: {productInfo.sku}
ASIN: {productInfo.asin}
)} {/* Top Level BSR Trend Chart */}

Top Level BSR Trend

{productInfo?.topCategory && ( {productInfo.topCategory} )}

Weekly Average Rank • Lower is better

{activeMarkets.map((m) => ( ))}
{/* Exact Legend matching screenshot */}
{activeMarkets.length > 0 && (
{activeMarkets[0]} BSR
)}
{/* Detail Level BSR Trend Chart */}

Detail Level BSR Trend

{productInfo?.detailCategory && ( {productInfo.detailCategory} )}

Sub-category Performance • Filtered ASINs

{activeMarkets.map((m) => ( ))}
{/* Exact Legend matching screenshot */}
Category Rank
{/* Average Rating Chart */}

Average Rating

Weekly Average (1.0 - 5.0)

{activeMarkets.map((m) => ( ))}
{/* Exact Legend matching screenshot */}
Star Rating
); }; export default VendorDataView;