const ACTION_LABELS = { 'settings.update': 'Изменены настройки', 'group.create': 'Создана группа', 'group.update': 'Изменена группа', 'group.delete': 'Удалена группа', 'group.photo.create': 'Загружена фото группы', 'group.photo.update': 'Изменено фото группы', 'group.photo.delete': 'Удалено фото группы', 'student.create': 'Добавлен ученик', 'student.update': 'Изменён ученик', 'student.delete': 'Удалён ученик', 'student.batch-group': 'Ученики перенесены в группу', 'entry.update': 'Изменена запись', 'entry.soft-delete': 'Запись в корзину', 'entry.restore': 'Запись восстановлена', 'entry.permanent-delete': 'Запись удалена безвозвратно', 'link.create': 'Создана ссылка', 'link.update': 'Изменена ссылка', 'link.delete': 'Удалена ссылка', 'backup.download': 'Скачан бэкап', 'backup.restore': 'Выполнено восстановление', }; function fmtTime(t) { try { return new Date(t).toLocaleString('ru'); } catch { return t || ''; } } function dt(t) { if (!t) return ''; if (typeof t === 'object') { return esc(JSON.stringify(t).slice(0, 120)); } try { const o = JSON.parse(t); return esc(JSON.stringify(o).slice(0, 120)); } catch { return esc(String(t).slice(0, 120)); } } async function loadAudit() { const el = document.getElementById('auditTable').querySelector('tbody'); el.innerHTML = 'Загрузка…'; const res = await fetch(`${API}/api/audit?limit=500`, { headers: hdr() }); if (!res.ok) { el.innerHTML = 'Ошибка загрузки'; return; } const rows = await res.json(); document.getElementById('auditCount').textContent = rows.length ? `Записей: ${rows.length}` : ''; const q = (document.getElementById('auditFilter').value || '').toLowerCase().trim(); const filtered = q ? rows.filter(r => (ACTION_LABELS[r.action] || r.action).toLowerCase().includes(q)) : rows; if (!filtered.length) { document.getElementById('auditEmpty').style.display = 'block'; el.innerHTML = ''; return; } document.getElementById('auditEmpty').style.display = 'none'; el.innerHTML = filtered.map(r => ` ${fmtTime(r.created_at)} ${esc(ACTION_LABELS[r.action] || r.action)} ${dt(r.target)} ${esc(r.ip || '')} `).join(''); } document.getElementById('auditFilter').addEventListener('input', loadAudit); document.getElementById('auditRefreshBtn').addEventListener('click', loadAudit); (async () => { if (await checkAuth()) { buildSidebar(document.body.dataset.page); loadAudit(); } })();