"use client"; /** * 로그인하지 않았으면 화면 대신 로그인만 보여준다. * * 들어오는 화면과 아카이브는 열어 둔다 — 로그인은 실제로 만들려고 누를 때 요구한다. * 그 요구는 여기가 아니라 시작 화면의 제출 버튼이 한다(useRequireLogin). */ import { usePathname, useRouter } from "next/navigation"; import GoogleSignIn from "@/components/google-sign-in"; import { signIn, useMe } from "@/lib/auth"; import { useState } from "react"; // 이 주소들은 그대로 보여준다. 하위 경로까지 여는 것은 아카이브뿐이다 const OPEN_PAGES = ["/", "/poster", "/playreel", "/login"]; const OPEN_TREES = ["/archive", "/playreel/archive"]; function isOpen(pathname: string): boolean { return OPEN_PAGES.includes(pathname) || OPEN_TREES.some((open) => pathname === open || pathname.startsWith(`${open}/`)); } /** 시작 화면이 제출 직전에 부른다. 로그인 안 돼 있으면 로그인 화면으로 보낸다 */ export function useRequireLogin() { const router = useRouter(); const pathname = usePathname(); const { me } = useMe(); return () => { if (me === false) { router.push(`/login?next=${encodeURIComponent(pathname)}`); return false; } return true; }; } export default function AuthGate({ children }: { children: React.ReactNode }) { const pathname = usePathname(); const { me, setMe } = useMe(); const [error, setError] = useState(null); if (isOpen(pathname)) return <>{children}; if (me === null) { return

확인하는 중…

; } if (me === false) { return (

로그인이 필요합니다

구글 계정으로 들어와 주세요.

{ setError(null); signIn(credential).then(setMe).catch((failure) => setError((failure as Error).message)); }} /> {error &&

{error}

}
); } return <>{children}; }