/* ============================================================ Website Checker — app.js Global utilities: modals, tabs, auto-dismiss alerts, helpers ============================================================ */ 'use strict'; /* ── Modal helpers ─────────────────────────────────────────── */ function openModal(id) { const el = document.getElementById(id); if (el) { el.classList.add('open'); document.body.style.overflow = 'hidden'; const firstInput = el.querySelector('input:not([type=hidden]), select, textarea'); if (firstInput) setTimeout(() => firstInput.focus(), 120); } } function closeModal(id) { const el = document.getElementById(id); if (el) { el.classList.remove('open'); document.body.style.overflow = ''; } } // Close modal when clicking the backdrop document.addEventListener('click', (e) => { if (e.target.classList.contains('modal-overlay')) { e.target.classList.remove('open'); document.body.style.overflow = ''; } }); // Close modal on Escape key document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { document.querySelectorAll('.modal-overlay.open').forEach(m => { m.classList.remove('open'); document.body.style.overflow = ''; }); } }); /* ── Tab switching ─────────────────────────────────────────── */ function switchTab(tabId, groupId) { const group = groupId ? document.getElementById(groupId) : document.body; group.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); group.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active')); const btn = group.querySelector(`[data-tab="${tabId}"]`); const panel = document.getElementById(tabId); if (btn) btn.classList.add('active'); if (panel) panel.classList.add('active'); } // Wire up tab buttons declared in HTML document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('.tab-btn[data-tab]').forEach(btn => { btn.addEventListener('click', () => { const tabId = btn.dataset.tab; const groupId = btn.dataset.group || null; switchTab(tabId, groupId); }); }); }); /* ── Auto-dismiss flash messages ───────────────────────────── */ document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('.alert').forEach(alert => { setTimeout(() => { alert.style.transition = 'opacity 0.5s'; alert.style.opacity = '0'; setTimeout(() => alert.remove(), 500); }, 5000); }); }); /* ── Confirm-delete helper ─────────────────────────────────── */ function confirmDelete(message, formOrUrl) { if (!confirm(message || 'Are you sure you want to delete this item?')) return false; if (typeof formOrUrl === 'string') { window.location.href = formOrUrl; } else if (formOrUrl && formOrUrl.submit) { formOrUrl.submit(); } return true; } /* ── Password visibility toggle ────────────────────────────── */ function togglePasswordVisibility(inputId, btn) { const input = document.getElementById(inputId); if (!input) return; if (input.type === 'password') { input.type = 'text'; if (btn) btn.textContent = '🙈'; } else { input.type = 'password'; if (btn) btn.textContent = '👁'; } } /* ── Dynamic credential rows (website form) ────────────────── */ function addCredentialRow(containerId) { const container = document.getElementById(containerId); if (!container) return; const index = container.querySelectorAll('.credential-entry').length; const row = document.createElement('div'); row.className = 'credential-entry'; row.innerHTML = `