import React, { useMemo } from 'react'; import { CombinedKPIs } from '../types'; import { pivotWeeklySalesData, WeeklyPivotRow } from '../services/dataProcessor'; interface WeeklyGridProps { data: CombinedKPIs[]; } const WeeklyGrid: React.FC = ({ data }) => { const { rows, weeks } = useMemo(() => pivotWeeklySalesData(data), [data]); // Group rows by 'line' const groupedRows = useMemo(() => { const groups: { [line: string]: WeeklyPivotRow[] } = {}; rows.forEach(row => { const line = row.line || 'Uncategorized'; if (!groups[line]) groups[line] = []; groups[line].push(row); }); // Sort lines alphabetically return Object.keys(groups).sort().reduce((acc, line) => { acc[line] = groups[line]; return acc; }, {} as { [line: string]: WeeklyPivotRow[] }); }, [rows]); // Calculate totals per week const weekTotals = useMemo(() => { const totals: { [weekKey: string]: number } = {}; weeks.forEach(week => { totals[week] = rows.reduce((sum, row) => sum + (row.unitsByWeek[week] || 0), 0); }); return totals; }, [rows, weeks]); const renderGrowth = (current: number, previous: number) => { if (!previous || previous === 0) return null; const pct = ((current - previous) / previous) * 100; const isPositive = pct >= 0; return (
{isPositive ? '▲' : '▼'}{Math.abs(pct).toFixed(0)}%
); }; return (
{weeks.map(week => ( ))} {weeks.map((week, idx) => ( ))} {Object.entries(groupedRows).map(([line, lineRows]) => ( {/* Category Header */} {lineRows.map((row) => ( {weeks.map((week, idx) => { const val = row.unitsByWeek[week] || 0; const prevVal = row.unitsByWeek[weeks[idx + 1]] || 0; return ( ); })} ))} ))}
Product Details {week.split('-')[1]}/{week.split('-')[0].slice(-2)}
TOTALS
{weekTotals[week]?.toLocaleString('de-DE')} {renderGrowth(weekTotals[week], weekTotals[weeks[idx + 1]])}
{line}
{row.sku} {row.title}
0 ? 'text-white' : 'text-slate-700'}`}> {val > 0 ? val.toLocaleString('de-DE') : '-'} {val > 0 && renderGrowth(val, prevVal)}
); }; export default WeeklyGrid;