'use client'; import Link from 'next/link'; import { usePathname, useRouter } from 'next/navigation'; import { useMemo, useState, useEffect } from 'react'; import { createClient } from '@/lib/supabase/client'; import type { User } from '@supabase/supabase-js'; const LINKS = [ { href: '/outsourcing', label: '외주 개발' }, { href: '/products', label: '소프트웨어' }, ]; export default function TopNav() { const pathname = usePathname(); const router = useRouter(); const supabase = useMemo(() => createClient(), []); const [open, setOpen] = useState(false); const [scrolled, setScrolled] = useState(false); const [user, setUser] = useState(null); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 8); onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); // Supabase auth state subscription (Sidebar.tsx:93-103 패턴) useEffect(() => { let mounted = true; supabase.auth.getSession().then(({ data }) => { if (mounted) setUser(data.session?.user ?? null); }); const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => { if (mounted) setUser(session?.user ?? null); }); return () => { mounted = false; subscription.unsubscribe(); }; }, [supabase]); const handleLogout = async () => { await supabase.auth.signOut(); setOpen(false); router.replace('/'); router.refresh(); }; useEffect(() => { setOpen(false); }, [pathname]); useEffect(() => { if (open) { const prev = document.body.style.overflow; document.body.style.overflow = 'hidden'; return () => { document.body.style.overflow = prev; }; } }, [open]); useEffect(() => { if (!open) return; const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false); }; window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, [open]); const isActive = (href: string) => { if (href === '/') return pathname === '/'; return pathname === href || pathname.startsWith(href + '/'); }; return ( <>
{/* 모바일 드로어 */} {open && (
setOpen(false)} >
e.stopPropagation()} role="dialog" aria-modal="true" aria-label="메뉴" > {/* 드로어 헤더 */}
JSM 쟁승메이드
{/* 드로어 링크 */}
{LINKS.map((l) => ( {l.label} ))}
{user ? ( <> 마이페이지 ) : ( 로그인 )}
{/* 드로어 하단 CTA */}
프로젝트 문의
)} ); }