import { useCallback, useEffect, useState } from 'react' import App from './App' import { api, setUnauthorizedHandler } from './api' import { Login } from './Login' import type { Me } from './types' /** * AuthGate decides, on load and after every 401, whether to show the setup * screen, a login form, or the app itself. It owns the one GET /api/me call * the app needs before it can render anything real. */ export function AuthGate() { const [me, setMe] = useState(null) const [error, setError] = useState('') const load = useCallback(async () => { try { setMe(await api.me()) setError('') } catch (e) { setError(e instanceof Error ? e.message : String(e)) } }, []) useEffect(() => { load() }, [load]) // A 401 elsewhere in the app (an expired or revoked session) means the // server no longer considers us logged in; drop straight to the login form // instead of waiting for the next unrelated re-render to notice. useEffect(() => { setUnauthorizedHandler(() => setMe((prev) => (prev ? { ...prev, authenticated: false } : prev))) return () => setUnauthorizedHandler(null) }, []) const logout = useCallback(async () => { await api.logout().catch(() => undefined) await load() }, [load]) if (!me) { return
{error || 'loading…'}
} if (!me.authenticated) { return } return }