import { useEffect, useRef, useState } from 'react'; import { AnchorButton, Button, Callout, Intent, NonIdealState, Spinner, Tab, Tabs, Tag } from '@blueprintjs/core'; import DeployWizard from '../components/wizard/DeployWizard'; import { tenantUrl, CLARITY_DOMAIN } from '../config'; import { getTenants, subscribeToTenantLogs } from '../api/tenantApi'; import type { TenantRecord } from '../types/provisioning'; const ENV_INTENT: Record = { prod: Intent.DANGER, uat: Intent.WARNING, fdev: Intent.PRIMARY, }; function TenantCard({ t }: { t: TenantRecord }) { const [logs, setLogs] = useState([]); const [logsOpen, setLogsOpen] = useState(false); const logRef = useRef(null); const sourceRef = useRef(null); useEffect(() => { if (!logsOpen) return; const src = subscribeToTenantLogs( t.subdomain, (line) => setLogs((prev) => [...prev.slice(-500), line]), // cap at 500 lines () => {} ); sourceRef.current = src; return () => { src.close(); sourceRef.current = null; }; }, [logsOpen, t.subdomain]); // Auto-scroll to bottom when new lines arrive useEffect(() => { if (logRef.current) logRef.current.scrollTop = logRef.current.scrollHeight; }, [logs]); return (
{t.clientName} {t.subdomain}
{t.environment} {t.status}
setLogsOpen(id === 'logs')}> Site: {t.siteCode} Container: {t.containerName ?? '—'}{t.containerPort ? `:${t.containerPort}` : ''} {new Date(t.provisionedAt).toLocaleString()} {t.status === 'Provisioned' && ( {t.subdomain}.{CLARITY_DOMAIN} )}
} /> {logs.length === 0 ? Connecting to container logs… : logs.map((l, i) =>
{l}
) } } /> ); } export default function DashboardPage() { const [wizardOpen, setWizardOpen] = useState(false); const [tenants, setTenants] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const load = () => { getTenants() .then((data) => { setTenants(data); setError(null); }) .catch((e: Error) => setError(e.message)) .finally(() => setLoading(false)); }; useEffect(() => { load(); }, []); const handleWizardClose = () => { setWizardOpen(false); setLoading(true); load(); }; if (wizardOpen) return ; return ( <>

Provisioned Tenants

Manage and monitor client deployments.

{loading && } title="Loading tenants..." />} {error && ( {error} )} {!loading && !error && tenants.length === 0 && (
🏗️

No tenants provisioned yet

Deploy your first client to get started.

)} {!loading && tenants.length > 0 && (
{tenants.map((t) => ( ))}
)} ); }