feat(dashboard): add RealUnit KPI/funnel section to /realunit#1118
feat(dashboard): add RealUnit KPI/funnel section to /realunit#1118TaprootFreak wants to merge 2 commits into
Conversation
Add a new "Key Figures" section at the top of the RealUnit dashboard, fed by GET /v1/realunit/admin/stats. - dto: RealunitStats* interfaces mirroring the api DTO - hook: getStats() via useApi().call() - context: stats state + fetchStats() callback - screen: Key Figures section (summary cards + KYC funnel chart) as the first section, triggered in the existing data-loading effect - component: KpiFunnelChart (ApexCharts bar chart, DFX blue palette) - i18n: German overrides for the new labels and funnel step names - tests: unit tests for getStats, fetchStats, the chart and the section (100% coverage of the new chart component) - e2e: self-contained Playwright visual spec with mocked stats endpoint and session JWT, plus generated chromium-darwin baseline Companion api PR in DFXswiss/api.
davidleomay
left a comment
There was a problem hiding this comment.
Two small findings, both non-blocking:
monochrome + fill.colors dead code
In src/components/realunit/kpi-funnel-chart.tsx (the chart options, ~line 50-54):
When monochrome.enabled is true, ApexCharts ignores fill.colors — it generates monochrome shades from theme.monochrome.color (#092f62). The fill.colors: ["#5A81BB"] line has no effect.
- If the intent is
#5A81BBbars: switch off monochrome and keepfill.colors, or change the monochrome color to#5A81BB. - If the intent is
#092f62bars: thefill.colorsline is dead and can be removed.
kycConversionRate recomputed every render
In src/screens/realunit.screen.tsx (~line 64-70):
kycConversionRate() is defined as a plain function called directly in JSX, so it runs two .find() scans on every render of the section. A useMemo would be a bit cleaner and more consistent with how other derived values in the codebase are handled:
const kycConversionRate = useMemo(() => {
if (!stats) return "-";
const reachedContactData = stats.kycFunnel.find(e => e.step === "ContactData")?.reached.total ?? 0;
const completedIdent = stats.kycFunnel.find(e => e.step === "Ident")?.completed.total ?? 0;
if (!reachedContactData) return "-";
return `${((completedIdent / reachedContactData) * 100).toFixed(1)}%`;
}, [stats]);Low impact given the tiny array — fine to defer if you would rather keep it simple.
Everything else LGTM — clean separation of concerns, good test coverage, and the i18n is comprehensive.
New Kennzahlen (Key Figures) section at the top of the RealUnit dashboard (
/realunit).What
KpiFunnelChartgetStats()hook method +fetchStats()context callback, consumingGET /v1/realunit/admin/statsRealunitStats*TypeScript interfaces mirroring the api DTO field names exactlyTests
getStats(), contextfetchStats, theKpiFunnelChartcomponent (100% coverage), and the screen sectione2e/realunit-kpi.spec.ts) with mocked stats endpoint + session JWT; generated-chromium-darwinbaseline committedLocal checks green: lint, test (297 passing), build:dev.
Companion api PR in DFXswiss/api.