"use client"; import { useState, useEffect } from "react"; import { useAuth } from "@/hooks/useAuth"; import { useMenu } from "@/hooks/useMenu"; import { useProfile } from "@/hooks/useProfile"; import { MainHeader } from "@/components/layout/MainHeader"; import { MainSidebar } from "@/components/layout/MainSidebar"; import { ProfileModal } from "@/components/layout/ProfileModal"; import { LAYOUT_CONFIG } from "@/constants/layout"; /** * 메인 레이아웃 컴포넌트 * 비즈니스 로직은 커스텀 훅들에서 처리하고, UI 컴포넌트들을 조합하여 구성 */ export default function MainLayout({ children }: { children: React.ReactNode }) { const { user, logout, refreshUserData, loading: authLoading } = useAuth(); const [isSidebarOpen, setIsSidebarOpen] = useState(false); // 사이드바 상태 const [isMobile, setIsMobile] = useState(false); // 모바일 여부 // 화면 크기 감지 useEffect(() => { const checkMobile = () => { const mobile = window.innerWidth < 768; // md breakpoint setIsMobile(mobile); // 모바일에서는 사이드바를 기본적으로 닫아둠 if (mobile) { setIsSidebarOpen(false); } // PC에서는 사이드바 상태를 건드리지 않음 (항상 표시) }; checkMobile(); window.addEventListener("resize", checkMobile); return () => window.removeEventListener("resize", checkMobile); }, []); // 메뉴 관련 로직 const { menuList, expandedMenus, handleMenuClick } = useMenu(user, authLoading); // 프로필 관련 로직 const { isModalOpen, formData, selectedImage, isSaving, alertModal, closeAlert, openProfileModal, closeProfileModal, updateFormData, selectImage, removeImage, saveProfile, } = useProfile(user, refreshUserData); /** * 사이드바 토글 처리 (모바일에서만 동작) */ const handleSidebarToggle = () => { if (isMobile) { // 모바일에서만 토글 동작 setIsSidebarOpen(!isSidebarOpen); } // PC에서는 아무것도 하지 않음 (항상 표시) }; /** * 로그아웃 처리 */ const handleLogout = async () => { await logout(); }; return (
{/* 데스크톱 고정 사이드바 - md 이상에서 항상 표시 */} {/* 모바일 오버레이 사이드바 - md 미만에서만 표시 */} {isMobile && (
{/* 배경 오버레이 */}
setIsSidebarOpen(false)} /> {/* 사이드바 */}
)} {/* Main Content - 반응형 여백 적용 */}
{children}
{/* 프로필 수정 모달 */}
); }