diff --git a/apps/admin-ui/src/app/agent/page.tsx b/apps/admin-ui/src/app/agent/page.tsx new file mode 100644 index 0000000..28c5d85 --- /dev/null +++ b/apps/admin-ui/src/app/agent/page.tsx @@ -0,0 +1,151 @@ +"use client"; + +import { useCallback, useEffect, useState } from "react"; +import Link from "next/link"; +import { Nav, useAuth } from "@/components/Nav"; + +const MASTER_URL = "https://master.vonas.nl"; + +type TrayMeta = { + available?: boolean; + version?: string | null; + filename?: string; + sizeBytes?: number; + builtAt?: string | null; + productName?: string; + downloadUrl?: string; + note?: string; +}; + +function formatBytes(n: number): string { + if (!n || n <= 0) return "—"; + if (n < 1024 * 1024) return `${(n / 1024).toFixed(0)} KB`; + return `${(n / (1024 * 1024)).toFixed(1)} MB`; +} + +export default function AgentPage() { + useAuth(); + const [meta, setMeta] = useState(null); + const [err, setErr] = useState(null); + const [loading, setLoading] = useState(true); + + const load = useCallback(async () => { + setLoading(true); + setErr(null); + try { + const res = await fetch(`${MASTER_URL}/install/token-tray.json`, { + cache: "no-store", + }); + if (!res.ok) throw new Error(`Meta ophalen mislukt (${res.status})`); + const data = (await res.json()) as TrayMeta; + setMeta(data); + } catch (e) { + setErr(e instanceof Error ? e.message : String(e)); + setMeta(null); + } finally { + setLoading(false); + } + }, []); + + useEffect(() => { + void load(); + }, [load]); + + const available = Boolean(meta?.available); + const downloadHref = + meta?.downloadUrl?.trim() || `${MASTER_URL}/install/token-tray-setup.exe`; + + return ( + <> +