/** * 생산팀 대시보드 — Sprint 003 */ const PAGE_ICONS = { 'dashboard': 'fa-home', 'work.tbm': 'fa-clipboard-list', 'work.report_create': 'fa-file-alt', 'work.analysis': 'fa-chart-bar', 'work.nonconformity': 'fa-exclamation-triangle', 'work.schedule': 'fa-calendar-alt', 'work.meetings': 'fa-users', 'work.daily_status': 'fa-chart-bar', 'work.proxy_input': 'fa-user-edit', 'factory.repair_management': 'fa-tools', 'inspection.daily_patrol': 'fa-route', 'inspection.checkin': 'fa-user-check', 'inspection.work_status': 'fa-briefcase', 'purchase.request': 'fa-shopping-cart', 'purchase.analysis': 'fa-chart-line', 'attendance.my_vacation_info': 'fa-info-circle', 'attendance.monthly': 'fa-calendar', 'attendance.vacation_request': 'fa-paper-plane', 'attendance.vacation_management': 'fa-cog', 'attendance.vacation_allocation': 'fa-plus-circle', 'attendance.annual_overview': 'fa-chart-pie', 'admin.user_management': 'fa-users-cog', 'admin.projects': 'fa-project-diagram', 'admin.tasks': 'fa-tasks', 'admin.workplaces': 'fa-building', 'admin.equipments': 'fa-cogs', 'admin.departments': 'fa-sitemap', 'admin.notifications': 'fa-bell', 'admin.attendance_report': 'fa-clipboard-check', }; const CATEGORY_COLORS = { '작업 관리': '#3b82f6', '공장 관리': '#f59e0b', '소모품 관리': '#10b981', '근태 관리': '#8b5cf6', '시스템 관리': '#6b7280', }; const DEFAULT_COLOR = '#06b6d4'; function escHtml(s) { const d = document.createElement('div'); d.textContent = s; return d.innerHTML; } async function initDashboard() { showSkeleton(); try { const result = await api('/dashboard/my-summary'); if (!result.success) throw new Error(result.message || '데이터 로드 실패'); renderDashboard(result.data); } catch (err) { showError(err.message); } } function renderDashboard(data) { const { user, vacation, overtime, quick_access } = data; // 프로필 카드 const card = document.getElementById('profileCard'); const initial = (user.worker_name || user.name || '?').charAt(0); const vacRemaining = vacation.remaining_days; const vacTotal = vacation.total_days; const vacUsed = vacation.used_days; const vacPct = vacTotal > 0 ? Math.round((vacUsed / vacTotal) * 100) : 0; const vacColor = vacRemaining >= 5 ? 'green' : vacRemaining >= 3 ? 'yellow' : 'red'; const otHours = overtime.total_overtime_hours; const otDays = overtime.overtime_days; card.innerHTML = `
${escHtml(msg || '정보를 불러올 수 없습니다.')}