import { state, loadMasterDataFromDB, saveAsset } from './core/state'; import { renderNavigation } from './components/Navigation'; import { renderDashboard } from './views/DashboardView'; import { renderSWTable } from './views/SW_Table'; import { initBaseModal } from './components/Modal/BaseModal'; import { initHwModal, openHwModal } from './components/Modal/HWModal'; import { initSwModal, openSwModal } from './components/Modal/SWModal'; import { initSwUserModal } from './components/Modal/SWUserModal'; import { initDomainModal, openDomainModal } from './components/Modal/DomainModal'; import { initDashboardDetailModal } from './components/Modal/DashboardDetailModal'; import { initGuide } from './components/Guide'; import { createIcons, Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, History, RefreshCcw, BookOpen, Settings } from 'lucide'; // --- DB 저장을 위한 세분화된 헬퍼 함수들 --- async function apiBatchSave(url: string, data: any[], label: string) { try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(`${label} DB 저장 실패: ${errorData.error || response.statusText}`); } console.log(`✅ ${label} DB 저장 완료`); } catch (err) { console.error(`❌ ${label} DB 저장 오류:`, err); alert(`${label} 저장 중 오류가 발생했습니다: ${(err as any).message}`); } } const savePcToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/pc/batch`, state.masterData.pc, '개인PC'); const saveServerToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/server/batch`, state.masterData.server, '서버'); const saveStorageToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/storage/batch`, state.masterData.storage, '스토리지'); const saveNetworkToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/network/batch`, state.masterData.network, '네트워크'); const saveEquipToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/equipment/batch`, state.masterData.equipment, '업무지원장비'); const saveSwInternalToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/sw/internal/batch`, state.masterData.swInternal, '내부SW'); const saveSwExternalToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/sw/external/batch`, state.masterData.swExternal, '외부SW'); const saveCloudToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/cloud/batch`, state.masterData.cloud, '클라우드'); const saveSwUsersToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/asset/software/assignment/batch`, state.masterData.swUsers, 'SW사용자'); const saveLogsToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/asset/history/batch`, state.masterData.logs, '자산 로그'); const saveUsersToDB = () => apiBatchSave(`http://${location.hostname}:3000/api/users/batch`, state.masterData.users, '사용자마스터'); // 화면 갱신 통합 핸들러 function refreshView() { const mainContent = document.getElementById('main-content')!; if (!mainContent) return; if (state.activeSubTab === '대시보드') { renderDashboard(mainContent); } else { renderSWTable(mainContent); } } // 통합 저장 및 갱신 async function saveAllDataToDB() { await Promise.all([ savePcToDB(), saveServerToDB(), saveStorageToDB(), saveNetworkToDB(), saveEquipToDB(), saveSwInternalToDB(), saveSwExternalToDB(), saveCloudToDB(), saveSwUsersToDB(), saveLogsToDB(), saveUsersToDB() ]); await loadMasterDataFromDB(); refreshView(); } // --- App Initialization --- function initApp() { const mainContent = document.getElementById('main-content')!; if (!mainContent) return; const { closeAllModals } = initBaseModal(); try { renderNavigation((tab) => { if (tab === '대시보드') { renderDashboard(mainContent); } else { renderSWTable(mainContent); } }); initHwModal(() => saveAllDataToDB(), closeAllModals); initSwModal(() => saveAllDataToDB(), closeAllModals); initSwUserModal(() => { saveSwUsersToDB().then(() => { loadMasterDataFromDB().then(() => refreshView()); }); }, closeAllModals); initDomainModal(() => saveAllDataToDB(), closeAllModals); initDashboardDetailModal(); initGuide(); loadMasterDataFromDB().then((success) => { if (success) { refreshView(); } }); } catch (e) { console.error('❌ Initialization failed:', e); } console.log('🚀 ITAM App Multi-Table Optimized'); // --- 통합 이벤트 위임 (Dynamic Elements 지원) --- document.addEventListener('click', (e) => { const target = e.target as HTMLElement; // 자산 추가 if (target.closest('#btn-add-asset')) { const tab = state.activeSubTab; const cat = state.activeCategory; const newId = Math.random().toString(36).substring(2, 9); if (cat === 'users') { // 사용자 추가는 renderUserList 내부에서 별도로 처리하거나 여기서 호출 가능 // 현재 renderUserList에서 별도로 핸들링하고 있으므로 중복 실행 방지 return; } if (cat === 'hw') { openHwModal({ id: newId, asset_code: '', category: tab } as any, 'add'); } else if (cat === 'sw') { const swType = tab === '외부SW' ? '외부SW' : (tab === '내부SW' ? '내부SW' : '외부SW'); openSwModal({ id: newId, asset_type: swType } as any, 'add'); } else if (cat === 'ops') { if (tab === '도메인') openDomainModal(null); } return; } }); createIcons({ icons: { Plus, X, LayoutDashboard, Monitor, Server, Database, Laptop, CalendarClock, Key, Cpu, Layers, Users, Paperclip, Edit2, History, RefreshCcw, BookOpen, Settings } }); window.addEventListener('refresh-view', () => refreshView()); } /** * 헤더 역할 전환 토글 로직 */ function initRoleSwitcher() { const checkbox = document.getElementById('role-toggle-checkbox') as HTMLInputElement; const userLabel = document.querySelector('.role-label.user'); const adminLabel = document.querySelector('.role-label.admin'); if (!checkbox || !userLabel || !adminLabel) return; checkbox.addEventListener('change', () => { if (checkbox.checked) { alert('관리자 모드는 현재 준비 중입니다. 나중에 관리자 전용 페이지와 연결될 예정입니다.'); checkbox.checked = false; // UI 강제 되돌리기 return; } // 실무자 모드 전환 (현재는 Admin 진입이 차단되므로 사실상 fallback 로직) state.currentUserRole = 'user'; adminLabel.classList.remove('active'); userLabel.classList.add('active'); document.body.classList.remove('admin-mode'); }); } /** * 로그인 처리 로직 */ function handleLogin() { const loginContainer = document.getElementById('login-container'); const appLayout = document.getElementById('app-layout'); const roleCards = document.querySelectorAll('.role-card'); if (!loginContainer || !appLayout || roleCards.length === 0) return; roleCards.forEach(card => { card.addEventListener('click', () => { const role = card.getAttribute('data-role'); if (role === 'admin') { alert('관리자 모드는 현재 준비 중입니다. 실무자 모드를 이용해 주세요.'); return; } if (role === 'user') { console.log('🔓 Entering as Practitioner'); // 초기 토글 상태 설정 (실무자 고정) const checkbox = document.getElementById('role-toggle-checkbox') as HTMLInputElement; if (checkbox) checkbox.checked = false; state.currentUserRole = 'user'; // UI 전환 loginContainer.style.display = 'none'; appLayout.style.display = 'flex'; // 역할 스위처 및 앱 초기화 시작 initRoleSwitcher(); initApp(); // 로고 클릭 시 초기화면 복귀 로직 (한 번만 등록) const brand = document.querySelector('.brand') as HTMLElement; if (brand) { brand.style.cursor = 'pointer'; brand.onclick = () => { location.reload(); // 즉시 초기화면으로 복귀 }; } } }); }); } document.addEventListener('DOMContentLoaded', handleLogin);