// mobile-dashboard.js - 모바일 대시보드 v2
// 공장별 카테고리 탭 → 작업장 리스트 → 작업장별 상태 요약
(function() {
'use strict';
if (window.innerWidth > 768) return;
var today = new Date().toISOString().slice(0, 10);
// ==================== 캐시 변수 ====================
var categories = [];
var allWorkplaces = [];
var tbmByWorkplace = {};
var visitorsByWorkplace = {};
var movedByWorkplace = {};
var issuesByWorkplace = {};
var workplacesByCategory = {};
// ==================== 유틸리티 ====================
// escapeHtml, waitForApi → api-base.js 전역 사용
// ==================== 데이터 그룹핑 ====================
function groupTbmByWorkplace(sessions) {
tbmByWorkplace = {};
if (!Array.isArray(sessions)) return;
sessions.forEach(function(s) {
var wpId = s.workplace_id;
if (!wpId) return;
if (!tbmByWorkplace[wpId]) {
tbmByWorkplace[wpId] = { taskCount: 0, totalWorkers: 0, sessions: [] };
}
tbmByWorkplace[wpId].taskCount++;
tbmByWorkplace[wpId].totalWorkers += (parseInt(s.team_member_count) || 0);
tbmByWorkplace[wpId].sessions.push(s);
});
}
function groupVisitorsByWorkplace(requests) {
visitorsByWorkplace = {};
if (!Array.isArray(requests)) return;
requests.forEach(function(r) {
// 오늘 날짜 + 승인된 건만
if (r.visit_date !== today) return;
if (r.status !== 'approved') return;
var wpId = r.workplace_id;
if (!wpId) return;
if (!visitorsByWorkplace[wpId]) {
visitorsByWorkplace[wpId] = { visitCount: 0, totalVisitors: 0, requests: [] };
}
visitorsByWorkplace[wpId].visitCount++;
visitorsByWorkplace[wpId].totalVisitors += parseInt(r.visitor_count) || 0;
visitorsByWorkplace[wpId].requests.push(r);
});
}
function groupMovedByWorkplace(items) {
movedByWorkplace = {};
if (!Array.isArray(items)) return;
items.forEach(function(eq) {
var wpId = eq.current_workplace_id;
if (!wpId) return;
if (!movedByWorkplace[wpId]) {
movedByWorkplace[wpId] = { movedCount: 0, items: [] };
}
movedByWorkplace[wpId].movedCount++;
movedByWorkplace[wpId].items.push(eq);
});
}
function groupIssuesByWorkplace(issues) {
issuesByWorkplace = {};
if (!Array.isArray(issues)) return;
var activeStatuses = ['reported', 'received', 'in_progress'];
issues.forEach(function(issue) {
var wpId = issue.workplace_id;
if (!wpId) return;
if (activeStatuses.indexOf(issue.status) === -1) return;
if (!issuesByWorkplace[wpId]) {
issuesByWorkplace[wpId] = { activeCount: 0, items: [] };
}
issuesByWorkplace[wpId].activeCount++;
issuesByWorkplace[wpId].items.push(issue);
});
}
function groupWorkplacesByCategory(workplaces) {
workplacesByCategory = {};
if (!Array.isArray(workplaces)) return;
workplaces.forEach(function(wp) {
var catId = wp.category_id;
if (!catId) return;
if (!workplacesByCategory[catId]) {
workplacesByCategory[catId] = [];
}
workplacesByCategory[catId].push(wp);
});
}
// ==================== 렌더링 ====================
function renderCategoryTabs() {
var container = document.getElementById('mCategoryTabs');
if (!container || !categories.length) return;
var html = '';
categories.forEach(function(cat, idx) {
html += '';
});
// 전체 탭
html += '';
container.innerHTML = html;
// 이벤트 바인딩
var tabs = container.querySelectorAll('.md-cat-tab');
tabs.forEach(function(tab) {
tab.addEventListener('click', function() {
tabs.forEach(function(t) { t.classList.remove('active'); });
tab.classList.add('active');
var catId = tab.getAttribute('data-id');
selectCategory(catId);
});
});
// 첫 번째 카테고리 자동 선택
if (categories.length > 0) {
selectCategory(String(categories[0].category_id));
}
}
function selectCategory(categoryId) {
var workplaces;
if (categoryId === 'all') {
workplaces = allWorkplaces.filter(function(wp) { return wp.is_active !== false; });
} else {
workplaces = (workplacesByCategory[categoryId] || []).filter(function(wp) {
return wp.is_active !== false;
});
}
renderWorkplaceList(workplaces);
}
function renderWorkplaceList(workplaces) {
var container = document.getElementById('mWorkplaceList');
if (!container) return;
if (!workplaces || workplaces.length === 0) {
container.innerHTML = '
등록된 작업장이 없습니다.
';
return;
}
var html = '';
workplaces.forEach(function(wp) {
var wpId = wp.workplace_id;
var tbm = tbmByWorkplace[wpId];
var visitors = visitorsByWorkplace[wpId];
var moved = movedByWorkplace[wpId];
var issues = issuesByWorkplace[wpId];
var hasAny = tbm || visitors || moved || issues;
html += '
';
// 헤더 (클릭 영역)
html += '
';
html += '
' + escapeHtml(wp.workplace_name);
if (hasAny) {
html += '▼';
}
html += '
';
}
// 신고 (미완료만)
if (issues && issues.activeCount > 0) {
html += '
' +
'⚠' +
'신고 ' + issues.activeCount + '건' +
'
';
}
// 이동설비
if (moved && moved.movedCount > 0) {
html += '
' +
'↔' +
'이동설비 ' + moved.movedCount + '건' +
'
';
}
html += '
';
}
html += '
'; // .md-wp-header
// 상세 영역 (활동 있는 카드만)
if (hasAny) {
html += '
' + renderCardDetail(wpId) + '
';
}
html += '
'; // .md-wp-card
});
container.innerHTML = html;
// 클릭 이벤트 바인딩
var cards = container.querySelectorAll('.md-wp-card[data-wp-id]');
cards.forEach(function(card) {
var wpId = card.getAttribute('data-wp-id');
var hasActivity = tbmByWorkplace[wpId] || visitorsByWorkplace[wpId] ||
movedByWorkplace[wpId] || issuesByWorkplace[wpId];
if (!hasActivity) return;
card.querySelector('.md-wp-header').addEventListener('click', function() {
toggleCard(wpId);
});
});
}
// ==================== 카드 확장/접기 ====================
function toggleCard(wpId) {
var allCards = document.querySelectorAll('.md-wp-card.expanded');
var targetCard = document.querySelector('.md-wp-card[data-wp-id="' + wpId + '"]');
if (!targetCard) return;
var isExpanded = targetCard.classList.contains('expanded');
// 다른 카드 모두 접기 (아코디언)
allCards.forEach(function(card) {
card.classList.remove('expanded');
});
// 토글
if (!isExpanded) {
targetCard.classList.add('expanded');
}
}
function renderCardDetail(wpId) {
var html = '';
var tbm = tbmByWorkplace[wpId];
var visitors = visitorsByWorkplace[wpId];
var issues = issuesByWorkplace[wpId];
var moved = movedByWorkplace[wpId];
// TBM 작업
if (tbm && tbm.sessions.length > 0) {
html += '
';
html += '
▶ 작업
';
tbm.sessions.forEach(function(s) {
var taskName = s.task_name || '작업명 미지정';
var leaderName = s.leader_name || '미지정';
var memberCount = (parseInt(s.team_member_count) || 0);
html += '
';
}
// 방문
if (visitors && visitors.requests.length > 0) {
html += '
';
html += '
▶ 방문
';
visitors.requests.forEach(function(r) {
var company = r.visitor_company || '업체 미지정';
var count = parseInt(r.visitor_count) || 0;
var purpose = r.purpose_name || '';
html += '
';
html += '
' + escapeHtml(company) + ' · ' + count + '명';
if (purpose) html += ' · ' + escapeHtml(purpose);
html += '
';
html += '
';
});
html += '
';
}
// 신고
if (issues && issues.items.length > 0) {
var statusMap = { reported: '신고', received: '접수', in_progress: '처리중' };
html += '
';
html += '
▶ 신고
';
issues.items.forEach(function(issue) {
var category = issue.issue_category_name || '미분류';
var desc = issue.additional_description || '';
if (desc.length > 30) desc = desc.substring(0, 30) + '...';
var statusText = statusMap[issue.status] || issue.status;
var statusClass = 'md-wp-issue-status--' + (issue.status || 'reported');
var reporter = issue.reporter_name || '';
var icon = issue.status === 'in_progress' ? '🔴' : '⚠';
html += '
';
html += '
' + icon + ' ' + escapeHtml(category);
if (desc) html += ' · ' + escapeHtml(desc);
html += '
';
html += '
' + statusText + '';
if (reporter) html += ' → ' + escapeHtml(reporter);
html += '
';
html += '
';
});
html += '
';
}
// 이동설비
if (moved && moved.items.length > 0) {
html += '
';
html += '
▶ 이동설비
';
moved.items.forEach(function(eq) {
var eqName = eq.equipment_name || '설비명 미지정';
var fromWp = eq.original_workplace_name || '?';
var toWp = eq.current_workplace_name || '?';
html += '