import { useEffect, useState } from "react"; import { NavLink, Outlet, useLocation } from "react-router-dom"; import { NAVIGATION_ROUTES, routePath } from "../../contracts/routes.js"; import { useSession } from "../providers/session-provider.jsx"; import { useTheme } from "../providers/theme-provider.jsx"; const SESSION_LABELS = Object.freeze({ authenticated: "인증됨", unauthenticated: "로그인 전", "recovery-pending": "복구 대기", "integration-failed": "연동 필요", }); export function AppShell() { const location = useLocation(); const { sessionState, beginSignIn, signOut, recover } = useSession(); const { preference, setPreference } = useTheme(); const [navigationOpen, setNavigationOpen] = useState(false); const [sessionActionPending, setSessionActionPending] = useState(false); const [sessionActionFailed, setSessionActionFailed] = useState(false); useEffect(() => { setNavigationOpen(false); }, [location.pathname]); useEffect(() => { if (!navigationOpen) return undefined; /** @param {KeyboardEvent} event */ const closeOnEscape = (event) => { if (event.key === "Escape") setNavigationOpen(false); }; window.addEventListener("keydown", closeOnEscape); return () => window.removeEventListener("keydown", closeOnEscape); }, [navigationOpen]); async function runSessionAction() { setSessionActionPending(true); setSessionActionFailed(false); try { if (sessionState === "authenticated") { await signOut(); } else if (sessionState === "recovery-pending") { await recover(); } else { await beginSignIn( `${location.pathname}${location.search}${location.hash}`, ); } } catch { setSessionActionFailed(true); } finally { setSessionActionPending(false); } } const sessionActionLabel = sessionState === "authenticated" ? "로그아웃" : sessionState === "recovery-pending" ? "세션 복구" : "로그인"; const integrationAvailable = sessionState !== "integration-failed"; return (
본문으로 건너뛰기
Frontend Skeleton
{SESSION_LABELS[sessionState]} {integrationAvailable ? ( ) : null}
{sessionActionFailed ? (

세션 작업을 완료하지 못했습니다.

) : null}
{navigationOpen ? (
); }