// ======================================== // V2 - MINIMAL VERSION - JavaScript // Simple, clean interactions // ======================================== // Mobile Menu behavior is now handled by Bootstrap 5 (data-bs-toggle="collapse") // No manual JS toggle needed for the hamburger. // Smooth Scroll document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { const href = this.getAttribute('href'); if (href === '#' || href === '#home') return; const target = document.querySelector(href); if (target) { e.preventDefault(); const offset = 80; const targetPosition = target.offsetTop - offset; window.scrollTo({ top: targetPosition, behavior: 'smooth' }); } }); }); // Navbar scroll effect const navbar = document.querySelector('.navbar'); if (navbar) { window.addEventListener('scroll', () => { if (window.pageYOffset > 50) { navbar.classList.add('scrolled'); } else { navbar.classList.remove('scrolled'); } }); } // Intersection Observer (Animations) const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const fadeInObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.style.opacity = '1'; entry.target.style.transform = 'translateY(0)'; } }); }, observerOptions); document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('.service-item, .team-card, .testimonial-card, .step').forEach(el => { el.style.opacity = '0'; el.style.transform = 'translateY(30px)'; el.style.transition = 'opacity 0.6s ease, transform 0.6s ease'; fadeInObserver.observe(el); }); // Stats Counter const stats = document.querySelectorAll('.stat h3'); if (stats.length) { const isCustomizer = window.parent && window.parent.wp && window.parent.wp.customize; const countUp = (element, target) => { const isNumber = !target.includes('+') && !target.includes('$') && !target.includes('%'); if (!isNumber) return; const numericTarget = parseInt(target.replace(/[^0-9]/g, '')); if (isNaN(numericTarget)) return; const duration = 1500; const frames = 90; const increment = numericTarget / frames; let current = 0; const timer = setInterval(() => { current += increment; if (current >= numericTarget) { element.textContent = target; clearInterval(timer); } else { element.textContent = Math.floor(current) + target.replace(/[0-9]/g, ''); } }, 1000 / 60); }; const statsObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const el = entry.target; const val = el.getAttribute('data-target'); if (val && val !== '0') countUp(el, val); statsObserver.unobserve(el); } }); }, { threshold: 0.2 }); stats.forEach(stat => { const original = stat.textContent.trim(); stat.setAttribute('data-target', original); if (!isCustomizer && original !== '0' && original !== '') { stat.textContent = '0'; statsObserver.observe(stat); } }); } }); // Image Drag Prevention document.querySelectorAll('img').forEach(img => { img.addEventListener('dragstart', (e) => e.preventDefault()); }); // Phone Formatting document.querySelectorAll('input[type="tel"]').forEach(input => { input.addEventListener('input', (e) => { let value = e.target.value.replace(/\D/g, ''); if (value.length > 0) { if (value.startsWith('880')) value = value.substring(3); e.target.value = '+880 ' + value.substring(0, 10).replace(/(\d{3})(\d{3})(\d{4})/, '$1 $2 $3').trim(); } }); }); /** * Booking System Logic (Migrated from footer.php) */ const getBackupSlots = () => { const times = ['10:00 AM', '10:20 AM', '10:40 AM', '11:00 AM', '11:20 AM', '11:40 AM', '12:00 PM', '12:20 PM', '12:40 PM', '01:00 PM', '01:20 PM', '01:40 PM', '02:00 PM', '02:20 PM', '02:40 PM', '03:00 PM', '03:20 PM', '03:40 PM', '04:00 PM', '04:20 PM', '04:40 PM', '05:00 PM', '05:20 PM', '05:40 PM']; return times.map(t => ({ time: t, status: 'available' })); }; const renderSlotsUI = (slots, container, timeInput) => { if (!container) return; container.innerHTML = ''; slots.forEach(slot => { const div = document.createElement('div'); div.className = 'slot-item' + (slot.status === 'taken' ? ' taken' : ''); div.textContent = slot.time; if (slot.status !== 'taken') { div.onclick = function () { document.querySelectorAll('.slot-item').forEach(s => s.classList.remove('selected')); this.classList.add('selected'); if (timeInput) timeInput.value = slot.time; }; } container.appendChild(div); }); }; window.openBookingModal = function () { const modal = document.getElementById('bookingModal'); if (modal) { modal.classList.add('active'); document.body.style.overflow = 'hidden'; } }; window.closeBookingModal = function () { const modal = document.getElementById('bookingModal'); if (modal) { modal.classList.remove('active'); document.body.style.overflow = ''; } }; document.addEventListener('DOMContentLoaded', () => { const dateInput = document.getElementById('preferredDate'); const slotsContainer = document.getElementById('slots-container'); const timeInput = document.getElementById('preferredTime'); if (dateInput) { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); dateInput.setAttribute('min', tomorrow.toISOString().split('T')[0]); dateInput.addEventListener('change', function () { if (!this.value) return; renderSlotsUI(getBackupSlots(), slotsContainer, timeInput); const formData = new FormData(); formData.append('action', 'fetch_slots'); formData.append('date', this.value); formData.append('nonce', (window.applicationGuyData && window.applicationGuyData.nonce) || ''); fetch((window.applicationGuyData && window.applicationGuyData.ajaxUrl) || '/wp-admin/admin-ajax.php', { method: 'POST', body: formData }) .then(res => res.json()) .then(data => { if (data.success && data.data && data.data.length > 0) { renderSlotsUI(data.data, slotsContainer, timeInput); } }) .catch(err => console.warn('Server sync failed, kept backup slots.', err)); }); } const modal = document.getElementById('bookingModal'); if (modal) { modal.onclick = (e) => { if (e.target === modal) window.closeBookingModal(); }; } const urlParams = new URLSearchParams(window.location.search); if (urlParams.has('booking_success')) window.openBookingModal(); }); console.log('Application Guy v19.2 - Core Script Ready');