diff --git a/tkds/web/dashboard.html b/tkds/web/dashboard.html
index c6c0c44..f95450b 100644
--- a/tkds/web/dashboard.html
+++ b/tkds/web/dashboard.html
@@ -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 @@
@@ -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 =====