feat: redesign weight summary legend and add currency selector

Redesign WeightSummaryCard stats from a disconnected 4-column grid to a
compact legend-style list with color dots, percentages, and a divider
before the total row. Switch chart and legend colors to a neutral gray
palette.

Add a currency selector to settings (USD, EUR, GBP, JPY, CAD, AUD) that
changes the displayed symbol across the app. This is visual only — no
value conversion is performed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-16 20:33:07 +01:00
parent 4cb356d6b0
commit 9647f5759d
14 changed files with 470 additions and 145 deletions

View File

@@ -10,24 +10,25 @@ import {
import type { SetupItemWithCategory } from "../hooks/useSetups";
import { useWeightUnit } from "../hooks/useWeightUnit";
import { formatWeight, type WeightUnit } from "../lib/formatters";
import { LucideIcon } from "../lib/iconData";
const CATEGORY_COLORS = [
"#6366f1",
"#f59e0b",
"#10b981",
"#ef4444",
"#8b5cf6",
"#06b6d4",
"#f97316",
"#ec4899",
"#14b8a6",
"#84cc16",
"#374151",
"#4b5563",
"#6b7280",
"#7f8a94",
"#9ca3af",
"#b0b7bf",
"#c4c9cf",
"#d1d5db",
"#dfe2e6",
"#e5e7eb",
];
const CLASSIFICATION_COLORS: Record<string, string> = {
base: "#6366f1",
worn: "#f59e0b",
consumable: "#10b981",
base: "#6b7280",
worn: "#9ca3af",
consumable: "#d1d5db",
};
const CLASSIFICATION_LABELS: Record<string, string> = {
@@ -109,29 +110,34 @@ function CustomTooltip({
);
}
function SubtotalColumn({
function LegendRow({
color,
label,
weight,
unit,
color,
percent,
}: {
color: string;
label: string;
weight: number;
unit: WeightUnit;
color?: string;
percent?: number;
}) {
return (
<div className="flex flex-col items-center gap-1">
{color && (
<span
className="w-2.5 h-2.5 rounded-full"
style={{ backgroundColor: color }}
/>
)}
<span className="text-xs text-gray-500">{label}</span>
<span className="text-sm font-semibold text-gray-900">
<div className="flex items-center gap-3 py-1.5">
<span
className="w-2.5 h-2.5 rounded-full shrink-0"
style={{ backgroundColor: color }}
/>
<span className="text-sm text-gray-600 flex-1">{label}</span>
<span className="text-sm font-semibold text-gray-900 tabular-nums">
{formatWeight(weight, unit)}
</span>
{percent != null && (
<span className="text-xs text-gray-400 w-10 text-right tabular-nums">
{(percent * 100).toFixed(0)}%
</span>
)}
</div>
);
}
@@ -237,27 +243,39 @@ export function WeightSummaryCard({ items }: WeightSummaryCardProps) {
</ResponsiveContainer>
</div>
{/* Weight subtotals columns */}
<div className="flex-1 grid grid-cols-4 gap-4">
<SubtotalColumn
label="Base"
{/* Weight legend */}
<div className="flex-1 flex flex-col justify-center min-w-0">
<LegendRow
color="#6b7280"
label="Base Weight"
weight={baseWeight}
unit={unit}
color="#6366f1"
percent={totalWeight > 0 ? baseWeight / totalWeight : undefined}
/>
<SubtotalColumn
<LegendRow
color="#9ca3af"
label="Worn"
weight={wornWeight}
unit={unit}
color="#f59e0b"
percent={totalWeight > 0 ? wornWeight / totalWeight : undefined}
/>
<SubtotalColumn
<LegendRow
color="#d1d5db"
label="Consumable"
weight={consumableWeight}
unit={unit}
color="#10b981"
percent={totalWeight > 0 ? consumableWeight / totalWeight : undefined}
/>
<SubtotalColumn label="Total" weight={totalWeight} unit={unit} />
<div className="border-t border-gray-200 mt-1.5 pt-1.5">
<div className="flex items-center gap-3 py-1.5">
<LucideIcon name="sigma" size={10} className="text-gray-400 shrink-0 ml-0.5" />
<span className="text-sm font-medium text-gray-700 flex-1">Total</span>
<span className="text-sm font-bold text-gray-900 tabular-nums">
{formatWeight(totalWeight, unit)}
</span>
<span className="w-10" />
</div>
</div>
</div>
</div>
</div>