import { useEffect, useState } from "react"; import { api } from "./api.js"; import { Login } from "./Login.js"; import { StatusPanel } from "./StatusPanel.js"; import { AccountsPanel } from "./AccountsPanel.js"; import { PasskeysPanel } from "./PasskeysPanel.js"; import { AuditPanel } from "./AuditPanel.js"; import { RequestCrawl } from "./RequestCrawl.js"; import { SyncFooter } from "./SyncFooter.js"; import { InvitesPanel } from "./InvitesPanel.js"; import { StatsPanel } from "./StatsPanel.js"; import { OperatorsPanel } from "./OperatorsPanel.js"; import { Enroll } from "./Enroll.js"; export function App() { const [authed, setAuthed] = useState(null); const [appviewUrl, setAppviewUrl] = useState("https://bsky.app"); const [pdsHostname, setPdsHostname] = useState(""); const [passwordLogin, setPasswordLogin] = useState(true); const [pendingAdmins, setPendingAdmins] = useState(false); const [lastFullSync, setLastFullSync] = useState(null); // object wrapper so clicking the same handle twice still retriggers the search const [accountSearch, setAccountSearch] = useState<{ q: string } | null>(null); const [enrollToken] = useState( () => new URLSearchParams(window.location.search).get("enroll"), ); useEffect(() => { api .session() .then((s) => { setAuthed(s.authenticated); if (s.appviewUrl) setAppviewUrl(s.appviewUrl); if (s.pdsHostname) setPdsHostname(s.pdsHostname); setPasswordLogin(s.passwordLogin ?? true); setPendingAdmins(s.pendingAdmins ?? false); }) .catch(() => setAuthed(false)); }, []); useEffect(() => { document.title = pdsHostname ? `${pdsHostname} — operator` : "PDS Operator"; }, [pdsHostname]); if (authed === null) return null; if (!authed && enrollToken) { return ( setAuthed(true)} /> ); } if (!authed) { return ( setAuthed(true)} /> ); } return (

{pdsHostname || "pds"} / operator

setAccountSearch({ q: handle })} />
); }