From e69426882a5d84292526420f6c406c3ca3ec89f9 Mon Sep 17 00:00:00 2001 From: dev Date: Sat, 12 Sep 2026 01:01:59 +0300 Subject: [PATCH] Bans: unban requires inline confirmation row with yes/cancel --- public/js/bans.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/public/js/bans.js b/public/js/bans.js index 64e68c4..b7b6d86 100644 --- a/public/js/bans.js +++ b/public/js/bans.js @@ -49,6 +49,36 @@ function renderPage() { renderPager(document.getElementById('pager'), page, Math.max(1, Math.ceil(allBans.length / PAGE_SIZE)), p => { page = p; renderPage(); }); } +function askUnban(ip) { + const old = document.getElementById('unbanConfirmRow'); + if (old) old.remove(); + const tr = document.createElement('tr'); + tr.id = 'unbanConfirmRow'; + tr.innerHTML = ` + + Разблокировать ${esc(ip)}? + + + `; + tr.querySelector('#unbanYes').addEventListener('click', () => doUnban(ip)); + tr.querySelector('#unbanNo').addEventListener('click', () => tr.remove()); + document.getElementById('bansBody').appendChild(tr); + tr.scrollIntoView({ block: 'nearest', behavior: 'smooth' }); +} + +async function doUnban(ip) { + const res = await fetch(`${API}/api/bans/${encodeURIComponent(ip)}`, { method: 'DELETE', headers: hdr() }); + if (res.ok) showToast('IP разблокирован: ' + ip); + else showToast('Ошибка разблокировки'); + document.getElementById('unbanConfirmRow')?.remove(); + loadBans(); +} + +document.getElementById('bansBody').addEventListener('click', e => { + const ip = e.target.closest('[data-unban]')?.dataset.unban; + if (ip) askUnban(ip); +}); + document.getElementById('bansBody').addEventListener('click', async e => { const ip = e.target.closest('[data-unban]')?.dataset.unban; if (!ip) return;