// Theme handling document.addEventListener('DOMContentLoaded', () => { const themeToggle = document.getElementById('theme-toggle'); const html = document.documentElement; // Initialize toggle state based on current theme if (themeToggle) { themeToggle.checked = html.classList.contains('dark'); // Handle toggle changes themeToggle.addEventListener('change', function() { const isDark = this.checked; html.classList.toggle('dark', isDark); localStorage.setItem('theme', isDark ? 'dark' : 'light'); }); // Listen for system theme changes const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); mediaQuery.addEventListener('change', (e) => { if (!localStorage.getItem('theme')) { const isDark = e.matches; html.classList.toggle('dark', isDark); themeToggle.checked = isDark; } }); } }); // Handle search form submission document.addEventListener('submit', (e) => { if (e.target.matches('form[action*="search"]')) { const searchInput = e.target.querySelector('input[name="q"]'); if (!searchInput.value.trim()) { e.preventDefault(); } } }); // Mobile menu toggle with transitions document.addEventListener('DOMContentLoaded', () => { const mobileMenuBtn = document.getElementById('mobileMenuBtn'); const mobileMenu = document.getElementById('mobileMenu'); if (mobileMenuBtn && mobileMenu) { let isMenuOpen = false; const toggleMenu = () => { isMenuOpen = !isMenuOpen; mobileMenu.classList.toggle('show', isMenuOpen); mobileMenuBtn.setAttribute('aria-expanded', isMenuOpen.toString()); // Update icon const icon = mobileMenuBtn.querySelector('i'); icon.classList.remove(isMenuOpen ? 'fa-bars' : 'fa-times'); icon.classList.add(isMenuOpen ? 'fa-times' : 'fa-bars'); }; mobileMenuBtn.addEventListener('click', toggleMenu); // Close menu when clicking outside document.addEventListener('click', (e) => { if (isMenuOpen && !mobileMenu.contains(e.target) && !mobileMenuBtn.contains(e.target)) { toggleMenu(); } }); // Close menu when pressing escape document.addEventListener('keydown', (e) => { if (isMenuOpen && e.key === 'Escape') { toggleMenu(); } }); // Handle viewport changes const mediaQuery = window.matchMedia('(min-width: 1024px)'); mediaQuery.addEventListener('change', (e) => { if (e.matches && isMenuOpen) { toggleMenu(); } }); } }); // User dropdown toggle const userMenuBtn = document.getElementById('userMenuBtn'); const userDropdown = document.getElementById('userDropdown'); if (userMenuBtn && userDropdown) { userMenuBtn.addEventListener('click', (e) => { e.stopPropagation(); userDropdown.classList.toggle('active'); }); // Close dropdown when clicking outside document.addEventListener('click', (e) => { if (!userMenuBtn.contains(e.target) && !userDropdown.contains(e.target)) { userDropdown.classList.remove('active'); } }); // Close dropdown when pressing escape document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { userDropdown.classList.remove('active'); } }); } // Handle flash messages document.addEventListener('DOMContentLoaded', () => { const alerts = document.querySelectorAll('.alert'); alerts.forEach(alert => { setTimeout(() => { alert.style.opacity = '0'; setTimeout(() => alert.remove(), 300); }, 5000); }); }); // Initialize tooltips document.addEventListener('DOMContentLoaded', () => { const tooltips = document.querySelectorAll('[data-tooltip]'); tooltips.forEach(tooltip => { tooltip.addEventListener('mouseenter', (e) => { const text = e.target.getAttribute('data-tooltip'); const tooltipEl = document.createElement('div'); tooltipEl.className = 'absolute z-50 px-2 py-1 text-sm text-white bg-gray-900 rounded tooltip'; tooltipEl.textContent = text; document.body.appendChild(tooltipEl); const rect = e.target.getBoundingClientRect(); tooltipEl.style.top = rect.bottom + 5 + 'px'; tooltipEl.style.left = rect.left + (rect.width - tooltipEl.offsetWidth) / 2 + 'px'; }); tooltip.addEventListener('mouseleave', () => { const tooltips = document.querySelectorAll('.tooltip'); tooltips.forEach(t => t.remove()); }); }); });