'use client'; import Styles from '../styles/layout.module.scss'; import { useCallback } from 'react'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; import useAuth from '@/hooks/useAuth'; import useDragScroll from '@/hooks/useDragScroll'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faBars, faXmark, faCartShopping, faChevronLeft, faChevronRight, faSun, faMoon } from '@fortawesome/free-solid-svg-icons'; import NotificationBell from '@/app/component/NotificationBell'; import HeaderSearch from '@/app/component/HeaderSearch'; import SearchCommand from '@/app/component/SearchCommand'; import Profile from '@/app/component/Profile'; import Logo from '@/app/component/Logo'; import PointChargeIcon from '@/public/icons/layout/point.svg'; import useCart from '@/hooks/useCart'; import useTheme from '@/hooks/useTheme'; import { FEATURE_CHANNEL } from '@/constants/features'; import { useConfigContext } from '@/contexts/configProvider'; // 채널/방송 메뉴(생방송·크리에이터)는 채널 기능 ON 일 때만 노출 const channelNavItems = [ { href: '/live', label: '생방송' }, { href: '/creators', label: '크리에이터' } ]; // 관리자 관리형 메뉴(config.navMenu)가 비어 있을 때의 폴백 — 기존 하드코딩 목록 const baseNavItems = [ { href: '/market', label: '시장' }, { href: '/stock', label: '종목' }, { href: '/paper', label: '모의투자' }, { href: '/games', label: '게임' }, { href: '/board/briefing', label: '장전 시황' }, { href: '/board/proof', label: '수익인증' }, { href: '/feed/all', label: '피드' }, { href: '/store', label: '상점' }, { href: '/attendance', label: '출석부' }, { href: '/board/notice', label: '고객지원' } ]; const SCROLL_AMOUNT = 120; type Props = { sidebarOpen: boolean; onToggle: () => void; // 좌측 사이드바 노출 여부 — false 면 모바일 햄버거(사이드바 토글)도 숨김 showAside?: boolean; }; export default function Header({ sidebarOpen, onToggle, showAside = true }: Props) { const { isAuthenticated } = useAuth(); const { totalCount: cartCount } = useCart(); const { toggleTheme, isDark } = useTheme(); const pathname = usePathname(); const dragScroll = useDragScroll(); const config = useConfigContext(); // 상단 메뉴: 관리자 관리형(config.navMenu)이 있으면 사용, 없으면 하드코딩 폴백 const baseItems = config?.navMenu && config.navMenu.length > 0 ? config.navMenu : baseNavItems; const navItems = FEATURE_CHANNEL ? [...channelNavItems, ...baseItems] : baseItems; const scrollTabs = useCallback((dir: 'left' | 'right') => { const el = dragScroll.ref.current; if (!el) { return; } el.scrollBy({ left: dir === 'left' ? -SCROLL_AMOUNT : SCROLL_AMOUNT, behavior: 'smooth' }); }, [dragScroll.ref]); const handlePopupCharge = useCallback(() => { const w = 450, h = 635; const left = window.screenX + (window.outerWidth - w) / 2; const top = window.screenY + (window.outerHeight - h) / 2; window.open('/charge', 'charge', `width=${w},height=${h},left=${left},top=${top},scrollbars=no,resizable=no`); }, []); return ( ); }