diff --git a/components/WeeklyGrid.tsx b/components/WeeklyGrid.tsx index 81987b9..7f99d5d 100644 --- a/components/WeeklyGrid.tsx +++ b/components/WeeklyGrid.tsx @@ -9,6 +9,21 @@ interface WeeklyGridProps { 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 } = {}; @@ -24,58 +39,71 @@ const WeeklyGrid: React.FC = ({ data }) => { const isPositive = pct >= 0; return ( -
+
{isPositive ? '▲' : '▼'}{Math.abs(pct).toFixed(0)}%
); }; return ( -
+
- +
- + {weeks.map(week => ( - ))} - - + + {weeks.map((week, idx) => ( - ))} - {rows.map((row) => ( - - - {weeks.map((week, idx) => { - const val = row.unitsByWeek[week] || 0; - const prevVal = row.unitsByWeek[weeks[idx + 1]] || 0; - return ( - + + + {lineRows.map((row) => ( + + - ); - })} - + {weeks.map((week, idx) => { + const val = row.unitsByWeek[week] || 0; + const prevVal = row.unitsByWeek[weeks[idx + 1]] || 0; + return ( + + ); + })} + + ))} + ))}
Product DetailsProduct Details + {week.split('-')[1]}/{week.split('-')[0].slice(-2)}
Totals
TOTALS - {weekTotals[week]?.toLocaleString('de-DE')} - {renderGrowth(weekTotals[week], weekTotals[weeks[idx + 1]])} + +
+ {weekTotals[week]?.toLocaleString('de-DE')} + {renderGrowth(weekTotals[week], weekTotals[weeks[idx + 1]])} +
-
- {row.sku} - {row.title} - {row.line} -
-
- 0 ? 'text-white' : 'text-slate-600'}`}> - {val > 0 ? val.toLocaleString('de-DE') : '-'} - - {val > 0 && renderGrowth(val, prevVal)} + {Object.entries(groupedRows).map(([line, lineRows]) => ( + + {/* Category Header */} +
+ {line} +
+
+ {row.sku} + {row.title} +
+
+ 0 ? 'text-white' : 'text-slate-700'}`}> + {val > 0 ? val.toLocaleString('de-DE') : '-'} + + {val > 0 && renderGrowth(val, prevVal)} +
+