feat(dashboard): real business metrics with week-over-week trends

Dashboard KPIs were three flat counters with no trend data — the cards
rendered a neutral dash where the design intends movement indicators.
Summary now queries three trailing windows and emits four KPIs with
real deltas: bookings this week, completed (new CompletedCount metric
in both repositories), cancellations, and utilization in percentage
points. KPI labels localize in the frontend via a code-to-key map so
Czech operators no longer see English labels on live data.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-09-18 11:34:00 +02:00
1 parent 668a54ae1d
commit 0dc26e0c16
10 files changed
+141 -8

No files matched your search

@@ -211,8 +211,17 @@ export function DashboardDataProvider(props: { children: any }) {
};
};
const kpiLabelKeys: Record<string, string> = {
bookings_this_week: "dashboard.kpi.bookingsThisWeek",
completed: "dashboard.kpi.completed",
cancellations: "dashboard.kpi.cancellations",
utilization: "dashboard.kpi.utilization",
};
const normalizedKpis = createMemo(() => (resolvedSummary()?.kpis ?? []).map((kpi: any) => ({
...kpi, trend: kpi.trend ?? "neutral", change: kpi.change ?? "—",
...kpi,
label: kpi.code && kpiLabelKeys[kpi.code] ? i18n.t(kpiLabelKeys[kpi.code]) : kpi.label,
trend: kpi.trend ?? "neutral",
change: kpi.change ?? "—",
})));
const normalizedUpcomingBookings = createMemo(() => (resolvedSummary()?.upcomingBookings ?? []).map((booking: any) => ({