dimensionlab-website/src/lib/ui/components/DashboardFrame.tsx
2026-06-20 00:49:22 +02:00

59 lines
1.8 KiB
TypeScript

import { useId } from "react";
import type { ReactNode } from "react";
import type { UiDashboardPreview } from "../types";
import { ModuleCard } from "./ModuleCard";
import { ServicePanel } from "./ServicePanel";
import { StatusStrip } from "./StatusStrip";
import { TelemetryGrid } from "./TelemetryGrid";
export interface DashboardFrameProps {
actions?: ReactNode;
dashboard: UiDashboardPreview;
titleId?: string;
}
export function DashboardFrame({
actions,
dashboard,
titleId,
}: DashboardFrameProps) {
const generatedTitleId = useId();
const resolvedTitleId = titleId || `${generatedTitleId}-title`;
return (
<main className="dashboard-frame" aria-labelledby={resolvedTitleId}>
<header className="dashboard-frame__header">
<div className="dashboard-frame__title">
<div className="dashboard-frame__title-copy">
{dashboard.eyebrow ? <p>{dashboard.eyebrow}</p> : null}
<h1 id={resolvedTitleId}>{dashboard.title}</h1>
{dashboard.subtitle ? <span>{dashboard.subtitle}</span> : null}
</div>
{actions ? (
<div className="dashboard-frame__actions">{actions}</div>
) : null}
</div>
{dashboard.modules.length ? (
<div className="dashboard-frame__modules">
{dashboard.modules.map((module) => (
<ModuleCard key={module.id} module={module} />
))}
</div>
) : null}
</header>
<TelemetryGrid cards={dashboard.telemetry} />
<section className="dashboard-frame__panels" aria-label="Service groups">
{dashboard.serviceGroups.map((group) => (
<ServicePanel key={group.id} group={group} />
))}
</section>
<StatusStrip
id={dashboard.statusStripId}
items={dashboard.statusItems}
/>
</main>
);
}