UI/UX-Prototyp der Analytics-Dashboards in HiveGrid, fachlich auf einen SHK-/Handwerksbetrieb zugeschnitten. Ziel ist die Übergabe an die Entwicklung, nicht der Produktivbetrieb. Inhalt: sechs Seiten (Übersicht, Finanzen, Aufträge, Kunden, Team, Komponenten), 26 KPIs, neun Chart-Bausteine, Filtersystem mit seitenabhängiger Relevanz und ein deterministischer Demo-Datensatz (420 Kunden, 1.900 Aufträge, Stichtag 30.07.2026). Drei Quellen sind zusammengeführt: die fachliche Planung mit dem Branchenpartner (Januar 2026), die Subframe-Komponentenbibliothek aus dem HiveGrid-Pitch und IBM Carbon Data Visualization für die Diagrammregeln. Herkunft und bewusste Abweichungen stehen in docs/HERKUNFT.md. Dokumentation: README, HANDOVER (was echte Logik braucht), docs/DESIGN-SYSTEM, KPI-KATALOG, DATENMODELL, NAVIGATION, HERKUNFT, ZIELSYSTEM (Einbauort in HiveGrid Cloud) und LEITPLANKEN (welche Cloud-Screens als Vorbild taugen). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
9.4 KiB
Zielsystem: HiveGrid Cloud
Wohin dieser Prototyp eingebaut wird, was dort heute schon steht und was beim Einbau konkret anzupassen ist.
Repo: HiveGrid-Cloud (Gitea git.tool-ctrl.de/toolctrl-labs/HiveGrid-Cloud).
pnpm-Monorepo, React Router 7, Prisma/Postgres, mandantenfähig mit RLS.
apps/web (Tenant- und Admin-App), dazu api, worker, desktop,
hocuspocus, portal-domain-controller und rund 40 Pakete unter packages/.
Größenordnung: 678 Route-Dateien, davon 575 im Core-Manifest.
1. Der Platz dieses Prototyps
Das Ziel ist der Tenant-Dashboard-Screen unter …/<tenant>/dashboard.
Dort liegt bereits eine Implementierung:
| Datei | Was drin steht |
|---|---|
apps/web/app/components/screens/dashboard/DashboardPage.tsx |
Widget-Grid, 495 Zeilen |
…/DashboardEditPanel.tsx |
Edit-Modus (Widget-Filter/Zeitraum) |
…/DashboardDrilldownDialog.tsx |
Drilldown je Kachel |
…/DashboardMonthlySeriesChart.tsx, …/DashboardStageDistributionChart.tsx |
die zwei vorhandenen Diagramme |
apps/web/app/routes/app.$tenant/dashboard.tsx |
Loader, SSE-Stream, Export |
Fachlich ist das die Phase P11 (Modul M20): drei feste Rollen-Layouts (GF · Büro · Monteur) aus einer Widget-Registry, live über SSE, plus das Komfort-Delta aus P30 (Edit-Modus, Drilldown, CSV-/Report-Export, Realtime-Opt-out).
Wichtig: Dieser Stand ist ausdrücklich Interim-UI nach AD-28 — der Dev
baut aus ~/ui gegen ein stabiles View-Model, damit das Ticket nicht auf den
finalen Screen wartet. Der Kommentarkopf von DashboardPage.tsx sagt es
wörtlich: „Final Subframe optics = tracked design-nachzug (D-DASH / VD-P30)."
Genau diese Lücke füllt dieser Prototyp. Der Einbau ist der geplante Nachzug, kein Umbau gegen den Strom.
2. Gemeinsame Basis — und wo sie auseinanderläuft
| Prototyp | HiveGrid Cloud | |
|---|---|---|
| Subframe-Projekt | f023064a5ca0 |
f023064a5ca0 — dasselbe |
| Bibliothek | ui/, 86 Komponenten |
apps/web/app/ui/, Alias ~/ui/*, 92 Komponenten |
| Überschneidung | 82 Komponenten gleich benannt | dieselben 82 |
| Diagramme | Recharts ^2.15.4 | Recharts ^2.15.3 — dieselbe Bibliothek |
| Framework | Next.js 16 | React Router 7 |
Die vier Namensunterschiede: DialogFullscreen → FullscreenDialog,
DrawerRight → Drawer, AddressDialog und BannerOffline existieren dort
nicht. Cloud hat zusätzlich BulkActionBar, ConfirmDialog, DropdownMenu,
ModalBlank, ResultDialog, BannerPermanent, ChatSprechblase.
Dass Komponentenbibliothek und Chart-Bibliothek übereinstimmen, ist der Grund, warum der Einbau realistisch ein Port ist und keine Neuimplementierung.
3. Was beim Einbau konkret anders wird
3.1 Daten kommen als View-Model-Prop
Der Prototyp importiert DATENSATZ direkt. In der Cloud gilt das Muster
<XPage vm={} actions={} />: Die Route besitzt Loader, SSE und Actions, die
Screen-Komponente ist rein und bekommt alles als Prop. Kein useLoaderData
in der Komponente.
export type DashboardPageVM = VMState<DashboardPageData>;
type VMState<T> =
| { status: "idle" }
| { status: "loading"; data?: T }
| { status: "ready"; data: T }
| { status: "empty" }
| { status: "error"; data?: T; error: { messageKey: string; code?: string } };
Fünf Zustände statt einem. Der Prototyp kennt nur „Daten da"; loading,
empty und error sind je Seite zu ergänzen. Die Chart-Leerzustände
(ChartLeer) decken davon nur einen Teil ab.
DashboardPageData führt außerdem activeRole, layout, generatedAt,
streamUrl, canCustomize, liveUpdatesEnabled, layoutSource und
catalog — das Dashboard ist dort rollen- und berechtigungsabhängig, was der
Prototyp nicht abbildet.
3.2 Kein eigenes App-Chrome
AppShell.tsx aus diesem Prototyp fällt beim Einbau weg. Die Cloud-Routen
laufen bereits in der echten App-Shell mit Sidebar, Tenant-Layout und
Breadcrumb (SubframeAppShell.tsx, AppSidebar.tsx). Screen-Komponenten
dürfen dort ausdrücklich kein ~/ui/layouts/DefaultPageLayout rendern —
das bringt eine eigene Beispiel-Sidebar mit und erzeugt eine doppelte
Navigation. Stattdessen gilt PageShell / PageHeader / PageBody aus
components/screens/shared/PageShell.tsx.
Unsere Seitenköpfe und die Filterleiste bleiben, die Rahmen-Navigation nicht.
3.3 Texte über i18n
Alle statischen Texte laufen über react-i18next (t("app.dashboard.…")).
Dieser Prototyp hat deutsche Strings fest im JSX. Das ist beim Einbau
mechanische Arbeit, aber flächendeckend — es betrifft jede Karte, jede
Achsenbeschriftung und jeden Leerzustand.
Die deutschen Bezeichner im Code (umsatz, auftraege) bleiben davon
unberührt und passen zur Cloud, deren UI ebenfalls deutsch ist (EN-Locale erst
in P30).
3.4 Barrierefreiheit der Diagramme
In der Cloud sind Charts konsequent aria-hidden="true", und die umgebende
Karte liefert eine Textzusammenfassung plus Datentabelle für Screenreader.
Dieser Prototyp hat das nicht. Beim Einbau ist es Pflicht — das Repo fährt
ein a11y-Lint-Baseline-Gate und axe-Tests je Primitive.
3.5 Stabile Oberflächen-IDs
Jede relevante Fläche trägt ein data-ui-id (ui.dashboard.widget.…), erfasst
in docs/ui-inventory/surfaces.json. Tests und Agenten adressieren darüber.
Unsere Widget-IDs aus dem WidgetContext sind der natürliche Anknüpfungspunkt,
müssen aber auf das dortige Namensschema umgestellt werden.
3.6 Spacing passt bereits
.planning/INTERIM-UI-DESIGN-STANDARDS.md schreibt fest: Page-Padding 24,
Card 16, Grid-Gap 16, Section-Gap 24, Field-Gap 16,
Control-Höhe Medium 36, Input-Radius 4. Das deckt sich mit dem
8-px-System in DESIGN-SYSTEM.md Abschnitt 5 — hier ist
nichts anzupassen.
4. Was dieser Prototyp dem Zielsystem voraushat
Nicht alles fließt nur in eine Richtung. Drei Dinge fehlen dort heute:
Ein gemeinsames Chart-Theme. Die beiden vorhandenen Diagramme setzen
Farben direkt im JSX (fill="#334155", fill="#cbd5e1"), jedes mit eigenem
Gitter (strokeDasharray="3 3"), eigener Achsenbreite und eigenem
Balkenradius. Es gibt keine geteilte Palette, keine Kategorien-Obergrenze und
keine feste Farbzuordnung. features/dashboard/utils/chartTheme.ts ist genau
das, was dort fehlt — und der Teil, der sich am ehesten unabhängig vom Rest
übernehmen lässt.
Ausformulierte Diagramm-Regeln. DESIGN-SYSTEM.md hat in der Cloud keine Entsprechung. Die Standards dort regeln Layout, Controls und Zustände sehr genau, Datenvisualisierung dagegen gar nicht.
Fachliche Kennzahl-Definitionen. KPI-KATALOG.md mit Zeitbezug und Berechnung je KPI ist im Zielsystem so nicht vorhanden; die Widget-Registry beschreibt Kacheln, nicht deren betriebswirtschaftliche Definition.
5. Wer entwirft was — der Rest ist noch nicht fertig designt
HiveGrid Cloud ist nach dem Designer-First-Prinzip organisiert
(.planning/DESIGNER-FIRST-PLAYBOOK.md). Der Ablauf ist verbindlich:
- Dev/Planung stellt je Phase einen Designer-Brief bereit — was das Modul tut und welche UI-Elemente vorkommen müssen, kein Layout.
- Der Designer entwirft die Screens in Subframe und darf Spec und UI/UX überschreiben — Anordnung und Layout sind eine Design-Entscheidung.
- Das Delta (geänderte Spec-Punkte, neue UX-Entscheidungen, Subframe-Link) wird in den Brief eingetragen.
- Der Dev setzt um und zieht Spec und Doku nach.
Es gibt 31 solcher Briefs (.planning/designer-briefs/P01…P34.md) — Auth, CRM,
Lead-Inbox, Projekt-Pipelines, Automation-Flow-Editor, Form-Builder, Plantafel,
Kalender, Telefonie, HR, Billing, Customer-Portal, Help-Center. Für einen
großen Teil davon steht der Delta-Block noch leer: Der finale Screen ist
noch nicht entworfen, die Route läuft bis dahin auf Interim-UI.
Für die Einordnung dieses Prototyps heißt das dreierlei:
- Das Dashboard ist ein Baustein unter vielen, nicht die Leitgestaltung der Anwendung. Es fügt sich in eine App-Shell und ein Design-System ein, die bereits stehen.
- Was hier an Anordnung und Raster festgelegt ist, ist ein Vorschlag. Die Layout-Hoheit liegt beim Designer — der Brief zu P11 sagt ausdrücklich „Anordnung = Davids freie Hand". Verbindlich zu übergeben sind die Kennzahl-Definitionen, die Chart-Regeln und das Verhalten, nicht die Pixelanordnung.
- Andere Bereiche der Anwendung sehen heute noch nicht final aus, weil sie entweder auf Interim-UI laufen oder noch beim Designer liegen. Ein Vergleich „unser Dashboard gegen den aktuellen Screen X" misst deshalb nicht zwangsläufig gegen den Zielzustand.
6. Wenn du dir das Zielsystem selbst ansehen willst
corepack enable && pnpm install
pnpm dev:services # Postgres + Redis
pnpm dev:services:reset # Wegwerf-DB inkl. Migrationen und Demo-Daten
pnpm dev:local
Tenant-App auf http://app.localhost:3000. Die lokalen Demo-Zugänge (Tenant
„HiveGrid Demo SHK") stehen im README von HiveGrid Cloud unter „App starten" —
sie werden hier bewusst nicht wiederholt. Die Demo-Daten sind zunächst
ausgeblendet und erscheinen über „Demo-Daten anzeigen" oder ?demo=show.
Der Weg zum Dashboard ist nach dem Login die erste Seite der Tenant-App.
Für einen schnellen Überblick ohne Setup:
docs/ui-inventory/surface-map.md listet alle stabilen Oberflächen mit ihren
Quelldateien, docs/route-inventory.md die Größenordnung des Routenbestands.