document.addEventListener('DOMContentLoaded', () => { const urlForm = document.getElementById('url-form'); const urlInput = document.getElementById('url-input'); const textInput = document.getElementById('text-input'); const htmlInput = document.getElementById('html-input'); const imageUpload = document.getElementById('image-upload'); const imagePreview = document.getElementById('image-preview'); const previewImg = document.getElementById('preview-img'); const removeImageBtn = document.getElementById('remove-image'); const analyzeBtn = document.getElementById('analyze-btn'); const loadingSpinner = document.getElementById('loading'); const resultCard = document.getElementById('result-card'); const omniPlusBtn = document.getElementById('omni-plus-btn'); const omniMenu = document.getElementById('omni-menu'); const omniMenuItems = document.querySelectorAll('.omni-menu-item'); const sidebar = document.querySelector('.sidebar'); const sidebarToggle = document.getElementById('sidebar-toggle'); const navAnalyzer = document.getElementById('nav-analyzer'); let currentMode = 'url'; let selectedFile = null; // --- Sidebar & Navigation --- const overlay = document.createElement('div'); overlay.className = 'sidebar-overlay'; document.body.appendChild(overlay); // All sidebar toggle buttons (analyzer page + stats page) document.querySelectorAll('.sidebar-toggle-btn').forEach(btn => { btn.addEventListener('click', () => { const isActive = sidebar.classList.toggle('active'); overlay.style.display = isActive ? 'block' : 'none'; }); }); overlay.addEventListener('click', () => { sidebar.classList.remove('active'); overlay.style.display = 'none'; }); // Close button inside sidebar const sidebarClose = document.getElementById('sidebar-close'); if (sidebarClose) { sidebarClose.addEventListener('click', () => { sidebar.classList.remove('active'); overlay.style.display = 'none'; }); } if (navAnalyzer) { navAnalyzer.addEventListener('click', (e) => { e.preventDefault(); showPage('analyzer'); if (window.innerWidth <= 1024) sidebar.classList.remove('active'); overlay.style.display = 'none'; }); } // --- Page Navigation --- const analyzerPage = document.querySelector('.main-content:not(#stats-page)'); const statsPage = document.getElementById('stats-page'); const navStats = document.getElementById('nav-stats'); const statsBackBtn = document.getElementById('stats-back-btn'); function showPage(page) { if (page === 'stats') { analyzerPage.classList.add('d-none'); statsPage.classList.remove('d-none'); navAnalyzer.classList.remove('active'); navStats.classList.add('active'); fetchStats(); } else { statsPage.classList.add('d-none'); analyzerPage.classList.remove('d-none'); navStats.classList.remove('active'); navAnalyzer.classList.add('active'); } window.scrollTo({ top: 0, behavior: 'smooth' }); } if (navStats) { navStats.addEventListener('click', (e) => { e.preventDefault(); showPage('stats'); if (window.innerWidth <= 1024) sidebar.classList.remove('active'); overlay.style.display = 'none'; }); } if (statsBackBtn) { statsBackBtn.addEventListener('click', () => showPage('analyzer')); } // --- Omni-Menu Logic --- omniPlusBtn.addEventListener('click', (e) => { e.stopPropagation(); omniMenu.classList.toggle('active'); }); document.addEventListener('click', () => { omniMenu.classList.remove('active'); }); omniMenuItems.forEach(item => { item.addEventListener('click', () => { const mode = item.dataset.mode; if (mode) switchMode(mode); omniMenu.classList.remove('active'); }); }); function switchMode(mode) { currentMode = mode; // Hide all urlInput.classList.add('d-none'); textInput.classList.add('d-none'); htmlInput.classList.add('d-none'); // Remove 'required' from all urlInput.removeAttribute('required'); textInput.removeAttribute('required'); htmlInput.removeAttribute('required'); // Show selected if (mode === 'url') { urlInput.classList.remove('d-none'); urlInput.setAttribute('required', ''); urlInput.focus(); } else if (mode === 'text') { textInput.classList.remove('d-none'); textInput.setAttribute('required', ''); textInput.focus(); } else if (mode === 'html') { htmlInput.classList.remove('d-none'); htmlInput.setAttribute('required', ''); htmlInput.focus(); } } // --- File/Image Handling --- imageUpload.addEventListener('change', (e) => { const file = e.target.files[0]; if (file && file.type.startsWith('image/')) { selectedFile = file; const reader = new FileReader(); reader.onload = (e) => { previewImg.src = e.target.result; imagePreview.classList.remove('d-none'); }; reader.readAsDataURL(file); } }); removeImageBtn.addEventListener('click', () => { selectedFile = null; imageUpload.value = ''; imagePreview.classList.add('d-none'); }); // --- Analysis Submission --- urlForm.addEventListener('submit', async (e) => { e.preventDefault(); const url = urlInput.value.trim(); const text = textInput.value.trim(); const html = htmlInput.value.trim(); if (currentMode === 'url' && !url && !selectedFile) return; if (currentMode === 'text' && !text) return; if (currentMode === 'html' && !html) return; // Reset UI resultCard.style.display = 'none'; loadingSpinner.style.display = 'block'; analyzeBtn.disabled = true; try { const formData = new FormData(); if (currentMode === 'url' && url) formData.append('url', url); if (currentMode === 'text' && text) formData.append('text', text); if (currentMode === 'html' && html) formData.append('html', html); if (selectedFile) formData.append('image', selectedFile); const response = await fetch('/predict', { method: 'POST', body: formData // Fetch automatically sets content-type for FormData }); const data = await response.json(); if (data.error) { showError(data.error); } else { showResult(data); fetchHistory(); } } catch (error) { showError('Erro ao conectar com o serviço de análise multi-modal.'); console.error(error); } finally { loadingSpinner.style.display = 'none'; analyzeBtn.disabled = false; } }); function showResult(data) { const isPhishing = data.result === 'Phishing'; const isSuspect = data.result === 'Suspeito'; const colorClass = isPhishing ? 'is-phishing' : (isSuspect ? 'text-warning' : 'is-safe'); const borderColor = isPhishing ? 'var(--danger)' : (isSuspect ? 'orange' : 'var(--success)'); const icon = isPhishing ? 'fa-shield-virus' : (isSuspect ? 'fa-exclamation-triangle' : 'fa-shield-check'); const statusText = isPhishing ? 'Potencial Phishing' : (isSuspect ? 'Análise Suspeita' : 'URL Legítima'); let agentsHtml = ''; if (data.agent_details) { agentsHtml = `
${data.url}
Nenhuma busca recente encontrada.
Nenhuma análise registrada ainda.
'; } } // --- Toggle History Detail --- window.toggleHistoryDetail = function (index) { const detail = document.getElementById(`detail-${index}`); const chevron = document.getElementById(`chevron-${index}`); if (!detail) return; const isOpen = detail.style.display !== 'none'; detail.style.display = isOpen ? 'none' : 'block'; if (chevron) { chevron.style.transform = isOpen ? 'rotate(0deg)' : 'rotate(180deg)'; } }; // Initialize fetchHistory(); });