/** * m-dashboard.js — 현황판 모바일 페이지 로직 */ var currentUser = null; var allIssues = []; var projects = []; var filteredIssues = []; // 모달/시트 상태 var selectedOpinionIssueId = null; var selectedCommentIssueId = null; var selectedCommentOpinionIndex = null; var selectedReplyIssueId = null; var selectedReplyOpinionIndex = null; var selectedReplyCommentIndex = null; var selectedCompletionIssueId = null; var selectedRejectionIssueId = null; var completionPhotoBase64 = null; // 수정 상태 var editMode = null; // 'opinion', 'comment', 'reply' var editIssueId = null; var editOpinionIndex = null; var editCommentIndex = null; var editReplyIndex = null; // ===== 초기화 ===== async function initialize() { currentUser = await mCheckAuth(); if (!currentUser) return; await Promise.all([loadProjects(), loadIssues()]); updateStatistics(); renderIssues(); renderBottomNav('dashboard'); hideLoading(); } async function loadProjects() { try { var resp = await fetch(API_BASE_URL + '/projects/', { headers: { 'Authorization': 'Bearer ' + TokenManager.getToken() } }); if (resp.ok) { projects = await resp.json(); var sel = document.getElementById('projectFilter'); sel.innerHTML = ''; projects.forEach(function (p) { sel.innerHTML += ''; }); } } catch (e) { console.error('프로젝트 로드 실패:', e); } } async function loadIssues() { try { var resp = await fetch(API_BASE_URL + '/issues/admin/all', { headers: { 'Authorization': 'Bearer ' + TokenManager.getToken() } }); if (resp.ok) { var data = await resp.json(); allIssues = data.filter(function (i) { return i.review_status === 'in_progress'; }); // 프로젝트별 순번 재할당 allIssues.sort(function (a, b) { return new Date(a.reviewed_at) - new Date(b.reviewed_at); }); var groups = {}; allIssues.forEach(function (issue) { if (!groups[issue.project_id]) groups[issue.project_id] = []; groups[issue.project_id].push(issue); }); Object.keys(groups).forEach(function (pid) { groups[pid].forEach(function (issue, idx) { issue.project_sequence_no = idx + 1; }); }); filteredIssues = allIssues.slice(); } } catch (e) { console.error('이슈 로드 실패:', e); } } function updateStatistics() { var today = new Date().toDateString(); var todayIssues = allIssues.filter(function (i) { return i.reviewed_at && new Date(i.reviewed_at).toDateString() === today; }); var pending = allIssues.filter(function (i) { return i.completion_requested_at && i.review_status === 'in_progress'; }); var overdue = allIssues.filter(function (i) { return i.expected_completion_date && new Date(i.expected_completion_date) < new Date(); }); document.getElementById('totalInProgress').textContent = allIssues.length; document.getElementById('todayNew').textContent = todayIssues.length; document.getElementById('pendingCompletion').textContent = pending.length; document.getElementById('overdue').textContent = overdue.length; } function filterByProject() { var pid = document.getElementById('projectFilter').value; filteredIssues = pid ? allIssues.filter(function (i) { return i.project_id == pid; }) : allIssues.slice(); renderIssues(); } // ===== 이슈 상태 판별 ===== function getIssueStatus(issue) { if (issue.review_status === 'completed') return 'completed'; if (issue.completion_requested_at) return 'pending_completion'; if (issue.expected_completion_date) { var diff = (new Date(issue.expected_completion_date) - new Date()) / 86400000; if (diff < 0) return 'overdue'; if (diff <= 3) return 'urgent'; } return 'in_progress'; } function getStatusBadgeHtml(status) { var map = { 'in_progress': ' 진행 중', 'urgent': ' 긴급', 'overdue': ' 지연됨', 'pending_completion': ' 완료 대기', 'completed': ' 완료됨' }; return map[status] || map['in_progress']; } // ===== 렌더링 ===== function renderIssues() { var container = document.getElementById('issuesList'); var empty = document.getElementById('emptyState'); if (!filteredIssues.length) { container.innerHTML = ''; empty.classList.remove('hidden'); return; } empty.classList.add('hidden'); // 날짜별 그룹화 (reviewed_at 기준) var grouped = {}; var dateObjs = {}; filteredIssues.forEach(function (issue) { var d = new Date(issue.reviewed_at || issue.report_date); var key = d.toLocaleDateString('ko-KR'); if (!grouped[key]) { grouped[key] = []; dateObjs[key] = d; } grouped[key].push(issue); }); var html = Object.keys(grouped) .sort(function (a, b) { return dateObjs[b] - dateObjs[a]; }) .map(function (dateKey) { var issues = grouped[dateKey]; return '