// /js/project-analysis.js import { getMasterData, getWorkReports } from './project-analysis-api.js'; import { processRawData, applyFilters, getAnalysis } from './project-analysis-data.js'; import { setDefaultDates, setUIState, updateFilterOptions, renderSummary, renderAnalysisTables, renderDetailTable, switchTab, getCurrentFilters, } from './project-analysis-ui.js'; // 애플리케이션 상태 (전역 변수 최소화) const state = { masterData: null, processedData: [], filteredData: [], }; // DOM 요소 참조 (이벤트 리스너 설정용) const DOM = { startDate: document.getElementById('startDate'), endDate: document.getElementById('endDate'), analyzeBtn: document.getElementById('analyzeBtn'), quickMonthBtn: document.getElementById('quickMonth'), quickLastMonthBtn: document.getElementById('quickLastMonth'), applyFilterBtn: document.getElementById('applyFilter'), tabButtons: document.querySelectorAll('.tab-button'), }; /** * 분석 실행 버튼 클릭 이벤트 핸들러 */ async function handleAnalysis() { const startDate = DOM.startDate.value; const endDate = DOM.endDate.value; if (!startDate || !endDate || startDate > endDate) { alert('올바른 분석 기간을 설정해주세요.'); return; } setUIState('loading'); try { const rawReports = await getWorkReports(startDate, endDate); state.processedData = processRawData(rawReports, state.masterData); if (state.processedData.length === 0) { setUIState('no-data'); updateFilterOptions([]); return; } updateFilterOptions(state.processedData); handleFilterChange(); // 필터 적용 및 렌더링 setUIState('data'); } catch (error) { console.error('분석 처리 중 오류:', error); setUIState('error'); alert(error.message); } } /** * 필터 적용 버튼 클릭 또는 분석 후 자동 실행되는 핸들러 */ function handleFilterChange() { const filters = getCurrentFilters(); state.filteredData = applyFilters(state.processedData, filters); const analysisResult = getAnalysis(state.filteredData); renderSummary(analysisResult.summary); renderAnalysisTables(analysisResult); renderDetailTable(state.filteredData); } /** * 빠른 날짜 설정 버튼 핸들러 * @param {'this' | 'last'} monthType - 이번 달 또는 지난 달 */ function handleQuickDate(monthType) { const now = new Date(); const year = now.getFullYear(); const month = now.getMonth(); const firstDay = monthType === 'this' ? new Date(year, month, 1) : new Date(year, month - 1, 1); const lastDay = monthType === 'this' ? new Date(year, month + 1, 0) : new Date(year, month, 0); DOM.startDate.value = firstDay.toISOString().split('T')[0]; DOM.endDate.value = lastDay.toISOString().split('T')[0]; } /** * 이벤트 리스너 설정 */ function setupEventListeners() { DOM.analyzeBtn.addEventListener('click', handleAnalysis); DOM.applyFilterBtn.addEventListener('click', handleFilterChange); DOM.quickMonthBtn.addEventListener('click', () => handleQuickDate('this')); DOM.quickLastMonthBtn.addEventListener('click', () => handleQuickDate('last')); DOM.tabButtons.forEach(btn => { btn.addEventListener('click', () => switchTab(btn.dataset.tab)); }); } /** * 페이지 초기화 함수 */ async function initialize() { setDefaultDates(); setupEventListeners(); try { state.masterData = await getMasterData(); // 페이지 로드 시 바로 분석 실행 await handleAnalysis(); } catch (error) { alert(error.message); setUIState('error'); } } // 초기화 실행 document.addEventListener('DOMContentLoaded', initialize);