Files
ITAM/src/components/Navigation.ts

121 lines
4.1 KiB
TypeScript

import { state } from '../core/state';
const MENU_CONFIG: any = {
hw: {
label: '하드웨어',
tabs: ['대시보드', '서버', 'PC', '스토리지', '공간정보장비', 'PC부품', '부품 마스터', '네트워크', '업무지원장비']
},
sw: {
label: '소프트웨어',
tabs: ['외부SW', '내부SW']
},
ops: {
label: '운영지원',
tabs: ['클라우드', '도메인', '비용관리', '사용자']
},
vip: {
label: '내빈/외빈',
tabs: ['선물']
},
fac: {
label: '시설자산',
tabs: ['사무가구']
}
};
export function renderNavigation(onTabChange: (tab: string) => void) {
const header = document.querySelector('.main-header') as HTMLElement;
const headerContainer = document.querySelector('.header-container')!;
if (!headerContainer) return;
const render = () => {
// 1. 헤더 구조 (Vercel Style: Clean Single Row)
headerContainer.innerHTML = `
<div class="brand" id="btn-home-logo" style="cursor: pointer;">
<img src="img/image_92.png" class="main-logo" alt="HM Logo" />
<h1>한맥자산관리시스템</h1>
</div>
<nav class="integrated-nav" id="main-nav-list"></nav>
<div class="header-actions">
<div class="role-toggle-wrapper">
<span class="role-label user ${state.currentUserRole === 'user' ? 'active' : ''}">실무자</span>
<label class="role-toggle">
<input type="checkbox" id="role-toggle-checkbox" ${state.currentUserRole === 'admin' ? 'checked' : ''}>
<span class="role-slider"></span>
</label>
<span class="role-label admin ${state.currentUserRole === 'admin' ? 'active' : ''}">관리자</span>
</div>
<div class="notification-area">
<button class="icon-btn" title="알림"><i data-lucide="bell" style="width:18px; height:18px;"></i></button>
</div>
</div>
`;
const navList = document.getElementById('main-nav-list')!;
// 2. GNB 메뉴 렌더링 (Ghost Tab Style)
Object.keys(MENU_CONFIG).forEach(catKey => {
const config = MENU_CONFIG[catKey];
const visibleTabs = config.tabs.filter((tab: string) => {
if (state.currentUserRole === 'admin') return tab === '대시보드';
return tab !== '대시보드';
});
if (visibleTabs.length === 0) return;
visibleTabs.forEach((tab: string) => {
if (tab === '부품 마스터') return;
const item = document.createElement('div');
const isActive = state.activeSubTab === tab;
item.className = `gnb-trigger ${isActive ? 'active' : ''}`;
item.textContent = tab;
item.style.fontSize = 'var(--fs-sm)'; // Ensure small but standard font
item.addEventListener('click', (e) => {
e.stopPropagation();
state.activeCategory = catKey as any;
state.activeSubTab = tab;
render();
onTabChange(tab);
});
navList.appendChild(item);
});
});
// 3. 관리자 전용 '관리도구'
if (state.currentUserRole === 'admin') {
const adminTrigger = document.createElement('div');
adminTrigger.className = 'gnb-trigger admin-trigger';
adminTrigger.innerHTML = '관리도구';
adminTrigger.addEventListener('click', () => window.open('/map_editor.html', '_blank'));
navList.appendChild(adminTrigger);
}
// 4. 이벤트 바인딩
document.getElementById('btn-home-logo')?.addEventListener('click', () => location.reload());
const roleToggle = document.getElementById('role-toggle-checkbox') as HTMLInputElement;
roleToggle?.addEventListener('change', () => {
state.currentUserRole = roleToggle.checked ? 'admin' : 'user';
if (state.currentUserRole === 'admin') {
state.activeCategory = 'hw';
state.activeSubTab = '대시보드';
} else {
state.activeCategory = 'hw';
state.activeSubTab = '서버';
}
render();
onTabChange(state.activeSubTab);
});
// 아이콘 생성
// @ts-ignore
if (window.lucide) window.lucide.createIcons();
};
render();
}