import { useState, useCallback } from 'react'; import { api, getTokenPayload, isRegistered as checkRegistered, needsPasswordReset as checkNeedsReset, validateStoredToken } from '@/lib/api'; import { ensureAuth } from './useCloudSave'; interface AuthGateState { loading: boolean; backendError: string | null; needsInvite: boolean; needsPasswordReset: boolean; registered: boolean; isAdmin: boolean; config: { requireInvite: boolean; userInvitations: number } | null; setRegistered: (value: boolean) => void; setNeedsPasswordReset: (value: boolean) => void; retry: () => void; } export function useAuthGate(): AuthGateState { const [config, setConfig] = useState<{ requireInvite: boolean; userInvitations: number } | null>(null); const [loading, setLoading] = useState(true); const [backendError, setBackendError] = useState(null); const [registered, setRegistered] = useState(false); const [passwordReset, setPasswordReset] = useState(false); const [admin, setAdmin] = useState(false); const [initCount, setInitCount] = useState(0); const init = useCallback(async () => { setLoading(true); setBackendError(null); validateStoredToken(); try { await api.health(); } catch (e) { setBackendError(e instanceof Error ? e.message : 'Cannot connect to server'); setLoading(false); return; } try { const cfg = await api.config.get(); setConfig(cfg); } catch { setConfig({ requireInvite: false, userInvitations: 0 }); } try { await ensureAuth(); } catch { // auth failed — will show as unregistered } const payload = getTokenPayload(); setRegistered(checkRegistered()); setPasswordReset(checkNeedsReset()); setAdmin(payload?.role === 'admin'); setLoading(false); }, []); // Run init on mount and on retry useState(() => { init(); }); const retry = useCallback(() => { setInitCount(c => c + 1); init(); }, [init]); const handleSetRegistered = useCallback((value: boolean) => { setRegistered(value); const payload = getTokenPayload(); if (payload) { setAdmin(payload.role === 'admin'); setPasswordReset(payload.mustResetPassword); } }, []); const handleSetPasswordReset = useCallback((value: boolean) => { setPasswordReset(value); }, []); const needsInvite = !!(config?.requireInvite && !registered); return { loading, backendError, needsInvite, needsPasswordReset: passwordReset, registered, isAdmin: admin, config, setRegistered: handleSetRegistered, setNeedsPasswordReset: handleSetPasswordReset, retry, }; }