Collapse the three Compare tabs (MoM / YoY / Budget) into two modes. The
new "Actual vs actual" mode exposes an explicit reference-month dropdown
in the header (defaults to the previous month, wraps around January) and
a MoM/YoY sub-toggle. The chart is rewritten to a grouped side-by-side
BarChart with two bars per category (reference period vs comparison
period) so both values are visible at a glance instead of just the
delta. The URL PeriodSelector stays in sync with the reference month.
- useCompare: state splits into { mode: "actual"|"budget", subMode:
"mom"|"yoy", year, month }. Pure helpers previousMonth(),
defaultReferencePeriod(), comparisonMeta() extracted for tests
- CompareModeTabs: 2 modes instead of 3
- New CompareSubModeToggle and CompareReferenceMonthPicker components
- ComparePeriodChart: grouped bars via two <Bar dataKey="..."/> on a
vertical BarChart
- i18n: modeActual / subModeMoM / subModeYoY / referenceMonth (FR+EN),
retire modeMoM / modeYoY
- 9 new vitest cases covering the pure helpers (January wrap-around for
both MoM and YoY, default reference period, month/year arithmetic)
Closes #96
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
37 lines
1.1 KiB
TypeScript
37 lines
1.1 KiB
TypeScript
import { useTranslation } from "react-i18next";
|
|
import type { CompareMode } from "../../hooks/useCompare";
|
|
|
|
export interface CompareModeTabsProps {
|
|
value: CompareMode;
|
|
onChange: (mode: CompareMode) => void;
|
|
}
|
|
|
|
export default function CompareModeTabs({ value, onChange }: CompareModeTabsProps) {
|
|
const { t } = useTranslation();
|
|
|
|
const modes: { id: CompareMode; labelKey: string }[] = [
|
|
{ id: "actual", labelKey: "reports.compare.modeActual" },
|
|
{ id: "budget", labelKey: "reports.compare.modeBudget" },
|
|
];
|
|
|
|
return (
|
|
<div className="inline-flex gap-1" role="tablist">
|
|
{modes.map(({ id, labelKey }) => (
|
|
<button
|
|
key={id}
|
|
type="button"
|
|
role="tab"
|
|
onClick={() => onChange(id)}
|
|
aria-selected={value === id}
|
|
className={`px-3 py-2 rounded-lg text-sm font-medium transition-colors ${
|
|
value === id
|
|
? "bg-[var(--primary)] text-white"
|
|
: "bg-[var(--card)] border border-[var(--border)] text-[var(--foreground)] hover:bg-[var(--muted)]"
|
|
}`}
|
|
>
|
|
{t(labelKey)}
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|