import { useEffect, useState, useCallback } from "react"; import { api, type CursorStatus } from "./api.js"; import { RequestCrawl } from "./RequestCrawl.js"; export function StatusPanel({ onLastSync, }: { onLastSync?: (iso: string | null) => void; }) { const [status, setStatus] = useState(null); const [error, setError] = useState(null); const refresh = useCallback(() => { api .cursorStatus() .then((s) => { setStatus(s); onLastSync?.(s.lastFullSync); }) .catch((e) => setError(e.message)); }, [onLastSync]); useEffect(() => { refresh(); const id = setInterval(refresh, 15_000); return () => clearInterval(id); }, [refresh]); const gap = status?.gap; const gapClass = gap == null ? "warn" : gap < 500 ? "ok" : gap < 5000 ? "warn" : "error"; const statusClass = status == null ? "" : status.relayStatus === "active" || status.relayStatus === "idle" ? "ok" : status.relayStatus === "throttled" ? "warn" : "error"; // pulsing skeleton while the first fetch is in flight; static dash once it has failed const placeholder = error ? ( — ) : (