/** * Main JavaScript * @package MartinsEVieira */ (function() { 'use strict'; const body = document.body; // ============= UTILITÁRIOS ============= /** * Debounce function para otimizar performance */ function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } /** * Cache de elementos do DOM */ const elements = { cookieBanner: document.getElementById('cookie-banner'), cookieAccept: document.getElementById('cookie-accept'), cookieDecline: document.getElementById('cookie-decline'), themeToggle: document.getElementById('theme-toggle'), mobileMenuToggle: document.getElementById('mobile-menu-toggle'), mainNav: document.getElementById('main-nav'), header: document.querySelector('.site-header'), loadMoreBtn: document.getElementById('load-more-posts'), postsContainer: document.getElementById('posts-container'), loadingSpinner: document.getElementById('loading-spinner') }; // ============= BANNER DE COOKIES (LGPD) ============= function initCookieBanner() { if (!elements.cookieBanner) return; const cookieConsent = localStorage.getItem('cookieConsent'); if (!cookieConsent) { setTimeout(() => { elements.cookieBanner.classList.add('show'); }, 1000); } function handleCookieConsent(accepted) { localStorage.setItem('cookieConsent', accepted ? 'accepted' : 'declined'); localStorage.setItem('cookieConsentDate', new Date().toISOString()); elements.cookieBanner.classList.remove('show'); } if (elements.cookieAccept) { elements.cookieAccept.addEventListener('click', () => handleCookieConsent(true)); } if (elements.cookieDecline) { elements.cookieDecline.addEventListener('click', () => handleCookieConsent(false)); } } // ============= MODO ESCURO ============= function initDarkMode() { if (!elements.themeToggle) return; const icon = elements.themeToggle.querySelector('i'); const currentTheme = localStorage.getItem('theme'); // Aplicar tema inicial if (currentTheme === 'light') { body.classList.remove('dark-mode'); icon?.classList.replace('fa-sun', 'fa-moon'); } else { body.classList.add('dark-mode'); icon?.classList.replace('fa-moon', 'fa-sun'); if (!currentTheme) { localStorage.setItem('theme', 'dark'); } } // Toggle modo escuro elements.themeToggle.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); body.classList.toggle('dark-mode'); const isDark = body.classList.contains('dark-mode'); localStorage.setItem('theme', isDark ? 'dark' : 'light'); if (icon) { icon.classList.replace(isDark ? 'fa-moon' : 'fa-sun', isDark ? 'fa-sun' : 'fa-moon'); } }); } // ============= MENU MOBILE ============= function initMobileMenu() { if (!elements.mobileMenuToggle || !elements.mainNav) return; function toggleMenu(shouldOpen) { const isOpen = shouldOpen ?? !elements.mobileMenuToggle.classList.contains('active'); elements.mobileMenuToggle.classList.toggle('active', isOpen); elements.mobileMenuToggle.setAttribute('aria-expanded', isOpen); elements.mainNav.classList.toggle('active', isOpen); body.classList.toggle('menu-open', isOpen); body.style.overflow = isOpen ? 'hidden' : ''; } // Toggle menu elements.mobileMenuToggle.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); toggleMenu(); }); // Fechar menu ao clicar em links elements.mainNav.addEventListener('click', (e) => { if (e.target.tagName === 'A' && !e.target.closest('.theme-toggle-item')) { toggleMenu(false); } }); // Fechar menu ao clicar fora document.addEventListener('click', (e) => { if (body.classList.contains('menu-open')) { const isClickInsideNav = elements.mainNav.contains(e.target); const isClickOnToggle = elements.mobileMenuToggle.contains(e.target); if (!isClickInsideNav && !isClickOnToggle) { toggleMenu(false); } } }); } // ============= SMOOTH SCROLL ============= function initSmoothScroll() { document.addEventListener('click', (e) => { const anchor = e.target.closest('a[href*="#"]'); if (!anchor) return; const href = anchor.getAttribute('href'); const hashIndex = href.indexOf('#'); if (hashIndex === -1) return; const hash = href.substring(hashIndex); const targetId = hash.substring(1); const target = document.getElementById(targetId); if (target) { e.preventDefault(); target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); } // ============= HEADER SCROLL ============= function initHeaderScroll() { if (!elements.header) return; const handleScroll = debounce(() => { const shouldElevate = window.scrollY > 100; elements.header.style.boxShadow = shouldElevate ? '0 4px 20px rgba(0,0,0,0.15)' : '0 2px 10px rgba(0,0,0,0.1)'; }, 50); window.addEventListener('scroll', handleScroll, { passive: true }); } // ============= ANIMAÇÃO CARDS ============= function initCardAnimations() { const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.style.opacity = '1'; entry.target.style.transform = 'translateY(0)'; } }); }, observerOptions); const cards = document.querySelectorAll('.area-card, .post-card, .post-card-archive'); cards.forEach(card => { card.style.opacity = '0'; card.style.transform = 'translateY(20px)'; card.style.transition = 'all 0.6s ease'; observer.observe(card); }); } // ============= EFEITO RIPPLE ============= function initRippleEffect() { document.addEventListener('click', (e) => { const card = e.target.closest('.area-card'); if (!card) return; const ripple = document.createElement('span'); ripple.classList.add('ripple-effect'); const rect = card.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; ripple.style.left = x + 'px'; ripple.style.top = y + 'px'; card.appendChild(ripple); setTimeout(() => ripple.remove(), 600); }); } // ============= CARREGAR MAIS POSTS ============= function initLoadMorePosts() { if (!elements.loadMoreBtn || !elements.postsContainer) return; elements.loadMoreBtn.addEventListener('click', async function() { const currentPage = parseInt(this.getAttribute('data-page')); const maxPages = parseInt(this.getAttribute('data-max')); const nextPage = currentPage + 1; // Mostrar spinner elements.loadMoreBtn.style.display = 'none'; elements.loadingSpinner.style.display = 'block'; const formData = new FormData(); formData.append('action', 'load_more_posts'); formData.append('page', nextPage); formData.append('nonce', ajaxData.nonce); try { const response = await fetch(ajaxData.ajaxurl, { method: 'POST', body: formData }); const data = await response.json(); if (data.success) { const tempDiv = document.createElement('div'); tempDiv.innerHTML = data.data.posts; const newPosts = tempDiv.querySelectorAll('.post-card'); newPosts.forEach((post, index) => { post.style.opacity = '0'; post.style.transform = 'translateY(20px)'; elements.postsContainer.appendChild(post); setTimeout(() => { post.style.transition = 'all 0.6s ease'; post.style.opacity = '1'; post.style.transform = 'translateY(0)'; }, index * 100); }); elements.loadMoreBtn.setAttribute('data-page', nextPage); if (nextPage >= maxPages) { elements.loadMoreBtn.style.display = 'none'; elements.loadingSpinner.style.display = 'none'; } else { elements.loadMoreBtn.style.display = 'inline-flex'; elements.loadingSpinner.style.display = 'none'; } } else { elements.loadMoreBtn.style.display = 'none'; elements.loadingSpinner.style.display = 'none'; } } catch (error) { elements.loadMoreBtn.style.display = 'inline-flex'; elements.loadingSpinner.style.display = 'none'; } }); } // ============= INICIALIZAÇÃO ============= document.addEventListener('DOMContentLoaded', () => { initCookieBanner(); initDarkMode(); initMobileMenu(); initSmoothScroll(); initHeaderScroll(); initCardAnimations(); initRippleEffect(); initLoadMorePosts(); }); })();