diff --git a/src/layouts/DashboardLayout.tsx b/src/layouts/DashboardLayout.tsx index 3f7c467..48b0ea9 100644 --- a/src/layouts/DashboardLayout.tsx +++ b/src/layouts/DashboardLayout.tsx @@ -1,57 +1,158 @@ import { Outlet } from 'react-router-dom'; -import { SidebarProvider, Sidebar, SidebarHeader, SidebarContent, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarTrigger } from '@/components/ui/sidebar'; import { useMenuStore } from '@/store/menuStore'; import { useNavigate } from 'react-router-dom'; +import { useEffect } from 'react'; +import { + LayoutDashboard, + ShoppingCart, + Factory, + ClipboardCheck, + Package, + Database, + ChevronDown, + Menu, +} from 'lucide-react'; export default function DashboardLayout() { - const { menuItems, activeMenu, setActiveMenu, sidebarCollapsed } = useMenuStore(); + const { menuItems, activeMenu, setActiveMenu, setMenuItems } = useMenuStore(); const navigate = useNavigate(); + // 현재 사용자 역할 가져오기 + const userDataStr = localStorage.getItem("user"); + const userData = userDataStr ? JSON.parse(userDataStr) : null; + const currentRole = userData?.role || "CEO"; + + // 역할별 대시보드 정의 + const roleDashboards = [ + { role: 'SystemAdmin', label: '시스템 관리자', icon: Database }, + { role: 'CEO', label: 'CEO', icon: LayoutDashboard }, + { role: 'ProductionManager', label: '생산 관리자', icon: Factory }, + ]; + + // 초기 메뉴 설정 + useEffect(() => { + if (menuItems.length === 0) { + setMenuItems([ + { + id: 'dashboard', + label: '대시보드', + icon: LayoutDashboard, + path: '/dashboard' + }, + { + id: 'sales-leads', + label: '영업 대시보드', + icon: ShoppingCart, + path: '/dashboard/sales-leads' + }, + { + id: 'production', + label: '생산관리', + icon: Factory, + path: '/dashboard/production' + }, + { + id: 'quality', + label: '품질관리', + icon: ClipboardCheck, + path: '/dashboard/quality' + }, + { + id: 'materials', + label: '자재관리', + icon: Package, + path: '/dashboard/materials' + }, + ]); + } + }, [menuItems.length, setMenuItems]); + const handleMenuClick = (menuId: string, path: string) => { setActiveMenu(menuId); navigate(path); }; - return ( - -
- - -
-
- S -
- SAM -
-
- - - {menuItems.map((item) => ( - - handleMenuClick(item.id, item.path)} - isActive={activeMenu === item.id} - > - - {item.label} - - - ))} - - -
+ const handleRoleChange = (role: string) => { + // 역할 변경 시 localStorage 업데이트 + if (userData) { + userData.role = role; + localStorage.setItem("user", JSON.stringify(userData)); + // 페이지 새로고침하여 역할별 대시보드 표시 + window.location.reload(); + } + }; -
-
- -
- {/* 테마 토글, 사용자 메뉴 등 추가 가능 */} -
-
- -
-
+ if (menuItems.length === 0) { + return
Loading...
; + } + + return ( +
+
+
+

SAM

+
+
- + +
+
+ +
+ + {/* 역할별 대시보드 전환 버튼 */} +
+ + + {/* 드롭다운 메뉴 */} +
+ {roleDashboards.map((dashboard) => { + const DashboardIcon = dashboard.icon; + return ( + + ); + })} +
+
+
+
+ +
+
+
); } \ No newline at end of file diff --git a/src/store/menuStore.ts b/src/store/menuStore.ts index a1937c9..6c533d9 100644 --- a/src/store/menuStore.ts +++ b/src/store/menuStore.ts @@ -38,6 +38,11 @@ export const useMenuStore = create()( }), { name: 'sam-menu', + // menuItems는 함수(icon)를 포함하므로 localStorage에서 제외 + partialize: (state) => ({ + activeMenu: state.activeMenu, + sidebarCollapsed: state.sidebarCollapsed, + }), } ) ); \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index 78e84c5..5d1d25c 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -26,12 +26,14 @@ export default defineConfig({ host: '0.0.0.0', // Docker 컨테이너 내 모든 네트워크 인터페이스에서 접근 허용 port: 5173, strictPort: true, - // Nginx 리버스 프록시를 통한 도메인 접근 허용 - hmr: { - clientPort: 80, // HTTP 사용 (nginx가 port 80에서 리스닝) - protocol: 'ws', // HTTP 환경에서는 WebSocket (ws) 사용 - host: 'dev.sam.kr', // HMR 연결 시 사용할 호스트 - }, + // 환경별 HMR 설정: Docker 환경에서만 커스텀 설정 사용 + hmr: process.env.VITE_DOCKER_ENV === 'true' + ? { + clientPort: 80, // HTTP 사용 (nginx가 port 80에서 리스닝) + protocol: 'ws', // HTTP 환경에서는 WebSocket (ws) 사용 + host: 'dev.sam.kr', // HMR 연결 시 사용할 호스트 + } + : true, // 로컬 환경에서는 기본 HMR 설정 사용 // 파일 감시 설정 (Docker 환경에서 필수) watch: { usePolling: true,