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 (
);
}
return (
);
};
export default AuthLayout;