import { useDbStore } from "@/store/db"; import { useAuth } from "@/store/auth"; import { useEffect, useMemo } from "react"; import { Navigate, Outlet, useLocation, useNavigate, useSearchParams, } from "react-router-dom"; import BackgroundLayout from "./BackgroundLayout"; import { useOAuthContext } from "@/context/oauth"; const AuthLayout = () => { const { connecting, db, connect } = useDbStore(); const [searchParams] = useSearchParams(); const { active, setActive, setClientID, setRedirectURI, setScope, setState, setNonce, } = useOAuthContext(); const dbConnected = useMemo(() => !!db, [db]); const loadingAccounts = useAuth((state) => state.loadingAccounts); const loadAccounts = useAuth((state) => state.loadAccounts); const hasLoadedAccounts = useAuth((state) => state.hasLoadedAccounts); const activeAccount = useAuth((state) => state.activeAccount); const hasAccounts = useAuth((state) => state.accounts.length > 0); const authenticating = useAuth((state) => state.authenticating); const authenticate = useAuth((state) => state.authenticate); const hasAuthenticated = useAuth((state) => state.hasAuthenticated); const signInRequired = useAuth((state) => state.signInRequired); const location = useLocation(); const navigate = useNavigate(); const isAuthPage = useMemo(() => { const allowedPaths = ["/login", "/register", "/authenticate"]; return allowedPaths.some((p) => location.pathname.startsWith(p)); }, [location.pathname]); const loading = useMemo(() => { if (isAuthPage) { return connecting; } return ( !hasAuthenticated || !hasLoadedAccounts || loadingAccounts || authenticating || connecting ); }, [ isAuthPage, hasAuthenticated, hasLoadedAccounts, loadingAccounts, authenticating, connecting, ]); useEffect(() => { if (!active) { console.log( "setting search params:", Object.fromEntries(searchParams.entries()) ); setActive(true); setClientID(searchParams.get("client_id") ?? ""); setRedirectURI(searchParams.get("redirect_uri") ?? ""); const scope = searchParams.get("scope") ?? ""; setScope(scope.split(" ").filter((s) => s.length > 0)); setState(searchParams.get("state") ?? ""); setNonce(searchParams.get("nonce") ?? ""); } }, [ active, searchParams, setActive, setClientID, setNonce, setRedirectURI, setScope, setState, ]); useEffect(() => { connect(); }, [connect]); useEffect(() => { if (dbConnected) { loadAccounts(); } }, [dbConnected, loadAccounts]); useEffect(() => { if (dbConnected && !loadingAccounts && activeAccount) { authenticate(); } }, [activeAccount, dbConnected, authenticate, loadingAccounts]); useEffect(() => { if (!signInRequired && isAuthPage) { const to = location.state?.from ?? "/"; navigate(to, { state: { reset: true } }); } }, [isAuthPage, location.state?.from, navigate, signInRequired]); if (signInRequired && !isAuthPage) { return ( ); } if (loading) { return (
Loading...

Loading...

); } return ( ); }; export default AuthLayout;