import { ChevronRight, Circle } from 'lucide-react'; import type { MenuItem } from '@/store/menuStore'; import { useEffect, useRef } from 'react'; interface SidebarProps { menuItems: MenuItem[]; activeMenu: string; expandedMenus: string[]; sidebarCollapsed: boolean; isMobile: boolean; onMenuClick: (menuId: string, path: string) => void; onToggleSubmenu: (menuId: string) => void; onCloseMobileSidebar?: () => void; } // 재귀적 메뉴 아이템 컴포넌트 Props interface MenuItemComponentProps { item: MenuItem; depth: number; // 0: 1depth, 1: 2depth, 2: 3depth activeMenu: string; expandedMenus: string[]; sidebarCollapsed: boolean; isMobile: boolean; activeMenuRef: React.RefObject; onMenuClick: (menuId: string, path: string) => void; onToggleSubmenu: (menuId: string) => void; onCloseMobileSidebar?: () => void; } // 재귀적 메뉴 아이템 컴포넌트 (3depth 이상 지원) function MenuItemComponent({ item, depth, activeMenu, expandedMenus, sidebarCollapsed, isMobile, activeMenuRef, onMenuClick, onToggleSubmenu, onCloseMobileSidebar, }: MenuItemComponentProps) { const IconComponent = item.icon; const hasChildren = item.children && item.children.length > 0; const isExpanded = expandedMenus.includes(item.id); const isActive = activeMenu === item.id; const handleClick = () => { if (hasChildren) { onToggleSubmenu(item.id); } else { onMenuClick(item.id, item.path); if (isMobile && onCloseMobileSidebar) { onCloseMobileSidebar(); } } }; // depth별 스타일 설정 // 1depth (depth=0): 아이콘 + 굵은 텍스트 + 배경색 // 2depth (depth=1): 작은 아이콘 + 일반 텍스트 + 왼쪽 보더 // 3depth (depth=2+): 점(dot) 아이콘 + 작은 텍스트 + 더 깊은 들여쓰기 const is1Depth = depth === 0; const is2Depth = depth === 1; const is3DepthOrMore = depth >= 2; // 1depth 메뉴 렌더링 if (is1Depth) { return (
{/* 메인 메뉴 버튼 */} {/* 자식 메뉴 (재귀) */} {hasChildren && isExpanded && !sidebarCollapsed && (
{item.children?.map((child) => ( ))}
)}
); } // 2depth 메뉴 렌더링 if (is2Depth) { return (
{/* 자식 메뉴 (3depth) */} {hasChildren && isExpanded && (
{item.children?.map((child) => ( ))}
)}
); } // 3depth 이상 메뉴 렌더링 (점 아이콘 + 작은 텍스트) if (is3DepthOrMore) { return (
{/* 자식 메뉴 (4depth 이상 - 재귀) */} {hasChildren && isExpanded && (
{item.children?.map((child) => ( ))}
)}
); } return null; } export default function Sidebar({ menuItems, activeMenu, expandedMenus, sidebarCollapsed, isMobile, onMenuClick, onToggleSubmenu, onCloseMobileSidebar, }: SidebarProps) { // 활성 메뉴 자동 스크롤을 위한 ref const activeMenuRef = useRef(null); const menuContainerRef = useRef(null); // 활성 메뉴가 변경될 때 자동 스크롤 useEffect(() => { if (activeMenuRef.current && menuContainerRef.current) { // 부드러운 스크롤로 활성 메뉴를 화면에 표시 activeMenuRef.current.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest', }); } }, [activeMenu]); return (
{/* 메뉴 */}
{menuItems.map((item) => ( ))}
); }