/** * 페이지 관리자 * 모듈화된 페이지들의 생명주기를 관리하고 부드러운 전환을 제공 */ class PageManager { constructor() { this.currentPage = null; this.loadedModules = new Map(); this.pageHistory = []; } /** * 페이지 초기화 * @param {string} pageId - 페이지 식별자 * @param {Object} options - 초기화 옵션 */ async initializePage(pageId, options = {}) { try { // 로딩 표시 this.showPageLoader(); // 사용자 인증 확인 const user = await this.checkAuthentication(); if (!user) return; // 공통 헤더 초기화 await this.initializeCommonHeader(user, pageId); // 페이지별 권한 체크 if (!this.checkPagePermission(pageId, user)) { this.redirectToAccessiblePage(); return; } // 페이지 모듈 로드 및 초기화 await this.loadPageModule(pageId, options); // 페이지 히스토리 업데이트 this.updatePageHistory(pageId); // 로딩 숨기기 this.hidePageLoader(); } catch (error) { console.error('페이지 초기화 실패:', error); this.showErrorPage(error); } } /** * 사용자 인증 확인 */ async checkAuthentication() { const token = localStorage.getItem('access_token'); if (!token) { window.location.href = '/index.html'; return null; } try { // API가 로드될 때까지 대기 await this.waitForAPI(); const user = await AuthAPI.getCurrentUser(); localStorage.setItem('currentUser', JSON.stringify(user)); return user; } catch (error) { console.error('인증 실패:', error); localStorage.removeItem('access_token'); localStorage.removeItem('currentUser'); window.location.href = '/index.html'; return null; } } /** * API 로드 대기 */ async waitForAPI() { let attempts = 0; const maxAttempts = 50; while (!window.AuthAPI && attempts < maxAttempts) { await new Promise(resolve => setTimeout(resolve, 100)); attempts++; } if (!window.AuthAPI) { throw new Error('API를 로드할 수 없습니다.'); } } /** * 공통 헤더 초기화 */ async initializeCommonHeader(user, pageId) { // 권한 시스템 초기화 if (window.pagePermissionManager) { window.pagePermissionManager.setUser(user); } // 공통 헤더 초기화 if (window.commonHeader) { await window.commonHeader.init(user, pageId); } } /** * 페이지 권한 체크 */ checkPagePermission(pageId, user) { // admin은 모든 페이지 접근 가능 if (user.role === 'admin') { return true; } // 권한 시스템이 로드되지 않았으면 기본 페이지만 허용 if (!window.canAccessPage) { return ['issues_create', 'issues_view'].includes(pageId); } return window.canAccessPage(pageId); } /** * 접근 가능한 페이지로 리다이렉트 */ redirectToAccessiblePage() { alert('이 페이지에 접근할 권한이 없습니다.'); // 기본적으로 접근 가능한 페이지로 이동 if (window.canAccessPage && window.canAccessPage('issues_view')) { window.location.href = '/issue-view.html'; } else { window.location.href = '/index.html'; } } /** * 페이지 모듈 로드 */ async loadPageModule(pageId, options) { // 이미 로드된 모듈이 있으면 재사용 if (this.loadedModules.has(pageId)) { const module = this.loadedModules.get(pageId); if (module.reinitialize) { await module.reinitialize(options); } return; } // 페이지별 모듈 로드 const module = await this.createPageModule(pageId, options); if (module) { this.loadedModules.set(pageId, module); this.currentPage = pageId; } } /** * 페이지 모듈 생성 */ async createPageModule(pageId, options) { switch (pageId) { case 'issues_create': return new IssuesCreateModule(options); case 'issues_view': return new IssuesViewModule(options); case 'issues_manage': return new IssuesManageModule(options); case 'projects_manage': return new ProjectsManageModule(options); case 'daily_work': return new DailyWorkModule(options); case 'reports': return new ReportsModule(options); case 'users_manage': return new UsersManageModule(options); default: console.warn(`알 수 없는 페이지 ID: ${pageId}`); return null; } } /** * 페이지 히스토리 업데이트 */ updatePageHistory(pageId) { this.pageHistory.push({ pageId, timestamp: new Date(), url: window.location.href }); // 히스토리 크기 제한 (최대 10개) if (this.pageHistory.length > 10) { this.pageHistory.shift(); } } /** * 페이지 로더 표시 */ showPageLoader() { const existingLoader = document.getElementById('page-loader'); if (existingLoader) return; const loader = document.createElement('div'); loader.id = 'page-loader'; loader.className = 'fixed inset-0 bg-white bg-opacity-90 flex items-center justify-center z-50'; loader.innerHTML = `
페이지를 로드하는 중...
잠시만 기다려주세요
${error.message || '알 수 없는 오류가 발생했습니다.'}
${message}
${message}