import { useEffect, useRef, useState } from 'react'; import { Loader2 } from 'lucide-react'; import { useClient } from 'hooks/useClient'; import { ConnectionPanel } from './ConnectionPanel'; import { useOpenSeoChanged } from './channel'; /** * OpenSEO's own interface, served through Officer. * * ── An iframe on the PROXY, never on the instance ── * * `src` points at `/api/openseo/`, this Officer's own origin, so the browser's request carries the * session cookie and passes the permission gate like everything else. Pointing it at the instance * instead would work on a laptop and be a hole: OpenSEO self-hosts with `AUTH_MODE=local_noauth`, so a * URL that reaches it is a URL that needs no credential — and an iframe src is a URL the person can * read out of the page source and open directly. * * So the proxy is not a convenience here. It is the authentication. * * ── Setup replaces the app rather than sitting beside it ── * * With nothing configured there is no app to show, and a panel offering both an empty frame and a form * makes somebody choose between them. Configured, the form is gone — it lives in this plugin's own * settings once there is something to look at. */ export const AppPanel = () => { const client = useClient(); const clientRef = useRef(client); clientRef.current = client; const [configured, setConfigured] = useState(null); const [signal] = useOpenSeoChanged(); useEffect(() => { void (async () => { try { const status = await clientRef.current.get<{ configured: boolean }>('/openseo/status'); setConfigured(status.configured); } catch { // Cannot tell. Treated as configured rather than not: telling somebody they have set nothing up // is a far more alarming thing to be wrong about, and invites them to re-enter a working address. setConfigured(true); } })(); }, [signal]); if (configured === null) { return (
); } if (!configured) return ; return (