// 공통 JavaScript 기능들 // API 호출 헬퍼 async function apiCall(url, options = {}) { const defaultOptions = { headers: { 'Content-Type': 'application/json', }, }; const response = await fetch(url, { ...defaultOptions, ...options }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); } // 파일 크기 포맷팅 function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } // 날짜 포맷팅 function formatDate(dateString) { const date = new Date(dateString); return date.toLocaleString('ko-KR'); } // 토스트 알림 function showToast(message, type = 'info') { const toast = document.createElement('div'); toast.className = `alert alert-${type} toast`; toast.textContent = message; toast.style.cssText = ` position: fixed; top: 20px; right: 20px; z-index: 1000; min-width: 300px; animation: slideIn 0.3s ease; `; document.body.appendChild(toast); setTimeout(() => { toast.style.animation = 'slideOut 0.3s ease'; setTimeout(() => { document.body.removeChild(toast); }, 300); }, 3000); } // 로딩 상태 관리 function setLoading(element, loading = true) { if (loading) { element.disabled = true; element.innerHTML = ' 처리 중...'; } else { element.disabled = false; element.innerHTML = element.getAttribute('data-original-text') || '완료'; } } // 애니메이션 CSS 추가 const style = document.createElement('style'); style.textContent = ` @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes slideOut { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } } .toast { animation: slideIn 0.3s ease; } `; document.head.appendChild(style);