Files
dejanandClaude Opus 5 b8bf987d0e feat(dashboard): Analytics-Dashboard als Gestaltungsvorlage zur Übergabe
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
2026-08-29 17:25:20 +02:00

170 lines
6.2 KiB
TypeScript

"use client";
/*
* Documentation:
* Badge Feedback — https://app.subframe.com/f023064a5ca0/library?component=Badge+Feedback_896531e4-54ea-4e5a-8710-c30fc2ce10fb
*/
import React from "react";
import * as SubframeUtils from "../../utils";
export interface BadgeFeedbackRootProps
extends React.HTMLAttributes<HTMLDivElement> {
farbe?:
| "solid-neutral"
| "solid-positive"
| "solid-negative"
| "solid-warning"
| "solid-information"
| "solid-purple"
| "solid-blue"
| "solid-brand-primary"
| "solid-brand-secondary"
| "subtle-neutral"
| "subtle-positive"
| "subtle-negative"
| "subtle-warning"
| "subtle-information"
| "subtle-purple"
| "subtle-blue"
| "subtle-brand-primary"
| "subtle-brand-secondary"
| "ghost-neutral"
| "ghost-positive"
| "ghost-negative"
| "ghost-warning"
| "ghost-information"
| "ghost-purple"
| "ghost-blue"
| "ghost-brand-primary"
| "ghost-brand-secondary";
children?: React.ReactNode;
size?: "medium" | "small" | "large";
className?: string;
}
const BadgeFeedbackRoot = React.forwardRef<
HTMLDivElement,
BadgeFeedbackRootProps
>(function BadgeFeedbackRoot(
{
farbe = "solid-neutral",
children,
size = "medium",
className,
...otherProps
}: BadgeFeedbackRootProps,
ref
) {
return (
<div
className={SubframeUtils.twClassNames(
"group/896531e4 flex h-6 items-center gap-2 rounded-round bg-surface-feedback-solid-neutral px-2.5 py-1",
{
"h-8 py-2": size === "large",
"h-5 py-0.5": size === "small",
"bg-transparent px-0 py-0":
farbe === "ghost-brand-secondary" ||
farbe === "ghost-brand-primary" ||
farbe === "ghost-blue" ||
farbe === "ghost-purple" ||
farbe === "ghost-information" ||
farbe === "ghost-warning" ||
farbe === "ghost-negative" ||
farbe === "ghost-positive" ||
farbe === "ghost-neutral",
"bg-brand-brand-secondary-surface-subtle-default":
farbe === "subtle-brand-secondary",
"bg-brand-brand-surface-subtle-default":
farbe === "subtle-brand-primary",
"bg-surface-ui-subtle-blue-default": farbe === "subtle-blue",
"bg-surface-ui-subtle-purple-default": farbe === "subtle-purple",
"bg-surface-feedback-subtle-information":
farbe === "subtle-information",
"bg-surface-feedback-subtle-warning": farbe === "subtle-warning",
"bg-surface-feedback-subtle-negative": farbe === "subtle-negative",
"bg-surface-feedback-subtle-positive": farbe === "subtle-positive",
"bg-surface-feedback-subtle-neutral": farbe === "subtle-neutral",
"bg-brand-brand-secondary-surface-solid-default":
farbe === "solid-brand-secondary",
"bg-brand-brand-surface-solid-default":
farbe === "solid-brand-primary",
"bg-surface-ui-solid-blue-default": farbe === "solid-blue",
"bg-surface-ui-solid-purple-default": farbe === "solid-purple",
"bg-surface-feedback-solid-information":
farbe === "solid-information",
"bg-surface-feedback-solid-warning": farbe === "solid-warning",
"bg-surface-feedback-solid-negative-default":
farbe === "solid-negative",
"bg-surface-feedback-solid-positive-default":
farbe === "solid-positive",
},
className
)}
ref={ref}
{...otherProps}
>
<div
className={SubframeUtils.twClassNames(
"flex h-1 w-1 flex-none flex-col items-start gap-2 rounded-round bg-icon-neutral-on-solid",
{
"bg-brand-brand-secondary-surface-solid-default":
farbe === "ghost-brand-secondary" ||
farbe === "subtle-brand-secondary",
"bg-brand-brand-surface-solid-default":
farbe === "ghost-brand-primary" ||
farbe === "subtle-brand-primary",
"bg-icon-ui-blue":
farbe === "ghost-blue" || farbe === "subtle-blue",
"bg-icon-ui-purple":
farbe === "ghost-purple" || farbe === "subtle-purple",
"bg-icon-feedback-information":
farbe === "ghost-information" || farbe === "subtle-information",
"bg-icon-feedback-warning":
farbe === "ghost-warning" || farbe === "subtle-warning",
"bg-icon-feedback-negative":
farbe === "ghost-negative" || farbe === "subtle-negative",
"bg-icon-feedback-positive":
farbe === "ghost-positive" || farbe === "subtle-positive",
"bg-icon-neutral-on-subtle":
farbe === "ghost-neutral" || farbe === "subtle-neutral",
}
)}
/>
{children ? (
<span
className={SubframeUtils.twClassNames(
"whitespace-nowrap text-body-small-medium-0 font-body-small-medium-0 text-text-neutral-on-solid",
{
"text-brand-brand-secondary-surface-solid-default":
farbe === "ghost-brand-secondary",
"text-brand-brand-surface-solid-default":
farbe === "ghost-brand-primary",
"text-text-ui-blue": farbe === "ghost-blue",
"text-text-ui-purple": farbe === "ghost-purple",
"text-text-feedback-information": farbe === "ghost-information",
"text-text-feedback-warning": farbe === "ghost-warning",
"text-text-feedback-negative":
farbe === "ghost-negative" || farbe === "subtle-negative",
"text-text-feedback-positive":
farbe === "ghost-positive" || farbe === "subtle-positive",
"text-text-neutral-on-subtle":
farbe === "ghost-neutral" ||
farbe === "subtle-brand-secondary" ||
farbe === "subtle-brand-primary" ||
farbe === "subtle-blue" ||
farbe === "subtle-purple" ||
farbe === "subtle-information" ||
farbe === "subtle-warning" ||
farbe === "subtle-neutral",
}
)}
>
{children}
</span>
) : null}
</div>
);
});
export const BadgeFeedback = BadgeFeedbackRoot;