feat(tkds): 대시보드 UI 개선 — 역할 기반 바로가기 + 시스템 입구 통합

4개 섹션(자주사용/일상업무/시스템/업무도구)을 2개(내 바로가기/시스템)로 재구성.
권한 기반 ALL_SHORTCUTS 17개 + SYSTEM_CARDS 7개 통합, 카테고리 그룹핑 지원.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-03-13 18:29:40 +09:00
parent f4999df334
commit 2a8ae8572f

View File

@@ -193,6 +193,18 @@
.system-card .card-icon { font-size: 26px; }
.system-card .card-name { font-size: 14px; font-weight: 600; }
/* Shortcut category labels */
.shortcut-cat-label {
grid-column: 1 / -1;
font-size: 12px;
font-weight: 600;
color: #6b7280;
padding: 8px 0 2px;
border-bottom: 1px solid #e5e7eb;
margin-bottom: 4px;
}
.shortcut-cat-label:first-child { padding-top: 0; }
/* Coming soon */
.badge-soon {
display: inline-block;
@@ -253,22 +265,14 @@
</div>
</div>
<div class="container">
<div class="section" id="frequentSection" style="display:none">
<div class="section-title"><span>&#11088;</span> 자주 사용</div>
<div class="card-grid" id="frequentGrid"></div>
</div>
<div class="section" id="dailySection" style="display:none">
<div class="section-title"><span>&#128204;</span> 일상 업무</div>
<div class="card-grid" id="dailyGrid"></div>
<div class="section" id="shortcutSection" style="display:none">
<div class="section-title"><span>&#128204;</span> 내 바로가기</div>
<div class="card-grid" id="shortcutGrid"></div>
</div>
<div class="section" id="systemSection" style="display:none">
<div class="section-title"><span>&#127970;</span> 시스템</div>
<div class="system-grid" id="systemGrid"></div>
</div>
<div class="section" id="toolSection" style="display:none">
<div class="section-title"><span>&#128295;</span> 업무 도구</div>
<div class="card-grid" id="toolGrid"></div>
</div>
</div>
<div class="footer">TK Factory Services v1.0</div>
</div>
@@ -331,46 +335,45 @@
}
// ===== Card Definitions =====
var DAILY_CARDS = [
{ id: 'tbm', name: 'TBM', icon: '\uD83D\uDCCB', subdomain: 'tkfb', path: '/pages/work/tbm.html', pageKey: 's1.work.tbm' },
{ id: 'report', name: '\uC791\uC5C5\uBCF4\uACE0\uC11C', icon: '\uD83D\uDCDD', subdomain: 'tkfb', path: '/pages/work/report-create.html', pageKey: 's1.work.report_create' },
{ id: 'issue', name: '\uC548\uC804\uC2E0\uACE0', icon: '\u26A0\uFE0F', subdomain: 'tkreport', path: '/pages/safety/issue-report.html', accessKey: 'system2' },
{ id: 'checkin', name: '\uCD9C\uD1F4\uADFC \uCCB4\uD06C', icon: '\u23F0', subdomain: 'tkfb', path: '/pages/attendance/checkin.html', pageKey: 's1.inspection.checkin' },
{ id: 'vacation', name: '\uB0B4 \uC5F0\uCC28 \uC815\uBCF4', icon: '\uD83C\uDFD6\uFE0F', subdomain: 'tkfb', path: '/pages/attendance/my-vacation-info.html', pageKey: 's1.attendance.my_vacation_info' },
{ id: 'leave', name: '\uD734\uAC00 \uC2E0\uCCAD', icon: '\uD83D\uDCC5', subdomain: 'tkfb', path: '/pages/attendance/vacation-request.html', pageKey: 's1.attendance.vacation_request' }
var ALL_SHORTCUTS = [
// 작업 관리
{ id: 'tbm', name: 'TBM', icon: '\uD83D\uDCCB', cat: '작업 관리', subdomain: 'tkfb', path: '/pages/work/tbm.html', pageKey: 's1.work.tbm' },
{ id: 'report', name: '작업보고서', icon: '\uD83D\uDCDD', cat: '작업 관리', subdomain: 'tkfb', path: '/pages/work/report-create.html', pageKey: 's1.work.report_create' },
{ id: 'analysis', name: '작업 분석', icon: '\uD83D\uDCCA', cat: '작업 관리', subdomain: 'tkfb', path: '/pages/work/analysis.html', pageKey: 's1.work.analysis' },
{ id: 'nonconformity', name: '부적합 현황', icon: '\u26A0\uFE0F', cat: '작업 관리', subdomain: 'tkfb', path: '/pages/work/nonconformity.html', pageKey: 's1.work.nonconformity' },
// 공장 관리
{ id: 'repair', name: '시설설비 관리', icon: '\uD83D\uDD27', cat: '공장 관리', subdomain: 'tkfb', path: '/pages/admin/repair-management.html', pageKey: 's1.factory.repair_management' },
{ id: 'patrol', name: '일일순회점검', icon: '\uD83D\uDD0D', cat: '공장 관리', subdomain: 'tkfb', path: '/pages/inspection/daily-patrol.html', pageKey: 's1.inspection.daily_patrol' },
{ id: 'checkin', name: '출퇴근 체크', icon: '\u23F0', cat: '공장 관리', subdomain: 'tkfb', path: '/pages/attendance/checkin.html', pageKey: 's1.inspection.checkin' },
{ id: 'workstatus', name: '근무 현황', icon: '\uD83D\uDCBC', cat: '공장 관리', subdomain: 'tkfb', path: '/pages/attendance/work-status.html', pageKey: 's1.inspection.work_status' },
// 근태 관리
{ id: 'vacation', name: '내 연차 정보', icon: '\uD83C\uDFD6\uFE0F', cat: '근태 관리', subdomain: 'tkfb', path: '/pages/attendance/my-vacation-info.html', pageKey: 's1.attendance.my_vacation_info' },
{ id: 'monthly', name: '월간 근태', icon: '\uD83D\uDCC6', cat: '근태 관리', subdomain: 'tkfb', path: '/pages/attendance/monthly.html', pageKey: 's1.attendance.monthly' },
{ id: 'leave', name: '휴가 신청', icon: '\uD83D\uDCC5', cat: '근태 관리', subdomain: 'tkfb', path: '/pages/attendance/vacation-request.html', pageKey: 's1.attendance.vacation_request' },
{ id: 'vacmgmt', name: '휴가 관리', icon: '\u2699\uFE0F', cat: '근태 관리', subdomain: 'tkfb', path: '/pages/attendance/vacation-management.html', pageKey: 's1.attendance.vacation_management' },
// 신고·안전
{ id: 'issue', name: '안전신고', icon: '\uD83D\uDEA8', cat: '신고·안전', subdomain: 'tkreport', path: '/pages/safety/issue-report.html', accessKey: 'system2' },
{ id: 'visit', name: '방문 관리', icon: '\uD83D\uDEAA', cat: '신고·안전', subdomain: 'tksafety', pageKey: 'safety_visit_management' },
{ id: 'education', name: '안전교육', icon: '\uD83C\uDF93', cat: '신고·안전', subdomain: 'tksafety', path: '/education.html', pageKey: 'safety_visit_management' },
// 구매·행정
{ id: 'daylabor', name: '일용공 신청', icon: '\uD83D\uDC77', cat: '구매·행정', subdomain: 'tkpurchase', path: '/daylabor.html', pageKey: 'purchasing_schedule' },
{ id: 'schedule', name: '작업일정', icon: '\uD83D\uDCC5', cat: '구매·행정', subdomain: 'tkpurchase', path: '/schedule.html', pageKey: 'purchasing_schedule' }
];
var SYSTEM_CARDS = [
{ id: 'factory', name: '\uACF5\uC7A5\uAD00\uB9AC', icon: '\uD83C\uDFED', subdomain: 'tkfb', path: '/pages/dashboard.html', pageKey: 's1.dashboard', color: '#1a56db' },
{ id: 'report_sys', name: '\uC2E0\uACE0', icon: '\uD83D\uDEA8', subdomain: 'tkreport', accessKey: 'system2', color: '#dc2626' },
{ id: 'quality', name: '\uBD80\uC801\uD569\uAD00\uB9AC', icon: '\uD83D\uDCCA', subdomain: 'tkqc', pageKey: 'issues_dashboard', color: '#059669' }
{ id: 'factory', name: '공장관리', icon: '\uD83C\uDFED', subdomain: 'tkfb', path: '/pages/dashboard.html', pageKey: 's1.dashboard', color: '#1a56db' },
{ id: 'report_sys', name: '신고', icon: '\uD83D\uDEA8', subdomain: 'tkreport', accessKey: 'system2', color: '#dc2626' },
{ id: 'quality', name: '부적합관리', icon: '\uD83D\uDCCA', subdomain: 'tkqc', pageKey: 'issues_dashboard', color: '#059669' },
{ id: 'purchase', name: '구매관리', icon: '\uD83D\uDED2', subdomain: 'tkpurchase', pageKey: 'purchasing_schedule', color: '#d97706' },
{ id: 'safety', name: '안전관리', icon: '\uD83D\uDD27', subdomain: 'tksafety', pageKey: 'safety_visit_management', color: '#7c3aed' },
{ id: 'support', name: '행정지원', icon: '\uD83C\uDFE2', subdomain: 'tksupport', comingSoon: true, color: '#6b7280' },
{ id: 'admin', name: '통합관리', icon: '\u2699\uFE0F', subdomain: 'tkuser', pageKey: 'tkuser.users', color: '#0891b2' }
];
var TOOL_CARDS = [
{ id: 'purchase', name: '\uAD6C\uB9E4\uAD00\uB9AC', icon: '\uD83D\uDED2', subdomain: 'tkpurchase', pageKey: 'purchasing_schedule' },
{ id: 'safety', name: '\uC548\uC804\uAD00\uB9AC', icon: '\uD83D\uDD27', subdomain: 'tksafety', pageKey: 'safety_visit_management' },
{ id: 'support', name: '\uD589\uC815\uC9C0\uC6D0', icon: '\uD83C\uDFE2', comingSoon: true },
{ id: 'admin', name: '\uD1B5\uD569\uAD00\uB9AC', icon: '\u2699\uFE0F', subdomain: 'tkuser', pageKey: 'tkuser.users' }
];
// ===== Click Tracking =====
function trackClick(linkId) {
var clicks = JSON.parse(localStorage.getItem('hub_clicks') || '{}');
clicks[linkId] = (clicks[linkId] || 0) + 1;
localStorage.setItem('hub_clicks', JSON.stringify(clicks));
}
function getFrequentIds(limit) {
var clicks = JSON.parse(localStorage.getItem('hub_clicks') || '{}');
if (Object.keys(clicks).length === 0) {
return ['tbm', 'report', 'checkin', 'vacation'];
}
return Object.entries(clicks)
.sort(function(a, b) { return b[1] - a[1]; })
.slice(0, limit)
.map(function(e) { return e[0]; });
}
// ===== Rendering =====
function resolveHref(card) {
if (card.href) return card.href;
@@ -395,7 +398,6 @@
a.onclick = function(e) { e.preventDefault(); };
} else {
a.href = resolveHref(card);
a.onclick = function() { trackClick(card.id); };
}
var iconSpan = document.createElement('span');
@@ -432,9 +434,31 @@
var grid = document.getElementById(gridId);
grid.innerHTML = '';
visible.forEach(function(card) {
grid.appendChild(createCardElement(card, isSystem));
});
if (!isSystem && visible.length >= 10) {
// 카테고리별 그룹핑
var categories = [];
var catMap = {};
visible.forEach(function(c) {
var cat = c.cat || '기타';
if (!catMap[cat]) { catMap[cat] = []; categories.push(cat); }
catMap[cat].push(c);
});
categories.forEach(function(cat) {
var label = document.createElement('div');
label.className = 'shortcut-cat-label';
label.textContent = cat;
grid.appendChild(label);
catMap[cat].forEach(function(card) {
grid.appendChild(createCardElement(card, false));
});
});
} else {
visible.forEach(function(card) {
grid.appendChild(createCardElement(card, isSystem));
});
}
document.getElementById(sectionId).style.display = '';
}
@@ -470,29 +494,9 @@
if (systemAccess.system3 !== false) allowed.add('issues_dashboard');
}
// Render main sections
renderSection('dailySection', 'dailyGrid', DAILY_CARDS, allowed, systemAccess, false);
// Render sections
renderSection('shortcutSection', 'shortcutGrid', ALL_SHORTCUTS, allowed, systemAccess, false);
renderSection('systemSection', 'systemGrid', SYSTEM_CARDS, allowed, systemAccess, true);
renderSection('toolSection', 'toolGrid', TOOL_CARDS, allowed, systemAccess, false);
// Frequent section
var allCards = DAILY_CARDS.concat(TOOL_CARDS);
var cardMap = {};
allCards.forEach(function(c) { cardMap[c.id] = c; });
var frequentIds = getFrequentIds(4);
var frequentCards = frequentIds
.map(function(id) { return cardMap[id]; })
.filter(function(c) { return c && !c.comingSoon && isCardVisible(c, allowed, systemAccess); });
if (frequentCards.length > 0) {
var grid = document.getElementById('frequentGrid');
grid.innerHTML = '';
frequentCards.forEach(function(card) {
grid.appendChild(createCardElement(card, false));
});
document.getElementById('frequentSection').style.display = '';
}
}
// ===== Login =====