PATH:
home
/
u865795251
/
domains
/
whatisnewis.com
/
public_html
/
vfa
/
Editing: main.js
// Global dynamic pricing configuration let BASE_PRICE = 289; let REMINDER_PRICE = 40; const GST_RATE = 0.18; document.addEventListener('DOMContentLoaded', () => { // Fetch dynamic pricing settings on boot fetch('get-settings.php') .then(res => res.json()) .then(data => { BASE_PRICE = data.webinar_price; REMINDER_PRICE = data.reminder_price; const addonLabelText = document.getElementById('addon-label-text'); if (addonLabelText) { addonLabelText.innerText = `Add Call Reminder Support (+₹${REMINDER_PRICE})`; } if (typeof window.updatePricing === 'function') { window.updatePricing(); } }) .catch(err => console.error("Failed to load active pricing configuration:", err)); // --- 1. Sticky Header --- const header = document.getElementById('header'); window.addEventListener('scroll', () => { if (window.scrollY > 50) { header.classList.add('scrolled'); } else { header.classList.remove('scrolled'); } }); // --- 2. Mobile Menu Toggle --- const hamburger = document.getElementById('hamburger'); const navLinks = document.getElementById('nav-links'); hamburger.addEventListener('click', () => { hamburger.classList.toggle('active'); navLinks.classList.toggle('active'); }); // Close mobile menu when a link is clicked document.querySelectorAll('.nav-links a').forEach(link => { link.addEventListener('click', () => { hamburger.classList.remove('active'); navLinks.classList.remove('active'); }); }); // --- 3. Scroll Reveal Animations --- const revealElements = document.querySelectorAll('.reveal, .reveal-left, .reveal-right'); const revealOptions = { threshold: 0.1, rootMargin: "0px 0px -50px 0px" }; const revealObserver = new IntersectionObserver(function (entries, observer) { entries.forEach(entry => { if (!entry.isIntersecting) { return; } entry.target.classList.add('visible'); observer.unobserve(entry.target); // Stop observing once revealed }); }, revealOptions); revealElements.forEach(el => { revealObserver.observe(el); }); // --- 4. Counter Animation (Trust Section) --- const counters = document.querySelectorAll('.stat-number'); let counted = false; const counterObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting && !counted) { counted = true; counters.forEach(counter => { const target = +counter.getAttribute('data-target'); const duration = 2000; // 2 seconds const increment = target / (duration / 16); // 60fps approx let current = 0; const updateCounter = () => { current += increment; if (current < target) { counter.innerText = Math.ceil(current) + (target > 90 ? '+' : '%'); requestAnimationFrame(updateCounter); } else { counter.innerText = target + (target > 90 ? '+' : '%'); } }; updateCounter(); }); observer.disconnect(); } }); }, { threshold: 0.5 }); const trustSection = document.querySelector('.trust-stats'); if (trustSection) { counterObserver.observe(trustSection); } // --- 5. Testimonial Slider --- const track = document.getElementById('testimonial-track'); const prevBtn = document.getElementById('prev-testi'); const nextBtn = document.getElementById('next-testi'); if (prevBtn && nextBtn && track) { nextBtn.addEventListener('click', () => { const cardWidth = track.querySelector('.testimonial-card').offsetWidth; const gap = 24; track.scrollBy({ left: cardWidth + gap, behavior: 'smooth' }); }); prevBtn.addEventListener('click', () => { const cardWidth = track.querySelector('.testimonial-card').offsetWidth; const gap = 24; track.scrollBy({ left: -(cardWidth + gap), behavior: 'smooth' }); }); } // --- 6. FAQ Accordion --- const faqItems = document.querySelectorAll('.faq-item'); faqItems.forEach(item => { const question = item.querySelector('.faq-question'); const answer = item.querySelector('.faq-answer'); question.addEventListener('click', () => { const isActive = item.classList.contains('active'); // Close all items faqItems.forEach(faq => { faq.classList.remove('active'); faq.querySelector('.faq-answer').style.maxHeight = null; }); // Open clicked if it wasn't active if (!isActive) { item.classList.add('active'); answer.style.maxHeight = answer.scrollHeight + "px"; } }); }); // Initial setup for active FAQ const activeFaq = document.querySelector('.faq-item.active .faq-answer'); if (activeFaq) { activeFaq.style.maxHeight = activeFaq.scrollHeight + "px"; } // --- 7. Smooth Scroll for Anchor Links --- document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const targetId = this.getAttribute('href'); if (targetId === '#') return; const targetElement = document.querySelector(targetId); if (targetElement) { // Adjust for sticky header height const headerHeight = header.offsetHeight; const elementPosition = targetElement.getBoundingClientRect().top; const offsetPosition = elementPosition + window.pageYOffset - headerHeight; window.scrollTo({ top: offsetPosition, behavior: 'smooth' }); } }); }); // --- 8. Intl-Tel-Input Initialization --- const phoneInput = document.querySelector("#phone"); if (phoneInput) { window.iti = window.intlTelInput(phoneInput, { initialCountry: "in", separateDialCode: true, utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/18.2.1/js/utils.js", }); } // --- 9. Dynamic Pricing Logic --- const addReminderCheck = document.getElementById('addReminder'); const summarySubtotal = document.getElementById('summary-subtotal'); const summaryGst = document.getElementById('summary-gst'); const summaryTotal = document.getElementById('summary-total'); const btnText = document.querySelector('.btn-text'); // Dynamically exposed pricing handler window.updatePricing = function() { if (!addReminderCheck) return; const isReminderSelected = addReminderCheck.checked; const currentBase = BASE_PRICE + (isReminderSelected ? REMINDER_PRICE : 0); const currentGst = currentBase * GST_RATE; const currentTotal = currentBase + currentGst; // Update UI summarySubtotal.innerText = `₹${currentBase.toFixed(2)}`; summaryGst.innerText = `₹${currentGst.toFixed(2)}`; summaryTotal.innerText = `₹${currentTotal.toFixed(2)}`; btnText.innerText = `Pay ₹${currentBase} + GST`; } if (addReminderCheck) { addReminderCheck.addEventListener('change', window.updatePricing); window.updatePricing(); // Init on load } // --- 11. Newsletter Subscription Handler --- const newsletterForm = document.getElementById('newsletterForm'); const newsletterEmail = document.getElementById('newsletterEmail'); const newsletterSubmitBtn = document.getElementById('newsletterSubmitBtn'); const newsletterMessage = document.getElementById('newsletterMessage'); if (newsletterForm) { newsletterForm.addEventListener('submit', (e) => { e.preventDefault(); const email = newsletterEmail.value.trim(); if (!email) return; newsletterSubmitBtn.disabled = true; newsletterSubmitBtn.innerText = 'Subscribing...'; newsletterMessage.style.display = 'none'; fetch('subscribe-newsletter.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: email }) }) .then(res => res.json()) .then(data => { newsletterSubmitBtn.disabled = false; newsletterSubmitBtn.innerText = 'Subscribe'; if (data.success) { newsletterMessage.style.display = 'block'; newsletterMessage.style.background = 'rgba(0, 230, 118, 0.1)'; newsletterMessage.style.color = 'var(--green-primary)'; newsletterMessage.style.border = '1px solid rgba(0, 230, 118, 0.2)'; newsletterMessage.innerText = data.message; newsletterEmail.value = ''; } else { newsletterMessage.style.display = 'block'; newsletterMessage.style.background = 'rgba(239, 68, 68, 0.1)'; newsletterMessage.style.color = '#ef4444'; newsletterMessage.style.border = '1px solid rgba(239, 68, 68, 0.2)'; newsletterMessage.innerText = `⚠️ ${data.error || 'Failed to subscribe.'}`; } }) .catch(err => { newsletterSubmitBtn.disabled = false; newsletterSubmitBtn.innerText = 'Subscribe'; newsletterMessage.style.display = 'block'; newsletterMessage.style.background = 'rgba(239, 68, 68, 0.1)'; newsletterMessage.style.color = '#ef4444'; newsletterMessage.style.border = '1px solid rgba(239, 68, 68, 0.2)'; }); }); } // --- 12. Hero Foreground Video Mute/Unmute Toggle --- const fgVideo = document.getElementById('hero-foreground-video'); const muteToggle = document.getElementById('video-mute-toggle'); if (fgVideo && muteToggle) { muteToggle.addEventListener('click', () => { if (fgVideo.muted) { fgVideo.muted = false; muteToggle.innerHTML = '<i class="fa-solid fa-volume-high"></i>'; muteToggle.setAttribute('aria-label', 'Mute Video'); } else { fgVideo.muted = true; muteToggle.innerHTML = '<i class="fa-solid fa-volume-xmark"></i>'; muteToggle.setAttribute('aria-label', 'Unmute Video'); } }); } }); // --- 10. Payment & Form Processing (Secure Razorpay Integration) --- function processPayment() { const btn = document.getElementById('payButton'); const formMessage = document.getElementById('formMessage'); const addReminderCheck = document.getElementById('addReminder'); // Extract values const name = document.getElementById('fullName').value.trim(); const email = document.getElementById('email').value.trim(); const message = document.getElementById('message').value.trim(); const phone = document.getElementById('phone').value.trim(); // Basic frontend validations if (!name || !email || !phone) { formMessage.className = 'form-message error'; formMessage.innerText = '⚠️ Please fill out all required fields (Name, Email, Phone).'; formMessage.style.display = 'block'; return; } if (window.iti && !window.iti.isValidNumber()) { formMessage.className = 'form-message error'; formMessage.innerText = '⚠️ Please enter a valid phone number.'; formMessage.style.display = 'block'; return; } const countryCode = window.iti ? window.iti.getSelectedCountryData().dialCode : '91'; // Calculate final amount from active configuration const currentBase = BASE_PRICE + (addReminderCheck.checked ? REMINDER_PRICE : 0); const finalAmount = currentBase + (currentBase * GST_RATE); // Show processing state btn.classList.add('processing'); formMessage.style.display = 'none'; // Step 1: Create Order in backend fetch('create-order.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ amount: finalAmount.toFixed(2), name: name, email: email, phone: phone, countryCode: countryCode, message: message, reminderAdded: addReminderCheck.checked }) }) .then(res => { if (!res.ok) throw new Error('Order creation failed'); return res.json(); }) .then(orderData => { // Step 2: Open Razorpay Checkout popup using backend-generated Order ID (or client fallback if mock) const options = { "key": orderData.key_id, "amount": orderData.amount, "currency": "INR", "name": "VFA Academy", "description": "Premium Webinar Registration", "image": "https://vfaacademy.com/wp-content/uploads/2023/10/vfa-logo-1.png", "handler": function (response) { // Step 3: Securely verify payment signature on the backend fetch('verify-payment.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ razorpay_order_id: response.razorpay_order_id || orderData.order_id, razorpay_payment_id: response.razorpay_payment_id, razorpay_signature: response.razorpay_signature || '' }) }) .then(res => res.json()) .then(verifyData => { btn.classList.remove('processing'); if (verifyData.success) { // Reset Form fields document.getElementById('registrationForm').reset(); if (addReminderCheck) { addReminderCheck.checked = false; addReminderCheck.dispatchEvent(new Event('change')); } // Redirect to thank you page with parameters const inviteLink = "https://chat.whatsapp.com/DivfwVX8wJgKMnzMwBvnSV"; // Use the user's real community link from env window.location.href = `thankyou.html?total=${finalAmount.toFixed(2)}&reminder=${addReminderCheck.checked}&invite=${encodeURIComponent(inviteLink)}`; } else { alert("⚠️ Payment verification failure. Please contact support."); } }) .catch(err => { btn.classList.remove('processing'); console.error("Verification connection error:", err); alert("⚠️ Error verifying payment signature. Please contact support."); }); }, "prefill": { "name": name, "email": email, "contact": `+${countryCode}${phone}` }, "theme": { "color": "#00e676" }, "modal": { "ondismiss": function () { btn.classList.remove('processing'); } } }; // If it's a real order (not mock), attach the order_id for signature verification if (!orderData.mock) { options.order_id = orderData.order_id; } const rzp = new window.Razorpay(options); // Handle checkout failures rzp.on('payment.failed', function (response) { btn.classList.remove('processing'); alert(`⚠️ Payment Failed: ${response.error.description}`); }); rzp.open(); }) .catch(err => { btn.classList.remove('processing'); console.error("Initiation error:", err); alert("⚠️ Failed to connect to payment server. Please ensure your PHP server is online and you are accessing this page via http://localhost:3000/ (or your web hosting) instead of double-clicking index.html directly."); }); }
SAVE
CANCEL