diff --git a/public/js/settings.js b/public/js/settings.js index 27b5e2c..32f67e5 100644 --- a/public/js/settings.js +++ b/public/js/settings.js @@ -246,18 +246,33 @@ async function loadBans() { const bans = await res.json(); if (!bans.length) { el.innerHTML = 'Активных блокировок нет'; return; } el.innerHTML = bans.map(b => ` - + ${esc(b.ip)} — ${esc(b.reason)} до ${new Date(b.banned_until).toLocaleString('ru')} `).join(''); } -document.getElementById('bansList').addEventListener('click', async e => { +async function doUnban(ip) { + const res = await fetch(`${API}/api/bans/${encodeURIComponent(ip)}`, { method: 'DELETE', headers: hdr() }); + if (res.ok) { showToast('IP разблокирован: ' + ip); loadBans(); } + else showToast('Ошибка разблокировки'); +} + +document.getElementById('bansList').addEventListener('click', e => { const ip = e.target.closest('[data-unban]')?.dataset.unban; if (!ip) return; - const res = await fetch(`${API}/api/bans/${encodeURIComponent(ip)}`, { method: 'DELETE', headers: hdr() }); - if (res.ok) { showToast('IP разблокирован'); loadBans(); } - else showToast('Ошибка разблокировки'); + const chip = e.target.closest('[data-chip]'); + if (chip.dataset.confirming) return; + chip.dataset.confirming = '1'; + chip.style.background = 'rgba(239,68,68,.08)'; + e.target.outerHTML = ` + + Убрать из блокировки? + + + `; + chip.querySelector('[data-unban-yes]').addEventListener('click', () => doUnban(ip)); + chip.querySelector('[data-unban-no]').addEventListener('click', () => loadBans()); }); document.getElementById('backupBtn').addEventListener('click', downloadBackup);