feat: add react api and shadcn foundation

This commit is contained in:
vince 2026-06-19 23:35:46 +02:00
parent f6d6d39a7b
commit a71d66b1b8
21 changed files with 1524 additions and 36 deletions

View file

@ -1,5 +1,13 @@
import { useEffect, useState } from "react";
import type { DashboardRuntimeState } from "$lib/server/dashboard";
const loadingDashboardState: DashboardRuntimeState = {
state: "loading",
title: "Loading Dashboard",
subtitle: "Fetching active model",
message: "Waiting for the active dashboard document.",
};
export function AppStateView({
dashboard,
}: {
@ -19,14 +27,45 @@ export function AppStateView({
}
export default function App() {
return (
<AppStateView
dashboard={{
state: "loading",
title: "Loading Dashboard",
subtitle: "Fetching active model",
message: "Waiting for the active dashboard document.",
}}
/>
);
const [dashboard, setDashboard] =
useState<DashboardRuntimeState>(loadingDashboardState);
useEffect(() => {
let cancelled = false;
let refreshTimer: number | undefined;
async function loadDashboard() {
const response = await fetch("/api/dashboard");
const nextDashboard = (await response.json()) as DashboardRuntimeState;
if (cancelled) return;
setDashboard(nextDashboard);
if (refreshTimer) {
window.clearInterval(refreshTimer);
refreshTimer = undefined;
}
const refreshIntervalSeconds =
nextDashboard.state === "ready"
? nextDashboard.document.metadata.refreshIntervalSeconds
: undefined;
if (refreshIntervalSeconds) {
refreshTimer = window.setInterval(
() => void loadDashboard(),
refreshIntervalSeconds * 1000,
);
}
}
void loadDashboard();
return () => {
cancelled = true;
if (refreshTimer) window.clearInterval(refreshTimer);
};
}, []);
return <AppStateView dashboard={dashboard} />;
}