/** * TBM - Module Loader * TBM 모듈을 초기화하고 연결하는 메인 진입점 * * 로드 순서: * 1. state.js - 전역 상태 관리 * 2. utils.js - 유틸리티 함수 * 3. api.js - API 클라이언트 * 4. index.js - 이 파일 (메인 컨트롤러) */ class TbmController { constructor() { this.state = window.TbmState; this.api = window.TbmAPI; this.utils = window.TbmUtils; this.initialized = false; console.log('[TbmController] 생성'); } /** * 초기화 */ async init() { if (this.initialized) { console.log('[TbmController] 이미 초기화됨'); return; } console.log('🛠️ TBM 관리 페이지 초기화'); // API 함수가 로드될 때까지 대기 let retryCount = 0; while (!window.apiCall && retryCount < 50) { await new Promise(resolve => setTimeout(resolve, 100)); retryCount++; } if (!window.apiCall) { window.showToast?.('시스템을 초기화할 수 없습니다. 페이지를 새로고침해주세요.', 'error'); return; } // 오늘 날짜 설정 (서울 시간대 기준) const today = this.utils.getTodayKST(); const tbmDateEl = document.getElementById('tbmDate'); const sessionDateEl = document.getElementById('sessionDate'); if (tbmDateEl) tbmDateEl.value = today; if (sessionDateEl) sessionDateEl.value = today; // 이벤트 리스너 설정 this.setupEventListeners(); // 초기 데이터 로드 await this.api.loadInitialData(); await this.api.loadTodayOnlyTbm(); // 렌더링 this.displayTodayTbmSessions(); this.initialized = true; console.log('[TbmController] 초기화 완료'); } /** * 이벤트 리스너 설정 */ setupEventListeners() { // 탭 버튼들 document.querySelectorAll('.tbm-tab-btn').forEach(btn => { btn.addEventListener('click', () => { const tabName = btn.dataset.tab; if (tabName) this.switchTbmTab(tabName); }); }); } /** * 탭 전환 */ async switchTbmTab(tabName) { this.state.setCurrentTab(tabName); // 탭 버튼 활성화 상태 변경 document.querySelectorAll('.tbm-tab-btn').forEach(btn => { if (btn.dataset.tab === tabName) { btn.classList.add('active'); } else { btn.classList.remove('active'); } }); // 탭 컨텐츠 표시 변경 document.querySelectorAll('.tbm-tab-content').forEach(content => { content.classList.remove('active'); }); const tabContent = document.getElementById(`${tabName}-tab`); if (tabContent) tabContent.classList.add('active'); // 탭에 따라 데이터 로드 if (tabName === 'tbm-input') { await this.api.loadTodayOnlyTbm(); this.displayTodayTbmSessions(); } else if (tabName === 'tbm-manage') { await this.api.loadRecentTbmGroupedByDate(); this.displayTbmGroupedByDate(); this.updateViewModeIndicator(); } } /** * 오늘의 TBM 세션 표시 */ displayTodayTbmSessions() { const grid = document.getElementById('todayTbmGrid'); const emptyState = document.getElementById('todayEmptyState'); const todayTotalEl = document.getElementById('todayTotalSessions'); const todayCompletedEl = document.getElementById('todayCompletedSessions'); const todayActiveEl = document.getElementById('todayActiveSessions'); const sessions = this.state.todaySessions; if (sessions.length === 0) { if (grid) grid.innerHTML = ''; if (emptyState) emptyState.style.display = 'flex'; if (todayTotalEl) todayTotalEl.textContent = '0'; if (todayCompletedEl) todayCompletedEl.textContent = '0'; if (todayActiveEl) todayActiveEl.textContent = '0'; return; } if (emptyState) emptyState.style.display = 'none'; const completedCount = sessions.filter(s => s.status === 'completed').length; const activeCount = sessions.filter(s => s.status === 'draft').length; if (todayTotalEl) todayTotalEl.textContent = sessions.length; if (todayCompletedEl) todayCompletedEl.textContent = completedCount; if (todayActiveEl) todayActiveEl.textContent = activeCount; if (grid) { grid.innerHTML = sessions.map(session => this.createSessionCard(session)).join(''); } } /** * 날짜별 그룹으로 TBM 표시 */ displayTbmGroupedByDate() { const container = document.getElementById('tbmDateGroupsContainer'); const emptyState = document.getElementById('emptyState'); const totalSessionsEl = document.getElementById('totalSessions'); const completedSessionsEl = document.getElementById('completedSessions'); if (!container) return; const sortedDates = Object.keys(this.state.dateGroupedSessions).sort((a, b) => new Date(b) - new Date(a) ); if (sortedDates.length === 0 || this.state.allLoadedSessions.length === 0) { container.innerHTML = ''; if (emptyState) emptyState.style.display = 'flex'; if (totalSessionsEl) totalSessionsEl.textContent = '0'; if (completedSessionsEl) completedSessionsEl.textContent = '0'; return; } if (emptyState) emptyState.style.display = 'none'; // 통계 업데이트 const completedCount = this.state.allLoadedSessions.filter(s => s.status === 'completed').length; if (totalSessionsEl) totalSessionsEl.textContent = this.state.allLoadedSessions.length; if (completedSessionsEl) completedSessionsEl.textContent = completedCount; // 날짜별 그룹 HTML 생성 const today = this.utils.getTodayKST(); const dayNames = ['일', '월', '화', '수', '목', '금', '토']; container.innerHTML = sortedDates.map(date => { const sessions = this.state.dateGroupedSessions[date]; const dateObj = new Date(date + 'T00:00:00'); const dayName = dayNames[dateObj.getDay()]; const isToday = date === today; const [year, month, day] = date.split('-'); const displayDate = `${parseInt(month)}월 ${parseInt(day)}일`; return `