diff --git a/system1-factory/web/js/admin-settings.js b/system1-factory/web/js/admin-settings.js index a2cdcbe..d157bcb 100644 --- a/system1-factory/web/js/admin-settings.js +++ b/system1-factory/web/js/admin-settings.js @@ -537,35 +537,7 @@ function handleLogout() { } } -// ========== 토스트 알림 ========== // -function showToast(message, type = 'info', duration = 3000) { - if (!elements.toastContainer) return; - - const toast = document.createElement('div'); - toast.className = `toast ${type}`; - - const iconMap = { - success: '✅', - error: '❌', - warning: '⚠️', - info: 'ℹ️' - }; - - toast.innerHTML = ` -
${iconMap[type] || 'ℹ️'}
-
${message}
- - `; - - elements.toastContainer.appendChild(toast); - - // 자동 제거 - setTimeout(() => { - if (toast.parentElement) { - toast.remove(); - } - }, duration); -} +// showToast → api-base.js 전역 사용 // ========== 전역 함수 (HTML에서 호출) ========== // window.editUser = editUser; diff --git a/system1-factory/web/js/api-base.js b/system1-factory/web/js/api-base.js index 87d62cc..fb4952a 100644 --- a/system1-factory/web/js/api-base.js +++ b/system1-factory/web/js/api-base.js @@ -148,5 +148,88 @@ return response.json(); }; + // ==================== 공통 유틸리티 ==================== + + /** + * Toast 알림 표시 + */ + window.showToast = function(message, type, duration) { + type = type || 'info'; + duration = duration || 3000; + + var container = document.getElementById('toastContainer'); + if (!container) { + container = document.createElement('div'); + container.id = 'toastContainer'; + container.style.cssText = 'position:fixed;top:20px;right:20px;z-index:9999;display:flex;flex-direction:column;gap:10px;'; + document.body.appendChild(container); + } + + if (!document.getElementById('toastStyles')) { + var style = document.createElement('style'); + style.id = 'toastStyles'; + style.textContent = + '.toast{display:flex;align-items:center;gap:12px;padding:12px 20px;background:#fff;border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,.15);opacity:0;transform:translateX(100px);transition:all .3s ease;min-width:250px;max-width:400px}' + + '.toast.show{opacity:1;transform:translateX(0)}' + + '.toast-success{border-left:4px solid #10b981}.toast-error{border-left:4px solid #ef4444}' + + '.toast-warning{border-left:4px solid #f59e0b}.toast-info{border-left:4px solid #3b82f6}' + + '.toast-icon{font-size:20px}.toast-message{font-size:14px;color:#374151}'; + document.head.appendChild(style); + } + + var iconMap = { success: '\u2705', error: '\u274C', warning: '\u26A0\uFE0F', info: '\u2139\uFE0F' }; + var toast = document.createElement('div'); + toast.className = 'toast toast-' + type; + toast.innerHTML = '' + (iconMap[type] || '\u2139\uFE0F') + '' + message + ''; + container.appendChild(toast); + + setTimeout(function() { toast.classList.add('show'); }, 10); + setTimeout(function() { + toast.classList.remove('show'); + setTimeout(function() { toast.remove(); }, 300); + }, duration); + }; + + /** + * 날짜를 YYYY-MM-DD 형식으로 변환 + */ + window.formatDate = function(dateString) { + if (!dateString) return ''; + if (/^\d{4}-\d{2}-\d{2}$/.test(dateString)) return dateString; + var d = new Date(dateString); + if (isNaN(d.getTime())) return ''; + var y = d.getFullYear(); + var m = String(d.getMonth() + 1).padStart(2, '0'); + var day = String(d.getDate()).padStart(2, '0'); + return y + '-' + m + '-' + day; + }; + + /** + * apiCall이 로드될 때까지 대기 + */ + window.waitForApi = function(timeout) { + timeout = timeout || 5000; + return new Promise(function(resolve, reject) { + if (window.apiCall) return resolve(); + var elapsed = 0; + var iv = setInterval(function() { + elapsed += 50; + if (window.apiCall) { clearInterval(iv); resolve(); } + else if (elapsed >= timeout) { clearInterval(iv); reject(new Error('apiCall timeout')); } + }, 50); + }); + }; + + /** + * UUID v4 생성 + */ + window.generateUUID = function() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random() * 16 | 0; + var v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + }; + console.log('API 설정 완료:', window.API_BASE_URL); })(); diff --git a/system1-factory/web/js/daily-work-report/utils.js b/system1-factory/web/js/daily-work-report/utils.js index c6c4db8..2d96e2a 100644 --- a/system1-factory/web/js/daily-work-report/utils.js +++ b/system1-factory/web/js/daily-work-report/utils.js @@ -425,40 +425,7 @@ window.updateProgressSteps = function(currentStepNumber) { } }; -// 토스트 메시지 (간단 버전) -window.showToast = function(message, type = 'info', duration = 3000) { - console.log(`[Toast] ${type}: ${message}`); - - // 기존 토스트 제거 - const existingToast = document.querySelector('.toast-message'); - if (existingToast) { - existingToast.remove(); - } - - // 새 토스트 생성 - const toast = document.createElement('div'); - toast.className = `toast-message toast-${type}`; - toast.textContent = message; - toast.style.cssText = ` - position: fixed; - bottom: 20px; - right: 20px; - padding: 12px 20px; - border-radius: 8px; - color: white; - font-size: 14px; - z-index: 10000; - animation: slideIn 0.3s ease; - background-color: ${type === 'success' ? '#10b981' : type === 'error' ? '#ef4444' : type === 'warning' ? '#f59e0b' : '#3b82f6'}; - `; - - document.body.appendChild(toast); - - setTimeout(() => { - toast.style.animation = 'slideOut 0.3s ease'; - setTimeout(() => toast.remove(), 300); - }, duration); -}; +// showToast → api-base.js 전역 사용 // 확인 다이얼로그 window.showConfirmDialog = function(message, onConfirm, onCancel) { diff --git a/system1-factory/web/js/department-management.js b/system1-factory/web/js/department-management.js index 5207204..e159574 100644 --- a/system1-factory/web/js/department-management.js +++ b/system1-factory/web/js/department-management.js @@ -7,21 +7,11 @@ let selectedWorkers = new Set(); // 페이지 초기화 document.addEventListener('DOMContentLoaded', async () => { - await waitForApiConfig(); + await waitForApi(); await loadDepartments(); }); -// API 설정 로드 대기 -async function waitForApiConfig() { - let retryCount = 0; - while (!window.apiCall && retryCount < 50) { - await new Promise(resolve => setTimeout(resolve, 100)); - retryCount++; - } - if (!window.apiCall) { - console.error('API 설정 로드 실패'); - } -} +// waitForApi → api-base.js 전역 사용 // 부서 목록 로드 async function loadDepartments() { diff --git a/system1-factory/web/js/equipment-detail.js b/system1-factory/web/js/equipment-detail.js index 6080674..3135205 100644 --- a/system1-factory/web/js/equipment-detail.js +++ b/system1-factory/web/js/equipment-detail.js @@ -33,24 +33,14 @@ document.addEventListener('DOMContentLoaded', () => { } // API 설정 후 데이터 로드 - waitForApiConfig().then(() => { + waitForApi().then(() => { loadEquipmentData(); loadFactories(); loadRepairCategories(); }); }); -// API 설정 대기 -function waitForApiConfig() { - return new Promise(resolve => { - const check = setInterval(() => { - if (window.API_BASE_URL) { - clearInterval(check); - resolve(); - } - }, 50); - }); -} +// waitForApi → api-base.js 전역 사용 // 뒤로가기 function goBack() { diff --git a/system1-factory/web/js/group-leader-dashboard.js b/system1-factory/web/js/group-leader-dashboard.js index 0b1c01a..6b708b2 100644 --- a/system1-factory/web/js/group-leader-dashboard.js +++ b/system1-factory/web/js/group-leader-dashboard.js @@ -138,14 +138,7 @@ function renderWorkStatus(workers) { container.innerHTML = html; } -// 🍞 토스트 메시지 (기존 modern-dashboard.js에 있다면 중복 주의, 없으면 사용) -function showToast(message, type = 'info') { - if (window.showToast) { - window.showToast(message, type); - } else { - alert(message); - } -} +// showToast → api-base.js 전역 사용 // 초기화 document.addEventListener('DOMContentLoaded', () => { diff --git a/system1-factory/web/js/manage-user.js b/system1-factory/web/js/manage-user.js index 1633156..f976cfd 100644 --- a/system1-factory/web/js/manage-user.js +++ b/system1-factory/web/js/manage-user.js @@ -300,22 +300,7 @@ async function loadWorkerOptions() { } } -function showToast(message) { - const toast = document.createElement('div'); - toast.textContent = message; - toast.style.position = 'fixed'; - toast.style.bottom = '30px'; - toast.style.left = '50%'; - toast.style.transform = 'translateX(-50%)'; - toast.style.background = '#323232'; - toast.style.color = '#fff'; - toast.style.padding = '10px 20px'; - toast.style.borderRadius = '6px'; - toast.style.fontSize = '14px'; - toast.style.zIndex = 9999; - document.body.appendChild(toast); - setTimeout(() => toast.remove(), 2000); -} +// showToast → api-base.js 전역 사용 // ========== 페이지 접근 권한 관리 ========== diff --git a/system1-factory/web/js/mobile-dashboard.js b/system1-factory/web/js/mobile-dashboard.js index 2283513..c81f749 100644 --- a/system1-factory/web/js/mobile-dashboard.js +++ b/system1-factory/web/js/mobile-dashboard.js @@ -18,21 +18,7 @@ var workplacesByCategory = {}; // ==================== 유틸리티 ==================== - - // escapeHtml은 api-base.js에서 window.escapeHtml로 전역 제공 - - function waitForApi(timeout) { - timeout = timeout || 5000; - return new Promise(function(resolve, reject) { - if (window.apiCall) return resolve(); - var elapsed = 0; - var interval = setInterval(function() { - elapsed += 50; - if (window.apiCall) { clearInterval(interval); resolve(); } - else if (elapsed >= timeout) { clearInterval(interval); reject(new Error('apiCall timeout')); } - }, 50); - }); - } + // escapeHtml, waitForApi → api-base.js 전역 사용 // ==================== 데이터 그룹핑 ==================== diff --git a/system1-factory/web/js/modern-dashboard.js b/system1-factory/web/js/modern-dashboard.js index f25cbb6..d3acd5b 100644 --- a/system1-factory/web/js/modern-dashboard.js +++ b/system1-factory/web/js/modern-dashboard.js @@ -806,35 +806,7 @@ function showErrorState() { } } -// ========== 토스트 알림 ========== // -function showToast(message, type = 'info', duration = 3000) { - if (!elements.toastContainer) return; - - const toast = document.createElement('div'); - toast.className = `toast ${type}`; - - const iconMap = { - success: '✅', - error: '❌', - warning: '⚠️', - info: 'ℹ️' - }; - - toast.innerHTML = ` -
${iconMap[type] || 'ℹ️'}
-
${message}
- - `; - - elements.toastContainer.appendChild(toast); - - // 자동 제거 - setTimeout(() => { - if (toast.parentElement) { - toast.remove(); - } - }, duration); -} +// showToast → api-base.js 전역 사용 // ========== 작업자 관련 액션 함수들 ========== // function openWorkerModal(workerId, workerName) { @@ -1388,7 +1360,6 @@ async function handleModalVacation(vacationType) { // ========== 전역 함수 (HTML에서 호출) ========== // window.loadDashboardData = loadDashboardData; -window.showToast = showToast; window.updateSummaryCards = updateSummaryCards; window.displayWorkers = displayWorkers; window.openWorkerModal = openWorkerModal; diff --git a/system1-factory/web/js/project-management.js b/system1-factory/web/js/project-management.js index 4540d77..42ac7d6 100644 --- a/system1-factory/web/js/project-management.js +++ b/system1-factory/web/js/project-management.js @@ -557,59 +557,7 @@ async function deleteProjectById(projectId) { } } -// 토스트 메시지 표시 -function showToast(message, type = 'info') { - // 기존 토스트 제거 - const existingToast = document.querySelector('.toast'); - if (existingToast) { - existingToast.remove(); - } - - // 새 토스트 생성 - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - toast.textContent = message; - - // 스타일 적용 - Object.assign(toast.style, { - position: 'fixed', - top: '20px', - right: '20px', - padding: '12px 24px', - borderRadius: '8px', - color: 'white', - fontWeight: '500', - zIndex: '1000', - transform: 'translateX(100%)', - transition: 'transform 0.3s ease' - }); - - // 타입별 배경색 - const colors = { - success: '#10b981', - error: '#ef4444', - warning: '#f59e0b', - info: '#3b82f6' - }; - toast.style.backgroundColor = colors[type] || colors.info; - - document.body.appendChild(toast); - - // 애니메이션 - setTimeout(() => { - toast.style.transform = 'translateX(0)'; - }, 100); - - // 자동 제거 - setTimeout(() => { - toast.style.transform = 'translateX(100%)'; - setTimeout(() => { - if (toast.parentNode) { - toast.remove(); - } - }, 300); - }, 3000); -} +// showToast → api-base.js 전역 사용 // 전역 함수로 노출 window.openProjectModal = openProjectModal; diff --git a/system1-factory/web/js/safety-checklist-manage.js b/system1-factory/web/js/safety-checklist-manage.js index d0bdc02..79fb94f 100644 --- a/system1-factory/web/js/safety-checklist-manage.js +++ b/system1-factory/web/js/safety-checklist-manage.js @@ -831,42 +831,7 @@ async function addInlineCheck(tabType) { } } -/** - * 토스트 메시지 표시 - */ -function showToast(message, type = 'info') { - // 기존 토스트 제거 - const existingToast = document.querySelector('.toast-message'); - if (existingToast) { - existingToast.remove(); - } - - const toast = document.createElement('div'); - toast.className = `toast-message toast-${type}`; - toast.textContent = message; - toast.style.cssText = ` - position: fixed; - bottom: 20px; - left: 50%; - transform: translateX(-50%); - padding: 12px 24px; - border-radius: 8px; - font-size: 14px; - font-weight: 500; - z-index: 9999; - animation: fadeInUp 0.3s ease; - ${type === 'success' ? 'background: #10b981; color: white;' : ''} - ${type === 'error' ? 'background: #ef4444; color: white;' : ''} - ${type === 'info' ? 'background: #3b82f6; color: white;' : ''} - `; - - document.body.appendChild(toast); - - setTimeout(() => { - toast.style.animation = 'fadeOut 0.3s ease'; - setTimeout(() => toast.remove(), 300); - }, 3000); -} +// showToast → api-base.js 전역 사용 // 모달 외부 클릭 시 닫기 document.getElementById('checkModal')?.addEventListener('click', function(e) { diff --git a/system1-factory/web/js/safety-management.js b/system1-factory/web/js/safety-management.js index a6fc975..5a30a8e 100644 --- a/system1-factory/web/js/safety-management.js +++ b/system1-factory/web/js/safety-management.js @@ -4,85 +4,7 @@ let currentStatus = 'pending'; let requests = []; let currentRejectRequestId = null; -// ==================== Toast 알림 ==================== - -function showToast(message, type = 'info', duration = 3000) { - const toastContainer = document.getElementById('toastContainer') || createToastContainer(); - - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - - const iconMap = { - success: '✅', - error: '❌', - warning: '⚠️', - info: 'ℹ️' - }; - - toast.innerHTML = ` - ${iconMap[type] || 'ℹ️'} - ${message} - `; - - toastContainer.appendChild(toast); - - setTimeout(() => toast.classList.add('show'), 10); - - setTimeout(() => { - toast.classList.remove('show'); - setTimeout(() => toast.remove(), 300); - }, duration); -} - -function createToastContainer() { - const container = document.createElement('div'); - container.id = 'toastContainer'; - container.style.cssText = ` - position: fixed; - top: 20px; - right: 20px; - z-index: 9999; - display: flex; - flex-direction: column; - gap: 10px; - `; - - document.body.appendChild(container); - - if (!document.getElementById('toastStyles')) { - const style = document.createElement('style'); - style.id = 'toastStyles'; - style.textContent = ` - .toast { - display: flex; - align-items: center; - gap: 12px; - padding: 12px 20px; - background: white; - border-radius: 8px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); - opacity: 0; - transform: translateX(100px); - transition: all 0.3s ease; - min-width: 250px; - max-width: 400px; - } - .toast.show { - opacity: 1; - transform: translateX(0); - } - .toast-success { border-left: 4px solid #10b981; } - .toast-error { border-left: 4px solid #ef4444; } - .toast-warning { border-left: 4px solid #f59e0b; } - .toast-info { border-left: 4px solid #3b82f6; } - .toast-icon { font-size: 20px; } - .toast-message { font-size: 14px; color: #374151; } - `; - document.head.appendChild(style); - } - - return container; -} +// showToast → api-base.js 전역 사용 // ==================== 초기화 ==================== @@ -436,7 +358,6 @@ function startTraining(requestId) { } // 전역 함수로 노출 -window.showToast = showToast; window.switchTab = switchTab; window.viewDetail = viewDetail; window.closeDetailModal = closeDetailModal; diff --git a/system1-factory/web/js/safety-training-conduct.js b/system1-factory/web/js/safety-training-conduct.js index d6e38a6..746c7a7 100644 --- a/system1-factory/web/js/safety-training-conduct.js +++ b/system1-factory/web/js/safety-training-conduct.js @@ -8,85 +8,7 @@ let isDrawing = false; let hasSignature = false; let savedSignatures = []; // 저장된 서명 목록 -// ==================== Toast 알림 ==================== - -function showToast(message, type = 'info', duration = 3000) { - const toastContainer = document.getElementById('toastContainer') || createToastContainer(); - - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - - const iconMap = { - success: '✅', - error: '❌', - warning: '⚠️', - info: 'ℹ️' - }; - - toast.innerHTML = ` - ${iconMap[type] || 'ℹ️'} - ${message} - `; - - toastContainer.appendChild(toast); - - setTimeout(() => toast.classList.add('show'), 10); - - setTimeout(() => { - toast.classList.remove('show'); - setTimeout(() => toast.remove(), 300); - }, duration); -} - -function createToastContainer() { - const container = document.createElement('div'); - container.id = 'toastContainer'; - container.style.cssText = ` - position: fixed; - top: 20px; - right: 20px; - z-index: 9999; - display: flex; - flex-direction: column; - gap: 10px; - `; - - document.body.appendChild(container); - - if (!document.getElementById('toastStyles')) { - const style = document.createElement('style'); - style.id = 'toastStyles'; - style.textContent = ` - .toast { - display: flex; - align-items: center; - gap: 12px; - padding: 12px 20px; - background: white; - border-radius: 8px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); - opacity: 0; - transform: translateX(100px); - transition: all 0.3s ease; - min-width: 250px; - max-width: 400px; - } - .toast.show { - opacity: 1; - transform: translateX(0); - } - .toast-success { border-left: 4px solid #10b981; } - .toast-error { border-left: 4px solid #ef4444; } - .toast-warning { border-left: 4px solid #f59e0b; } - .toast-info { border-left: 4px solid #3b82f6; } - .toast-icon { font-size: 20px; } - .toast-message { font-size: 14px; color: #374151; } - `; - document.head.appendChild(style); - } - - return container; -} +// showToast → api-base.js 전역 사용 // ==================== 초기화 ==================== @@ -544,7 +466,6 @@ function goBack() { } // 전역 함수로 노출 -window.showToast = showToast; window.clearSignature = clearSignature; window.saveSignature = saveSignature; window.deleteSignature = deleteSignature; diff --git a/system1-factory/web/js/task-management.js b/system1-factory/web/js/task-management.js index 917ceb9..82866e1 100644 --- a/system1-factory/web/js/task-management.js +++ b/system1-factory/web/js/task-management.js @@ -358,31 +358,7 @@ function formatDate(dateString) { }); } -// 토스트 알림 -function showToast(message, type = 'info') { - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - toast.textContent = message; - toast.style.cssText = ` - position: fixed; - top: 20px; - right: 20px; - padding: 1rem 1.5rem; - background: ${type === 'success' ? '#10b981' : type === 'error' ? '#ef4444' : '#3b82f6'}; - color: white; - border-radius: 0.5rem; - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); - z-index: 10000; - animation: slideIn 0.3s ease-out; - `; - - document.body.appendChild(toast); - - setTimeout(() => { - toast.style.animation = 'slideOut 0.3s ease-out'; - setTimeout(() => toast.remove(), 300); - }, 3000); -} +// showToast → api-base.js 전역 사용 // ==================== 공정 관리 ==================== diff --git a/system1-factory/web/js/tbm-create.js b/system1-factory/web/js/tbm-create.js index d0fa09b..e71b185 100644 --- a/system1-factory/web/js/tbm-create.js +++ b/system1-factory/web/js/tbm-create.js @@ -32,7 +32,7 @@ document.addEventListener('DOMContentLoaded', async function() { try { // apiCall이 준비될 때까지 대기 - await waitForApiCall(); + await waitForApi(); // 초기 데이터 로드 await window.TbmAPI.loadInitialData(); @@ -68,22 +68,7 @@ } }); - function waitForApiCall() { - return new Promise(function(resolve) { - if (typeof window.apiCall === 'function') { - resolve(); - return; - } - var checks = 0; - var interval = setInterval(function() { - checks++; - if (typeof window.apiCall === 'function' || checks > 50) { - clearInterval(interval); - resolve(); - } - }, 100); - }); - } + // waitForApi → api-base.js 전역 사용 // ==================== 네비게이션 ==================== diff --git a/system1-factory/web/js/tbm.js b/system1-factory/web/js/tbm.js index 6f0429e..c67a70e 100644 --- a/system1-factory/web/js/tbm.js +++ b/system1-factory/web/js/tbm.js @@ -1005,13 +1005,7 @@ window.saveTbmSession = saveTbmSession; // ==================== 작업자 관리 ==================== -// UUID 생성 함수 -function generateUUID() { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - const r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); -} +// generateUUID → api-base.js 전역 사용 // 작업자 카드 리스트 렌더링 function renderWorkerTaskList() { @@ -3081,46 +3075,4 @@ async function saveHandover() { } window.saveHandover = saveHandover; -// 토스트 알림 -function showToast(message, type = 'info', duration = 3000) { - const container = document.getElementById('toastContainer'); - if (!container) return; - - const toast = document.createElement('div'); - toast.className = `toast ${type}`; - - const iconMap = { - success: '✅', - error: '❌', - warning: '⚠️', - info: 'ℹ️' - }; - - toast.innerHTML = ` -
${iconMap[type] || 'ℹ️'}
-
${message}
- - `; - - toast.style.cssText = ` - display: flex; - align-items: center; - gap: 0.75rem; - padding: 1rem 1.25rem; - background: white; - border-radius: 0.5rem; - box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1); - margin-bottom: 0.75rem; - min-width: 300px; - animation: slideIn 0.3s ease-out; - `; - - container.appendChild(toast); - - setTimeout(() => { - if (toast.parentElement) { - toast.style.animation = 'slideOut 0.3s ease-out'; - setTimeout(() => toast.remove(), 300); - } - }, duration); -} +// showToast → api-base.js 전역 사용 diff --git a/system1-factory/web/js/tbm/utils.js b/system1-factory/web/js/tbm/utils.js index 7926a43..c0ff8c4 100644 --- a/system1-factory/web/js/tbm/utils.js +++ b/system1-factory/web/js/tbm/utils.js @@ -173,56 +173,8 @@ class TbmUtils { // 전역 인스턴스 생성 window.TbmUtils = new TbmUtils(); -// 하위 호환성: 기존 함수들 +// 하위 호환성: TBM 전용 유틸 (showToast, formatDate, waitForApi, generateUUID는 api-base.js 전역) window.getTodayKST = () => window.TbmUtils.getTodayKST(); -window.formatDate = (dateString) => window.TbmUtils.formatDate(dateString); - -// 토스트 알림 -window.showToast = function(message, type = 'info', duration = 3000) { - const container = document.getElementById('toastContainer'); - if (!container) { - console.log(`[Toast] ${type}: ${message}`); - return; - } - - const toast = document.createElement('div'); - toast.className = `toast ${type}`; - - const iconMap = { - success: '✅', - error: '❌', - warning: '⚠️', - info: 'ℹ️' - }; - - toast.innerHTML = ` -
${iconMap[type] || 'ℹ️'}
-
${message}
- - `; - - toast.style.cssText = ` - display: flex; - align-items: center; - gap: 0.75rem; - padding: 1rem 1.25rem; - background: white; - border-radius: 0.5rem; - box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1); - margin-bottom: 0.75rem; - min-width: 300px; - animation: slideIn 0.3s ease-out; - `; - - container.appendChild(toast); - - setTimeout(() => { - if (toast.parentElement) { - toast.style.animation = 'slideOut 0.3s ease-out'; - setTimeout(() => toast.remove(), 300); - } - }, duration); -}; // 카테고리별 그룹화 window.groupChecksByCategory = function(checks) { diff --git a/system1-factory/web/js/vacation-allocation.js b/system1-factory/web/js/vacation-allocation.js index c835279..2a156e4 100644 --- a/system1-factory/web/js/vacation-allocation.js +++ b/system1-factory/web/js/vacation-allocation.js @@ -840,25 +840,4 @@ function closeModals() { }); } -/** - * 토스트 메시지 - */ -function showToast(message, type = 'info') { - const container = document.getElementById('toastContainer'); - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - toast.textContent = message; - - container.appendChild(toast); - - setTimeout(() => { - toast.classList.add('show'); - }, 10); - - setTimeout(() => { - toast.classList.remove('show'); - setTimeout(() => { - container.removeChild(toast); - }, 300); - }, 3000); -} +// showToast → api-base.js 전역 사용 diff --git a/system1-factory/web/js/visit-request.js b/system1-factory/web/js/visit-request.js index 7a26e18..752625d 100644 --- a/system1-factory/web/js/visit-request.js +++ b/system1-factory/web/js/visit-request.js @@ -10,94 +10,7 @@ let canvas = null; let ctx = null; let layoutImage = null; -// ==================== Toast 알림 ==================== - -/** - * Toast 메시지 표시 - */ -function showToast(message, type = 'info', duration = 3000) { - const toastContainer = document.getElementById('toastContainer') || createToastContainer(); - - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - - const iconMap = { - success: '✅', - error: '❌', - warning: '⚠️', - info: 'ℹ️' - }; - - toast.innerHTML = ` - ${iconMap[type] || 'ℹ️'} - ${message} - `; - - toastContainer.appendChild(toast); - - // 애니메이션 - setTimeout(() => toast.classList.add('show'), 10); - - // 자동 제거 - setTimeout(() => { - toast.classList.remove('show'); - setTimeout(() => toast.remove(), 300); - }, duration); -} - -/** - * Toast 컨테이너 생성 - */ -function createToastContainer() { - const container = document.createElement('div'); - container.id = 'toastContainer'; - container.style.cssText = ` - position: fixed; - top: 20px; - right: 20px; - z-index: 9999; - display: flex; - flex-direction: column; - gap: 10px; - `; - - document.body.appendChild(container); - - // Toast 스타일 추가 - if (!document.getElementById('toastStyles')) { - const style = document.createElement('style'); - style.id = 'toastStyles'; - style.textContent = ` - .toast { - display: flex; - align-items: center; - gap: 12px; - padding: 12px 20px; - background: white; - border-radius: 8px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); - opacity: 0; - transform: translateX(100px); - transition: all 0.3s ease; - min-width: 250px; - max-width: 400px; - } - .toast.show { - opacity: 1; - transform: translateX(0); - } - .toast-success { border-left: 4px solid #10b981; } - .toast-error { border-left: 4px solid #ef4444; } - .toast-warning { border-left: 4px solid #f59e0b; } - .toast-info { border-left: 4px solid #3b82f6; } - .toast-icon { font-size: 20px; } - .toast-message { font-size: 14px; color: #374151; } - `; - document.head.appendChild(style); - } - - return container; -} +// showToast, createToastContainer → api-base.js 전역 사용 // ==================== 초기화 ==================== @@ -523,7 +436,6 @@ function resetForm() { } // 전역 함수로 노출 -window.showToast = showToast; window.openMapModal = openMapModal; window.closeMapModal = closeMapModal; window.loadWorkplaceMap = loadWorkplaceMap; diff --git a/system1-factory/web/js/work-analysis.js b/system1-factory/web/js/work-analysis.js index 4c53e8b..f5951a1 100644 --- a/system1-factory/web/js/work-analysis.js +++ b/system1-factory/web/js/work-analysis.js @@ -740,59 +740,7 @@ function formatDate(date) { return `${year}-${month}-${day}`; } -// 토스트 메시지 표시 -function showToast(message, type = 'info') { - // 기존 토스트 제거 - const existingToast = document.querySelector('.toast'); - if (existingToast) { - existingToast.remove(); - } - - // 새 토스트 생성 - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - toast.textContent = message; - - // 스타일 적용 - Object.assign(toast.style, { - position: 'fixed', - top: '20px', - right: '20px', - padding: '12px 24px', - borderRadius: '8px', - color: 'white', - fontWeight: '500', - zIndex: '10000', - transform: 'translateX(100%)', - transition: 'transform 0.3s ease' - }); - - // 타입별 배경색 - const colors = { - success: '#10b981', - error: '#ef4444', - warning: '#f59e0b', - info: '#3b82f6' - }; - toast.style.backgroundColor = colors[type] || colors.info; - - document.body.appendChild(toast); - - // 애니메이션 - setTimeout(() => { - toast.style.transform = 'translateX(0)'; - }, 100); - - // 자동 제거 - setTimeout(() => { - toast.style.transform = 'translateX(100%)'; - setTimeout(() => { - if (toast.parentNode) { - toast.remove(); - } - }, 300); - }, 3000); -} +// showToast → api-base.js 전역 사용 // 전역 함수로 노출 window.switchAnalysisMode = switchAnalysisMode; diff --git a/system1-factory/web/js/work-management.js b/system1-factory/web/js/work-management.js index 99fd157..1bc6adf 100644 --- a/system1-factory/web/js/work-management.js +++ b/system1-factory/web/js/work-management.js @@ -172,59 +172,7 @@ function navigateToPage(url) { }, 300); } -// 토스트 메시지 표시 -function showToast(message, type = 'info') { - // 기존 토스트 제거 - const existingToast = document.querySelector('.toast'); - if (existingToast) { - existingToast.remove(); - } - - // 새 토스트 생성 - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - toast.textContent = message; - - // 스타일 적용 - Object.assign(toast.style, { - position: 'fixed', - top: '20px', - right: '20px', - padding: '12px 24px', - borderRadius: '8px', - color: 'white', - fontWeight: '500', - zIndex: '1000', - transform: 'translateX(100%)', - transition: 'transform 0.3s ease' - }); - - // 타입별 배경색 - const colors = { - success: '#10b981', - error: '#ef4444', - warning: '#f59e0b', - info: '#3b82f6' - }; - toast.style.backgroundColor = colors[type] || colors.info; - - document.body.appendChild(toast); - - // 애니메이션 - setTimeout(() => { - toast.style.transform = 'translateX(0)'; - }, 100); - - // 자동 제거 - setTimeout(() => { - toast.style.transform = 'translateX(100%)'; - setTimeout(() => { - if (toast.parentNode) { - toast.remove(); - } - }, 300); - }, 3000); -} +// showToast → api-base.js 전역 사용 // 전역 함수로 노출 window.navigateToPage = navigateToPage; diff --git a/system1-factory/web/js/worker-management.js b/system1-factory/web/js/worker-management.js index 8908fdb..94c03a3 100644 --- a/system1-factory/web/js/worker-management.js +++ b/system1-factory/web/js/worker-management.js @@ -10,21 +10,11 @@ let currentEditingWorker = null; // 페이지 초기화 document.addEventListener('DOMContentLoaded', async () => { console.log('👥 작업자 관리 페이지 초기화 시작'); - await waitForApiConfig(); + await waitForApi(); await loadDepartments(); }); -// API 설정 로드 대기 -async function waitForApiConfig() { - let retryCount = 0; - while (!window.apiCall && retryCount < 50) { - await new Promise(resolve => setTimeout(resolve, 100)); - retryCount++; - } - if (!window.apiCall) { - console.error('API 설정 로드 실패'); - } -} +// waitForApi → api-base.js 전역 사용 // ============================================ // 부서 관련 함수 @@ -573,53 +563,7 @@ function formatDate(dateString) { }); } -// 토스트 메시지 표시 -function showToast(message, type = 'info') { - const existingToast = document.querySelector('.toast'); - if (existingToast) { - existingToast.remove(); - } - - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - toast.textContent = message; - - Object.assign(toast.style, { - position: 'fixed', - top: '20px', - right: '20px', - padding: '12px 24px', - borderRadius: '8px', - color: 'white', - fontWeight: '500', - zIndex: '10000', - transform: 'translateX(100%)', - transition: 'transform 0.3s ease' - }); - - const colors = { - success: '#10b981', - error: '#ef4444', - warning: '#f59e0b', - info: '#3b82f6' - }; - toast.style.backgroundColor = colors[type] || colors.info; - - document.body.appendChild(toast); - - setTimeout(() => { - toast.style.transform = 'translateX(0)'; - }, 100); - - setTimeout(() => { - toast.style.transform = 'translateX(100%)'; - setTimeout(() => { - if (toast.parentNode) { - toast.remove(); - } - }, 300); - }, 3000); -} +// showToast → api-base.js 전역 사용 // ============================================ // 전역 함수 노출 diff --git a/system1-factory/web/js/workplace-management.js b/system1-factory/web/js/workplace-management.js index 223c8a7..b1cb198 100644 --- a/system1-factory/web/js/workplace-management.js +++ b/system1-factory/web/js/workplace-management.js @@ -903,59 +903,7 @@ function formatDate(dateString) { }); } -// 토스트 메시지 표시 -function showToast(message, type = 'info') { - // 기존 토스트 제거 - const existingToast = document.querySelector('.toast'); - if (existingToast) { - existingToast.remove(); - } - - // 새 토스트 생성 - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - toast.textContent = message; - - // 스타일 적용 - Object.assign(toast.style, { - position: 'fixed', - top: '20px', - right: '20px', - padding: '12px 24px', - borderRadius: '8px', - color: 'white', - fontWeight: '500', - zIndex: '1000', - transform: 'translateX(100%)', - transition: 'transform 0.3s ease' - }); - - // 타입별 배경색 - const colors = { - success: '#10b981', - error: '#ef4444', - warning: '#f59e0b', - info: '#3b82f6' - }; - toast.style.backgroundColor = colors[type] || colors.info; - - document.body.appendChild(toast); - - // 애니메이션 - setTimeout(() => { - toast.style.transform = 'translateX(0)'; - }, 100); - - // 자동 제거 - setTimeout(() => { - toast.style.transform = 'translateX(100%)'; - setTimeout(() => { - if (toast.parentNode) { - toast.remove(); - } - }, 300); - }, 3000); -} +// showToast → api-base.js 전역 사용 // 전역 함수 및 변수로 노출 (다른 모듈에서 접근 가능하도록) // 모듈 시스템이 이미 정의했으면 건너뜀 @@ -1604,7 +1552,6 @@ window.saveWorkplace = saveWorkplace; window.deleteWorkplace = deleteWorkplace; window.confirmDeleteWorkplace = confirmDeleteWorkplace; window.refreshWorkplaces = refreshWorkplaces; -window.showToast = showToast; window.loadCategories = loadCategories; window.updateLayoutPreview = updateLayoutPreview; window.openWorkplaceMapModal = openWorkplaceMapModal; diff --git a/system1-factory/web/js/workplace-management/utils.js b/system1-factory/web/js/workplace-management/utils.js index 49fa1be..1dd9c11 100644 --- a/system1-factory/web/js/workplace-management/utils.js +++ b/system1-factory/web/js/workplace-management/utils.js @@ -94,61 +94,6 @@ class WorkplaceUtils { // 전역 인스턴스 생성 window.WorkplaceUtils = new WorkplaceUtils(); -// 하위 호환성: 기존 함수들 -window.formatDate = (dateString) => window.WorkplaceUtils.formatDate(dateString); - -// 토스트 메시지 표시 -window.showToast = function(message, type = 'info') { - // 기존 토스트 제거 - const existingToast = document.querySelector('.toast'); - if (existingToast) { - existingToast.remove(); - } - - // 새 토스트 생성 - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - toast.textContent = message; - - // 스타일 적용 - Object.assign(toast.style, { - position: 'fixed', - top: '20px', - right: '20px', - padding: '12px 24px', - borderRadius: '8px', - color: 'white', - fontWeight: '500', - zIndex: '1000', - transform: 'translateX(100%)', - transition: 'transform 0.3s ease' - }); - - // 타입별 배경색 - const colors = { - success: '#10b981', - error: '#ef4444', - warning: '#f59e0b', - info: '#3b82f6' - }; - toast.style.backgroundColor = colors[type] || colors.info; - - document.body.appendChild(toast); - - // 애니메이션 - setTimeout(() => { - toast.style.transform = 'translateX(0)'; - }, 100); - - // 자동 제거 - setTimeout(() => { - toast.style.transform = 'translateX(100%)'; - setTimeout(() => { - if (toast.parentNode) { - toast.remove(); - } - }, 300); - }, 3000); -}; +// showToast, formatDate → api-base.js 전역 사용 console.log('[Module] workplace-management/utils.js 로드 완료');