/** * 신고 카테고리 관리 JavaScript */ import { API, getAuthHeaders } from '/js/api-config.js'; let currentType = 'nonconformity'; let categories = []; let items = []; // 초기화 document.addEventListener('DOMContentLoaded', async () => { await loadCategories(); }); /** * 유형 탭 전환 */ window.switchType = async function(type) { currentType = type; // 탭 상태 업데이트 document.querySelectorAll('.type-tab').forEach(tab => { tab.classList.toggle('active', tab.dataset.type === type); }); await loadCategories(); }; /** * 카테고리 로드 */ async function loadCategories() { const container = document.getElementById('categoryList'); container.innerHTML = '
카테고리를 불러오는 중...
'; try { const response = await fetch(`${API}/work-issues/categories/type/${currentType}`, { headers: getAuthHeaders() }); if (!response.ok) throw new Error('카테고리 조회 실패'); const data = await response.json(); if (data.success && data.data) { categories = data.data; // 항목도 로드 const itemsResponse = await fetch(`${API}/work-issues/items`, { headers: getAuthHeaders() }); if (itemsResponse.ok) { const itemsData = await itemsResponse.json(); if (itemsData.success) { items = itemsData.data || []; } } renderCategories(); } else { container.innerHTML = '
카테고리가 없습니다.
'; } } catch (error) { console.error('카테고리 로드 실패:', error); container.innerHTML = '
카테고리를 불러오지 못했습니다.
'; } } /** * 카테고리 렌더링 */ function renderCategories() { const container = document.getElementById('categoryList'); if (categories.length === 0) { container.innerHTML = '
등록된 카테고리가 없습니다.
'; return; } const severityLabel = { low: '낮음', medium: '보통', high: '높음', critical: '심각' }; container.innerHTML = categories.map(cat => { const catItems = items.filter(item => item.category_id === cat.category_id); return `
${cat.category_name}
${severityLabel[cat.severity] || '보통'} ${catItems.length}개 항목
${catItems.length > 0 ? catItems.map(item => `
${item.item_name}
${item.description ? `
${item.description}
` : ''}
${severityLabel[item.severity] || '보통'}
`).join('') : '
등록된 항목이 없습니다.
'}
`; }).join(''); } /** * 카테고리 토글 */ window.toggleCategory = function(categoryId) { const section = document.querySelector(`.category-section[data-category-id="${categoryId}"]`); if (section) { section.classList.toggle('expanded'); } }; /** * 카테고리 모달 열기 */ window.openCategoryModal = function(categoryId = null) { const modal = document.getElementById('categoryModal'); const title = document.getElementById('categoryModalTitle'); const deleteBtn = document.getElementById('deleteCategoryBtn'); document.getElementById('categoryId').value = ''; document.getElementById('categoryName').value = ''; document.getElementById('categoryDescription').value = ''; document.getElementById('categorySeverity').value = 'medium'; if (categoryId) { const category = categories.find(c => c.category_id === categoryId); if (category) { title.textContent = '카테고리 수정'; document.getElementById('categoryId').value = category.category_id; document.getElementById('categoryName').value = category.category_name; document.getElementById('categoryDescription').value = category.description || ''; document.getElementById('categorySeverity').value = category.severity || 'medium'; deleteBtn.style.display = 'block'; } } else { title.textContent = '새 카테고리'; deleteBtn.style.display = 'none'; } modal.style.display = 'flex'; }; /** * 카테고리 모달 닫기 */ window.closeCategoryModal = function() { document.getElementById('categoryModal').style.display = 'none'; }; /** * 카테고리 저장 */ window.saveCategory = async function() { const categoryId = document.getElementById('categoryId').value; const name = document.getElementById('categoryName').value.trim(); const description = document.getElementById('categoryDescription').value.trim(); const severity = document.getElementById('categorySeverity').value; if (!name) { alert('카테고리 이름을 입력하세요.'); return; } try { const url = categoryId ? `${API}/work-issues/categories/${categoryId}` : `${API}/work-issues/categories`; const response = await fetch(url, { method: categoryId ? 'PUT' : 'POST', headers: { ...getAuthHeaders(), 'Content-Type': 'application/json' }, body: JSON.stringify({ category_name: name, category_type: currentType, description, severity }) }); const data = await response.json(); if (response.ok && data.success) { alert(categoryId ? '카테고리가 수정되었습니다.' : '카테고리가 추가되었습니다.'); closeCategoryModal(); await loadCategories(); } else { throw new Error(data.error || '저장 실패'); } } catch (error) { console.error('카테고리 저장 실패:', error); alert('카테고리 저장에 실패했습니다: ' + error.message); } }; /** * 카테고리 삭제 */ window.deleteCategory = async function() { const categoryId = document.getElementById('categoryId').value; if (!categoryId) return; const catItems = items.filter(item => item.category_id == categoryId); if (catItems.length > 0) { alert(`이 카테고리에 ${catItems.length}개의 항목이 있습니다. 먼저 항목을 삭제하세요.`); return; } if (!confirm('이 카테고리를 삭제하시겠습니까?')) return; try { const response = await fetch(`${API}/work-issues/categories/${categoryId}`, { method: 'DELETE', headers: getAuthHeaders() }); const data = await response.json(); if (response.ok && data.success) { alert('카테고리가 삭제되었습니다.'); closeCategoryModal(); await loadCategories(); } else { throw new Error(data.error || '삭제 실패'); } } catch (error) { console.error('카테고리 삭제 실패:', error); alert('카테고리 삭제에 실패했습니다: ' + error.message); } }; /** * 항목 모달 열기 */ window.openItemModal = function(categoryId, itemId = null) { const modal = document.getElementById('itemModal'); const title = document.getElementById('itemModalTitle'); const deleteBtn = document.getElementById('deleteItemBtn'); document.getElementById('itemId').value = ''; document.getElementById('itemCategoryId').value = categoryId; document.getElementById('itemName').value = ''; document.getElementById('itemDescription').value = ''; document.getElementById('itemSeverity').value = 'medium'; if (itemId) { const item = items.find(i => i.item_id === itemId); if (item) { title.textContent = '항목 수정'; document.getElementById('itemId').value = item.item_id; document.getElementById('itemName').value = item.item_name; document.getElementById('itemDescription').value = item.description || ''; document.getElementById('itemSeverity').value = item.severity || 'medium'; deleteBtn.style.display = 'block'; } } else { const category = categories.find(c => c.category_id === categoryId); title.textContent = `새 항목 (${category?.category_name || ''})`; deleteBtn.style.display = 'none'; } modal.style.display = 'flex'; }; /** * 항목 모달 닫기 */ window.closeItemModal = function() { document.getElementById('itemModal').style.display = 'none'; }; /** * 항목 저장 */ window.saveItem = async function() { const itemId = document.getElementById('itemId').value; const categoryId = document.getElementById('itemCategoryId').value; const name = document.getElementById('itemName').value.trim(); const description = document.getElementById('itemDescription').value.trim(); const severity = document.getElementById('itemSeverity').value; if (!name) { alert('항목 이름을 입력하세요.'); return; } try { const url = itemId ? `${API}/work-issues/items/${itemId}` : `${API}/work-issues/items`; const response = await fetch(url, { method: itemId ? 'PUT' : 'POST', headers: { ...getAuthHeaders(), 'Content-Type': 'application/json' }, body: JSON.stringify({ category_id: categoryId, item_name: name, description, severity }) }); const data = await response.json(); if (response.ok && data.success) { alert(itemId ? '항목이 수정되었습니다.' : '항목이 추가되었습니다.'); closeItemModal(); await loadCategories(); } else { throw new Error(data.error || '저장 실패'); } } catch (error) { console.error('항목 저장 실패:', error); alert('항목 저장에 실패했습니다: ' + error.message); } }; /** * 항목 삭제 */ window.deleteItem = async function() { const itemId = document.getElementById('itemId').value; if (!itemId) return; if (!confirm('이 항목을 삭제하시겠습니까?')) return; try { const response = await fetch(`${API}/work-issues/items/${itemId}`, { method: 'DELETE', headers: getAuthHeaders() }); const data = await response.json(); if (response.ok && data.success) { alert('항목이 삭제되었습니다.'); closeItemModal(); await loadCategories(); } else { throw new Error(data.error || '삭제 실패'); } } catch (error) { console.error('항목 삭제 실패:', error); alert('항목 삭제에 실패했습니다: ' + error.message); } }; /** * 빠른 항목 추가 */ window.quickAddItem = async function(categoryId) { const input = document.getElementById(`newItemName_${categoryId}`); const name = input.value.trim(); if (!name) { alert('항목 이름을 입력하세요.'); input.focus(); return; } try { const response = await fetch(`${API}/work-issues/items`, { method: 'POST', headers: { ...getAuthHeaders(), 'Content-Type': 'application/json' }, body: JSON.stringify({ category_id: categoryId, item_name: name, severity: 'medium' }) }); const data = await response.json(); if (response.ok && data.success) { input.value = ''; await loadCategories(); // 카테고리 펼침 유지 toggleCategory(categoryId); } else { throw new Error(data.error || '추가 실패'); } } catch (error) { console.error('항목 추가 실패:', error); alert('항목 추가에 실패했습니다: ' + error.message); } };