"use client";
import { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import {
Shield,
User,
LogOut,
Menu,
X,
Home,
Settings,
BarChart3,
FileText,
Users,
Package,
Wrench,
ChevronDown,
ChevronRight,
} from "lucide-react";
import { useMenu } from "@/contexts/MenuContext";
import { useAuth } from "@/hooks/useAuth";
import { MenuItem } from "@/lib/api/menu";
// useAuth의 UserInfo 타입을 확장
interface ExtendedUserInfo {
userId: string;
userName: string;
userNameEng?: string;
userNameCn?: string;
deptCode?: string;
deptName?: string;
positionCode?: string;
positionName?: string;
email?: string;
tel?: string;
cellPhone?: string;
userType?: string;
userTypeName?: string;
authName?: string;
partnerCd?: string;
isAdmin: boolean;
sabun?: string;
photo?: string | null;
companyCode?: string;
locale?: string;
}
// useAuth의 UserInfo 타입을 사용하므로 별도 정의 불필요
interface MainLayoutProps {
children: React.ReactNode;
}
// 메뉴 아이콘 매핑 함수
const getMenuIcon = (menuName: string) => {
const name = menuName.toLowerCase();
if (name.includes("대시보드") || name.includes("dashboard")) return ;
if (name.includes("관리자") || name.includes("admin")) return ;
if (name.includes("사용자") || name.includes("user")) return ;
if (name.includes("프로젝트") || name.includes("project")) return ;
if (name.includes("제품") || name.includes("product")) return ;
if (name.includes("설정") || name.includes("setting")) return ;
if (name.includes("로그") || name.includes("log")) return ;
if (name.includes("메뉴") || name.includes("menu")) return
;
return ;
};
// 메뉴 데이터를 UI용으로 변환하는 함수
const convertMenuToUI = (menus: MenuItem[], userInfo: ExtendedUserInfo | null, parentId: string = "0"): any[] => {
return menus
.filter((menu) => (menu.parent_obj_id || menu.PARENT_OBJ_ID) === parentId)
.filter((menu) => (menu.status || menu.STATUS) === "active")
.sort((a, b) => (a.seq || a.SEQ || 0) - (b.seq || b.SEQ || 0))
.map((menu) => {
const menuId = menu.objid || menu.OBJID;
// 사용자 locale 기준으로 번역 처리
const getDisplayText = (menu: MenuItem) => {
// 다국어 텍스트가 있으면 사용, 없으면 기본 텍스트 사용
if (menu.translated_name || menu.TRANSLATED_NAME) {
return menu.translated_name || menu.TRANSLATED_NAME;
}
const baseName = menu.menu_name_kor || menu.MENU_NAME_KOR || "메뉴명 없음";
// 사용자 정보에서 locale 가져오기
const userLocale = userInfo?.locale || "ko";
if (userLocale === "EN") {
// 영어 번역
const translations: { [key: string]: string } = {
관리자: "Administrator",
사용자: "User Management",
메뉴: "Menu Management",
대시보드: "Dashboard",
권한: "Permission Management",
코드: "Code Management",
설정: "Settings",
로그: "Log Management",
프로젝트: "Project Management",
제품: "Product Management",
};
for (const [korean, english] of Object.entries(translations)) {
if (baseName.includes(korean)) {
return baseName.replace(korean, english);
}
}
} else if (userLocale === "JA") {
// 일본어 번역
const translations: { [key: string]: string } = {
관리자: "管理者",
사용자: "ユーザー管理",
메뉴: "メニュー管理",
대시보드: "ダッシュボード",
권한: "権限管理",
코드: "コード管理",
설정: "設定",
로그: "ログ管理",
프로젝트: "プロジェクト管理",
제품: "製品管理",
};
for (const [korean, japanese] of Object.entries(translations)) {
if (baseName.includes(korean)) {
return baseName.replace(korean, japanese);
}
}
} else if (userLocale === "ZH") {
// 중국어 번역
const translations: { [key: string]: string } = {
관리자: "管理员",
사용자: "用户管理",
메뉴: "菜单管理",
대시보드: "仪表板",
권한: "权限管理",
코드: "代码管理",
설정: "设置",
로그: "日志管理",
프로젝트: "项目管理",
제품: "产品管理",
};
for (const [korean, chinese] of Object.entries(translations)) {
if (baseName.includes(korean)) {
return baseName.replace(korean, chinese);
}
}
}
return baseName;
};
const menuName = getDisplayText(menu);
const menuUrl = menu.menu_url || menu.MENU_URL;
console.log(
`메뉴 ${menuId}: 번역명="${menu.translated_name || menu.TRANSLATED_NAME}", 기본명="${menu.menu_name_kor || menu.MENU_NAME_KOR}", 최종명="${menuName}"`,
);
const children = convertMenuToUI(menus, userInfo, menuId);
return {
id: menuId,
title: menuName,
icon: getMenuIcon(menuName || ""),
path: menuUrl,
children: children.length > 0 ? children : undefined,
};
});
};
export default function MainLayout({ children }: MainLayoutProps) {
const router = useRouter();
const { adminMenus, userMenus, loading: menuLoading } = useMenu();
const { user, loading: authLoading, logout } = useAuth();
const [sidebarOpen, setSidebarOpen] = useState(true);
const [expandedMenus, setExpandedMenus] = useState([]);
// 사용자의 회사 코드에 따라 메뉴 필터링
const filterMenusByCompany = (menus: MenuItem[]) => {
console.log("=== 메뉴 필터링 시작 ===");
console.log("사용자 정보:", user);
console.log("사용자 회사 코드:", (user as ExtendedUserInfo)?.companyCode);
console.log("전체 메뉴 수:", menus.length);
console.log("현재 경로:", window.location.pathname);
// 모든 메뉴 표시 (원래 상태로 복원)
console.log("모든 메뉴 표시");
return menus;
};
// 활성 메뉴만 필터링하여 UI용으로 변환 (언어 변경 시 재계산)
const activeMenus = [...adminMenus, ...userMenus].filter((menu) => (menu.status || menu.STATUS) === "active");
const filteredMenus = filterMenusByCompany(activeMenus);
const menuItems = convertMenuToUI(filteredMenus, user);
// 디버깅 로그 추가
console.log("=== MainLayout 메뉴 디버깅 ===");
console.log("adminMenus 개수:", adminMenus.length);
console.log("userMenus 개수:", userMenus.length);
console.log("activeMenus 개수:", activeMenus.length);
console.log("filteredMenus 개수:", filteredMenus.length);
console.log("menuItems 개수:", menuItems.length);
// 번역 데이터 확인
if (menuItems.length > 0) {
console.log("첫 번째 메뉴 아이템:", {
id: menuItems[0].id,
title: menuItems[0].title,
hasChildren: !!menuItems[0].children,
});
}
if (adminMenus.length > 0) {
console.log("첫 번째 adminMenu:", adminMenus[0]);
}
if (userMenus.length > 0) {
console.log("첫 번째 userMenu:", userMenus[0]);
}
// useAuth 훅에서 인증 상태를 관리하므로 별도 인증 확인 불필요
// useEffect(() => {
// checkAuthStatus();
// }, []);
// 키보드 단축키로 사이드바 토글
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
// Ctrl+B 또는 Cmd+B로 사이드바 토글
if ((event.ctrlKey || event.metaKey) && event.key === "b") {
event.preventDefault();
setSidebarOpen((prev) => !prev);
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, []);
const handleLogout = async () => {
await logout();
};
const toggleMenu = (menuId: string) => {
setExpandedMenus((prev) => (prev.includes(menuId) ? prev.filter((id) => id !== menuId) : [...prev, menuId]));
};
const handleMenuClick = (path?: string) => {
if (path) {
router.push(path);
}
};
if (authLoading) {
return (
);
}
if (!user) {
return null;
}
return (
{/* 상단 헤더 */}
PLM 솔루션
{user.userName}
{user.deptName && ({user.deptName})}
{/* 모바일 사이드바 오버레이 */}
{sidebarOpen && (
setSidebarOpen(false)} />
)}
{/* 왼쪽 사이드바 */}
{/* 가운데 컨텐츠 영역 */}
{children}
);
}