/* ===== 알림 수신자 관리 ===== */ let nrLoaded = false; let nrData = {}; // { type: { label, recipients: [...] } } let nrTypes = {}; // { type: label } let nrCategories = {}; // { category: { label, icon, types: [...] } } let nrAllUsers = []; // 사용자 목록 (수신자 추가용) async function loadNotificationRecipientsTab() { if (nrLoaded) return; try { const [typesRes, allRes, usersRes] = await Promise.all([ api('/notification-recipients/types'), api('/notification-recipients'), api('/users?status=active') ]); nrTypes = typesRes.data?.types || typesRes.data || {}; nrCategories = typesRes.data?.categories || {}; nrData = allRes.data || {}; nrAllUsers = (usersRes.data || usersRes || []).filter(u => u.status !== 'inactive'); nrLoaded = true; renderNrTab(); } catch (e) { document.getElementById('nrContent').innerHTML = `
데이터 로드 실패: ${escapeHtml(e.message)}
`; } } function renderNrTab() { const container = document.getElementById('nrContent'); if (!Object.keys(nrTypes).length) { container.innerHTML = '등록된 알림 유형이 없습니다.
'; return; } let html = ''; const categoryKeys = Object.keys(nrCategories); if (categoryKeys.length > 0) { // 카테고리별 그룹 렌더링 for (const [catKey, cat] of Object.entries(nrCategories)) { html += `추가 가능한 사용자가 없습니다.
'; } else { listEl.innerHTML = available.map(u => ` `).join(''); } document.getElementById('nrAddModal').classList.remove('hidden'); } function closeNrAddModal() { document.getElementById('nrAddModal').classList.add('hidden'); } async function submitNrAdd() { const checked = [...document.querySelectorAll('.nrAddCheck:checked')].map(c => Number(c.value)); if (checked.length === 0) { showToast('사용자를 선택해주세요.', 'error'); return; } try { for (const userId of checked) { await api('/notification-recipients', { method: 'POST', body: JSON.stringify({ notification_type: nrAddType, user_id: userId }) }); } showToast(`${checked.length}명 수신자 추가 완료`); closeNrAddModal(); nrLoaded = false; await loadNotificationRecipientsTab(); } catch (e) { showToast('수신자 추가 실패: ' + e.message, 'error'); } } async function removeNrRecipient(type, userId) { if (!confirm('이 수신자를 제거하시겠습니까?')) return; try { await api(`/notification-recipients/${type}/${userId}`, { method: 'DELETE' }); showToast('수신자 제거 완료'); nrLoaded = false; await loadNotificationRecipientsTab(); } catch (e) { showToast('수신자 제거 실패: ' + e.message, 'error'); } }