feat: 안전 코드 tksafety 이관 + 사용자 관리 정리 + UI Tailwind 전환

Phase 1: tksafety에 출입신청/체크리스트 API·웹 추가, tkfb 안전 코드 삭제
Phase 2: 사용자 관리 페이지 삭제, API 축소, 알림 수신자 tkuser 이관
Phase 3: tkuser 권한 페이지 정의 업데이트
Phase 4: 전체 34개 페이지 Tailwind CSS + tkfb-core.js 전환,
         미사용 CSS 20개·인프라 JS 10개·템플릿·컴포넌트 삭제

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-03-13 10:46:22 +09:00
parent 8373fe9e75
commit 9fda89a374
133 changed files with 5255 additions and 26181 deletions

View File

@@ -12,7 +12,6 @@
var categories = [];
var allWorkplaces = [];
var tbmByWorkplace = {};
var visitorsByWorkplace = {};
var movedByWorkplace = {};
var issuesByWorkplace = {};
var workplacesByCategory = {};
@@ -37,24 +36,6 @@
});
}
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;
@@ -158,11 +139,10 @@
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;
var hasAny = tbm || moved || issues;
html += '<div class="md-wp-card" data-wp-id="' + wpId + '">';
@@ -187,14 +167,6 @@
'</div>';
}
// 방문
if (visitors) {
html += '<div class="md-wp-stat-row">' +
'<span class="md-wp-stat-icon">&#128682;</span>' +
'<span class="md-wp-stat-text">방문 ' + visitors.visitCount + '건 &middot; ' + visitors.totalVisitors + '명</span>' +
'</div>';
}
// 신고 (미완료만)
if (issues && issues.activeCount > 0) {
html += '<div class="md-wp-stat-row md-wp-stat--warning">' +
@@ -230,7 +202,7 @@
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] ||
var hasActivity = tbmByWorkplace[wpId] ||
movedByWorkplace[wpId] || issuesByWorkplace[wpId];
if (!hasActivity) return;
card.querySelector('.md-wp-header').addEventListener('click', function() {
@@ -262,7 +234,6 @@
function renderCardDetail(wpId) {
var html = '';
var tbm = tbmByWorkplace[wpId];
var visitors = visitorsByWorkplace[wpId];
var issues = issuesByWorkplace[wpId];
var moved = movedByWorkplace[wpId];
@@ -282,23 +253,6 @@
html += '</div>';
}
// 방문
if (visitors && visitors.requests.length > 0) {
html += '<div class="md-wp-detail-section">';
html += '<div class="md-wp-detail-title">&#9654; 방문</div>';
visitors.requests.forEach(function(r) {
var company = r.visitor_company || '업체 미지정';
var count = parseInt(r.visitor_count) || 0;
var purpose = r.purpose_name || '';
html += '<div class="md-wp-detail-item">';
html += '<div class="md-wp-detail-main">' + escapeHtml(company) + ' &middot; ' + count + '명';
if (purpose) html += ' &middot; ' + escapeHtml(purpose);
html += '</div>';
html += '</div>';
});
html += '</div>';
}
// 신고
if (issues && issues.items.length > 0) {
var statusMap = { reported: '신고', received: '접수', in_progress: '처리중' };
@@ -380,7 +334,6 @@
var results = await Promise.allSettled([
window.apiCall('/workplaces/categories'),
window.apiCall('/tbm/sessions/date/' + today),
window.apiCall('/workplace-visits/requests?visit_date=' + today + '&status=approved'),
window.apiCall('/equipments/moved/list'),
window.apiCall('/work-issues?start_date=' + today + '&end_date=' + today),
window.apiCall('/workplaces')
@@ -396,24 +349,19 @@
groupTbmByWorkplace(results[1].value.data || []);
}
// 방문
if (results[2].status === 'fulfilled' && results[2].value && results[2].value.success) {
groupVisitorsByWorkplace(results[2].value.data || []);
}
// 이동설비
if (results[3].status === 'fulfilled' && results[3].value && results[3].value.success) {
groupMovedByWorkplace(results[3].value.data || []);
if (results[2].status === 'fulfilled' && results[2].value && results[2].value.success) {
groupMovedByWorkplace(results[2].value.data || []);
}
// 신고
if (results[4].status === 'fulfilled' && results[4].value && results[4].value.success) {
groupIssuesByWorkplace(results[4].value.data || []);
if (results[3].status === 'fulfilled' && results[3].value && results[3].value.success) {
groupIssuesByWorkplace(results[3].value.data || []);
}
// 작업장 전체 (카테고리별 그룹핑)
if (results[5].status === 'fulfilled' && results[5].value && results[5].value.success) {
allWorkplaces = results[5].value.data || [];
if (results[4].status === 'fulfilled' && results[4].value && results[4].value.success) {
allWorkplaces = results[4].value.data || [];
groupWorkplacesByCategory(allWorkplaces);
}