From 12ef51a5788e01f248aa41093869907feb6de488 Mon Sep 17 00:00:00 2001
From: SubleXBle <51033045+SubleXBle@users.noreply.github.com>
Date: Sat, 16 Aug 2025 20:36:15 +0200
Subject: [PATCH] Create blocklist-overlay.js
---
Web-UI/assets/js/blocklist-overlay.js | 204 ++++++++++++++++++++++++++
1 file changed, 204 insertions(+)
create mode 100644 Web-UI/assets/js/blocklist-overlay.js
diff --git a/Web-UI/assets/js/blocklist-overlay.js b/Web-UI/assets/js/blocklist-overlay.js
new file mode 100644
index 0000000..d6aac42
--- /dev/null
+++ b/Web-UI/assets/js/blocklist-overlay.js
@@ -0,0 +1,204 @@
+document.addEventListener('DOMContentLoaded', () => {
+ const openBtn = document.getElementById('openBlocklistBtn');
+ const overlay = document.getElementById('blocklistOverlay');
+ const closeBtn = document.getElementById('closeOverlayBtn');
+ const reloadBtn = document.getElementById('reloadBlocklistBtn');
+ const container = document.getElementById('blocklistContainer');
+ const searchInput = document.getElementById('blocklistSearch');
+ const dateInput = document.getElementById('blocklistDateFilter');
+ const resetBtn = document.getElementById('blocklistResetBtn');
+
+ // New: Elements for jail filter overlay
+ const jailFilterBtn = document.getElementById('blocklistJailFilterBtn');
+ const jailFilterOverlay = document.getElementById('blocklistJailFilterOverlay');
+ const jailFilterContainer = document.getElementById('blocklistJailFilterContainer');
+
+ let blocklistData = [];
+ let selectedJails = new Set();
+
+ if (!openBtn || !overlay || !closeBtn) {
+ console.warn("Overlay elements missing.");
+ return;
+ }
+
+ // Open main blocklist overlay
+ openBtn.addEventListener('click', () => {
+ overlay.classList.remove('hidden');
+ loadBlocklist();
+ });
+
+ // Close main overlay
+ closeBtn.addEventListener('click', () => {
+ overlay.classList.add('hidden');
+ });
+
+ reloadBtn?.addEventListener('click', loadBlocklist);
+
+ searchInput?.addEventListener('input', () => {
+ renderBlocklist(blocklistData, searchInput.value.trim(), Array.from(selectedJails));
+ });
+
+ dateInput?.addEventListener('input', () => {
+ renderBlocklist(blocklistData, searchInput.value.trim(), Array.from(selectedJails));
+ });
+
+ resetBtn?.addEventListener('click', () => {
+ if (searchInput) searchInput.value = '';
+ if (dateInput) dateInput.value = '';
+
+ // Reset all jails selected
+ selectedJails = new Set();
+ Array.from(jailFilterContainer.querySelectorAll('input[type="checkbox"]')).forEach(checkbox => {
+ checkbox.checked = true;
+ selectedJails.add(checkbox.value);
+ });
+
+ renderBlocklist(blocklistData, '', Array.from(selectedJails));
+ });
+
+ // Toggle jail filter overlay visibility
+ jailFilterBtn?.addEventListener('click', () => {
+ jailFilterOverlay.classList.toggle('hidden');
+ });
+
+ // Close jail filter if clicking outside
+ document.addEventListener('click', (e) => {
+ if (
+ jailFilterOverlay &&
+ !jailFilterOverlay.classList.contains('hidden') &&
+ !jailFilterOverlay.contains(e.target) &&
+ e.target !== jailFilterBtn
+ ) {
+ jailFilterOverlay.classList.add('hidden');
+ }
+ });
+
+ // Load blocklist data and setup jail filter checkboxes
+ function loadBlocklist() {
+ container.textContent = 'Loading blocklist...';
+ fetch('includes/get-blocklist.php', { cache: 'no-store' })
+ .then(res => {
+ if (!res.ok) throw new Error('Failed to load blocklist');
+ return res.json();
+ })
+ .then(data => {
+ blocklistData = data.entries || [];
+
+ // Extract unique jails, sorted
+ const uniqueJails = [...new Set(blocklistData.map(e => e.jail || 'unknown'))].sort();
+
+ // Setup jail filter checkbox list
+ setupJailFilter(uniqueJails);
+
+ // Select all jails by default
+ selectedJails = new Set(uniqueJails);
+
+ renderBlocklist(blocklistData, searchInput?.value.trim() || '', uniqueJails);
+ })
+ .catch(err => {
+ container.textContent = 'Error loading blocklist: ' + err.message;
+ });
+ }
+
+ // Create jail filter checkboxes dynamically
+ function setupJailFilter(jails) {
+ if (!jailFilterContainer) return;
+
+ jailFilterContainer.innerHTML = ''; // Clear previous
+
+ jails.forEach(jail => {
+ const label = document.createElement('label');
+ label.style.display = 'block';
+ label.style.cursor = 'pointer';
+
+ const checkbox = document.createElement('input');
+ checkbox.type = 'checkbox';
+ checkbox.value = jail;
+ checkbox.checked = true;
+
+ checkbox.addEventListener('change', () => {
+ if (checkbox.checked) {
+ selectedJails.add(jail);
+ } else {
+ selectedJails.delete(jail);
+ }
+ renderBlocklist(blocklistData, searchInput?.value.trim() || '', Array.from(selectedJails));
+ });
+
+ label.appendChild(checkbox);
+ label.appendChild(document.createTextNode(' ' + jail));
+ jailFilterContainer.appendChild(label);
+ });
+ }
+
+ // Render filtered blocklist entries
+ function renderBlocklist(data, filter = '', selectedJailsArr = []) {
+ if (!Array.isArray(data) || data.length === 0) {
+ container.textContent = 'Blocklist is empty.';
+ return;
+ }
+
+ const activeEntries = data.filter(entry => entry.active !== false);
+ const term = filter.toLowerCase();
+ const selectedDate = dateInput?.value;
+
+ const filteredData = activeEntries.filter(entry => {
+ const jailName = entry.jail || 'unknown';
+
+ const ipMatch = entry.ip.toLowerCase().includes(term);
+ const jailMatch = jailName.toLowerCase().includes(term);
+
+ let dateMatch = true;
+ if (selectedDate && entry.timestamp) {
+ const entryDate = new Date(entry.timestamp).toISOString().split('T')[0];
+ dateMatch = entryDate === selectedDate;
+ }
+
+ return (ipMatch || jailMatch) && dateMatch && selectedJailsArr.includes(jailName);
+ });
+
+ if (filteredData.length === 0) {
+ container.textContent = 'No entries match your search.';
+ return;
+ }
+
+ container.innerHTML = '';
+ filteredData.forEach(entry => {
+ const div = document.createElement('div');
+ div.className = 'blocklist-entry';
+
+ const jailLabel = entry.jail || 'unknown';
+ const timeLabel = entry.timestamp
+ ? new Date(entry.timestamp).toLocaleString()
+ : 'unknown time';
+
+ div.innerHTML = `
+ ${entry.ip} (Jail: ${jailLabel}) – Blocked at: ${timeLabel}
+
+ `;
+
+
+ const btn = div.querySelector('button');
+ btn.addEventListener('click', () => unblockIp(entry.ip, jailLabel));
+ container.appendChild(div);
+ });
+ }
+
+ // Unblock IP action
+ function unblockIp(ip, jail) {
+ fetch('includes/actions/action_unban-ip.php', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+ body: new URLSearchParams({ ip, jail })
+ })
+ .then(res => res.json())
+ .then(data => {
+ showNotification(data.message, !data.success);
+ if (data.success) loadBlocklist();
+ })
+ .catch(err => {
+ showNotification('Error unblocking IP: ' + err.message, true);
+ });
+ }
+
+});