/* ═══════════════════════════════════════════════════════ ELEGANCE OF INDIA — MAIN JAVASCRIPT All page scripts consolidated here with page guards. ═══════════════════════════════════════════════════════ */ document.addEventListener('DOMContentLoaded', () => { /* ════════════════════════════════════════════════════ COMMON — runs on every page ════════════════════════════════════════════════════ */ /* ── Header scroll shadow ── */ const header = document.getElementById('siteHeader'); if (header) { window.addEventListener('scroll', () => { header.classList.toggle('scrolled', window.scrollY > 60); }, { passive: true }); } /* ── Cart Badge (localStorage count) ── */ // Moved to header.php for better synchronization /* ── Back to top ── */ const btt = document.getElementById('backToTop'); if (btt) { window.addEventListener('scroll', () => { btt.classList.toggle('visible', window.scrollY > 400); }, { passive: true }); btt.addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' })); } /* ── Mega menu (desktop hover) ── */ document.querySelectorAll('.has-mega').forEach(li => { li.addEventListener('mouseenter', () => li.querySelector('.mega-panel')?.classList.add('open')); li.addEventListener('mouseleave', () => li.querySelector('.mega-panel')?.classList.remove('open')); }); /* ── Mobile menu ── */ const mobileBtn = document.getElementById('mobileMenuBtn'); const mainNav = document.getElementById('mainNav'); if (mobileBtn && mainNav) { mobileBtn.addEventListener('click', () => { mainNav.classList.toggle('open'); mobileBtn.classList.toggle('active'); }); if (window.innerWidth <= 768) { document.querySelectorAll('.has-mega > a').forEach(link => { link.addEventListener('click', (e) => { e.preventDefault(); link.parentElement.classList.toggle('open'); }); }); } } /* ── Header search ── */ // Moved to header.php /* ── Search row toggle ── */ // Moved to header.php /* ════════════════════════════════════════════════════ PAGE: HOME (index.html) ════════════════════════════════════════════════════ */ if (document.getElementById('heroSlider')) { /* ── Category Carousel (LEGACY - Redundant if implemented in index.php) ── */ const catTrack = document.getElementById('catTrack'); const catPrev = document.getElementById('catPrev'); const catNext = document.getElementById('catNext'); if (catTrack && catPrev && catNext) { try { let catIndex = 0; const gap = 24; const total = catTrack.children.length; const card = catTrack.querySelector('.cat-card') || catTrack.querySelector('.home-cat-card'); if (card) { const getCardW = () => card.offsetWidth; const getVisible = () => Math.floor((catTrack.parentElement.clientWidth + gap) / (getCardW() + gap)); const updateCatArrows = () => { catPrev.disabled = catIndex === 0; catNext.disabled = catIndex >= total - getVisible(); }; const catSlideTo = (idx) => { catIndex = Math.max(0, Math.min(idx, total - getVisible())); catTrack.style.transform = `translateX(-${catIndex * (getCardW() + gap)}px)`; updateCatArrows(); }; catPrev.addEventListener('click', () => catSlideTo(catIndex - 1)); catNext.addEventListener('click', () => catSlideTo(catIndex + 1)); updateCatArrows(); window.addEventListener('resize', () => catSlideTo(0)); } } catch(e) { console.warn("Legacy Category Carousel error:", e); } } /* ── Designer Carousel ── */ const track = document.getElementById('designerTrack'); if (track) { const dcCards = track.querySelectorAll('.designer-card'); const cardCount = dcCards.length; if (cardCount > 0) { let dcIndex = 0; function getVisibleCount() { const w = window.innerWidth; if (w > 1200) return 7; if (w > 1024) return 5; if (w > 768) return 4; return 3; } function slideDesigners(dir) { const maxIndex = cardCount - getVisibleCount(); dcIndex = Math.max(0, Math.min(dcIndex + dir, maxIndex)); track.style.transform = `translateX(-${dcIndex * (dcCards[0].offsetWidth + 20)}px)`; } const dPrevBtn = document.getElementById('dPrev'); const dNextBtn = document.getElementById('dNext'); if (dPrevBtn) dPrevBtn.addEventListener('click', () => slideDesigners(-1)); if (dNextBtn) dNextBtn.addEventListener('click', () => slideDesigners(1)); window.addEventListener('resize', () => { dcIndex = 0; track.style.transform = 'translateX(0)'; }); } } /* ── Wishlist toggle (home product cards) ── */ document.querySelectorAll('.wishlist-btn').forEach(btn => { btn.addEventListener('click', () => { const icon = btn.querySelector('i'); icon.classList.toggle('far'); icon.classList.toggle('fas'); icon.style.color = icon.classList.contains('fas') ? '#c0392b' : ''; }); }); /* ── Quick View Modal ── */ const overlay = document.getElementById('quickViewOverlay'); const modalClose = document.getElementById('modalClose'); const productData = [ { img: 'https://images.unsplash.com/photo-1583391733956-6c78276477e3?w=500&q=80', designer: 'Sabyasachi', name: 'Ivory Zardozi Bridal Lehenga', price: '₹3,45,000' }, { img: 'https://images.unsplash.com/photo-1515886657613-9f3515b0c78f?w=500&q=80', designer: 'Manish Malhotra', name: 'Emerald Sequin Draped Gown', price: '₹1,85,000' }, { img: 'https://images.unsplash.com/photo-1605518216938-7c31b7b14ad0?w=500&q=80', designer: 'Anita Dongre', name: 'Rose Gold Embroidered Anarkali', price: '₹62,500' }, { img: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=500&q=80', designer: 'Masaba Gupta', name: 'Cobalt Block-Print Kurta Set', price: '₹38,000' }, { img: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=500&q=80', designer: 'Ridhi Mehra', name: 'Sage Embroidered Kurta Set', price: '₹44,000' }, { img: 'https://images.unsplash.com/photo-1595341888016-a392ef81b7de?w=500&q=80', designer: 'Tarun Tahiliani', name: 'Midnight Navy Brocade Sherwani', price: '₹1,20,000' }, { img: 'https://images.unsplash.com/photo-1539109136881-3be0616acf4b?w=500&q=80', designer: 'Anamika Khanna', name: 'Crimson Handwoven Banarasi Saree', price: '₹95,000' }, { img: 'https://images.unsplash.com/photo-1605518216938-7c31b7b14ad0?w=500&q=80', designer: 'Gaurav Gupta', name: 'Molten Gold Sculptural Lehenga', price: '₹2,75,000' }, ]; document.querySelectorAll('.quick-view-btn').forEach((btn, index) => { btn.addEventListener('click', () => { const data = productData[index] || productData[0]; document.getElementById('qvImage').src = data.img; document.getElementById('qvImage').alt = data.name; document.getElementById('qvDesigner').textContent = data.designer; document.getElementById('qvName').textContent = data.name; document.getElementById('qvPrice').textContent = data.price; overlay.classList.add('open'); document.body.style.overflow = 'hidden'; }); }); function closeModal() { if (overlay) overlay.classList.remove('open'); document.body.style.overflow = ''; } if (modalClose) modalClose.addEventListener('click', closeModal); if (overlay) overlay.addEventListener('click', (e) => { if (e.target === overlay) closeModal(); }); document.addEventListener('keydown', (e) => { if (e.key === 'Escape') closeModal(); }); /* ── Newsletter Form ── */ const newsletterForm = document.getElementById('newsletterForm'); if (newsletterForm) newsletterForm.addEventListener('submit', (e) => { e.preventDefault(); const input = e.target.querySelector('input'); const btn = e.target.querySelector('button'); const orig = btn.textContent; btn.textContent = 'Subscribed! ✓'; btn.style.background = '#2ecc71'; input.value = ''; setTimeout(() => { btn.textContent = orig; btn.style.background = ''; }, 3000); }); /* ── Add to Cart Counter ── */ const cartCount = document.querySelector('.cart-count'); let count = 0; document.querySelectorAll('.product-name').forEach(name => { name.style.cursor = 'pointer'; name.addEventListener('click', () => { count++; if (cartCount) { cartCount.textContent = count; cartCount.style.transform = 'scale(1.4)'; setTimeout(() => { cartCount.style.transform = ''; }, 300); } }); }); /* ── Intersection Observer: fade-in sections ── */ const fadeEls = document.querySelectorAll('.product-card, .occ-card, .cat-card, .journal-card, .designer-card, .trust-item'); fadeEls.forEach(el => { el.style.opacity = '0'; el.style.transform = 'translateY(24px)'; el.style.transition = 'opacity 0.55s ease, transform 0.55s ease'; }); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { setTimeout(() => { entry.target.style.opacity = '1'; entry.target.style.transform = 'translateY(0)'; }, (entry.target.dataset.delay || 0)); observer.unobserve(entry.target); } }); }, { threshold: 0.12 }); document.querySelectorAll('.products-grid .product-card, .occasion-grid .occ-card').forEach((el, i) => { el.dataset.delay = i * 60; }); fadeEls.forEach(el => observer.observe(el)); /* ── Cycle images on hover ── */ document.querySelectorAll('.product-card[data-cycle]').forEach(card => { const imgs = Array.from(card.querySelectorAll('.cycle-img')); let idx = 0, timer = null; card.addEventListener('mouseenter', () => { idx = 0; imgs.forEach(img => { img.style.opacity = '0'; }); imgs[idx].style.opacity = '1'; timer = setInterval(() => { imgs[idx].style.opacity = '0'; idx = (idx + 1) % imgs.length; imgs[idx].style.opacity = '1'; }, 900); }); card.addEventListener('mouseleave', () => { clearInterval(timer); timer = null; idx = 0; imgs.forEach(img => { img.style.opacity = '0'; }); }); }); } // end HOME PAGE /* ════════════════════════════════════════════════════ PAGE: PLPs — Mens / Womens / Boys / Girls ════════════════════════════════════════════════════ */ if (document.querySelector('.plp-card')) { // Filter accordion document.querySelectorAll('.filter-group__header').forEach(btn => { btn.addEventListener('click', () => btn.closest('.filter-group').classList.toggle('open')); }); const filterLabels = { 'salwar-kameez': 'Salwar Kameez', 'sarees': 'Sarees', 'lehengas': 'Lehenga Choli', 'palazzo': 'Palazzo-Bottom Suits' }; function applyFilter(filter) { document.querySelectorAll('.cat-pill').forEach(p => { p.classList.toggle('active', p.dataset.filter === filter); }); document.querySelectorAll('.plp-card').forEach(card => { card.style.display = (filter === 'all' || card.dataset.category === filter) ? '' : 'none'; }); // Update count label if present (girls page) const countEl = document.getElementById('plpCount'); if (countEl) { const visible = [...document.querySelectorAll('.plp-card')].filter(c => c.style.display !== 'none').length; countEl.textContent = visible + ' style' + (visible !== 1 ? 's' : ''); } // Update breadcrumb const bc = document.getElementById('plpBreadcrumb'); if (bc) { const label = filterLabels[filter]; const existing = bc.querySelector('.current'); const existingSep = bc.querySelector('.sep'); if (label) { if (existing) existing.textContent = label; else { if (!existingSep) bc.insertAdjacentHTML('beforeend', ``); bc.insertAdjacentHTML('beforeend', `${label}`); } } else { if (existing) existing.remove(); if (existingSep) existingSep.remove(); } } const url = new URL(window.location); if (filter === 'all') url.searchParams.delete('filter'); else url.searchParams.set('filter', filter); window.history.replaceState({}, '', url); } // Category pills document.querySelectorAll('.cat-pill').forEach(pill => { pill.addEventListener('click', e => { e.preventDefault(); applyFilter(pill.dataset.filter); }); }); // Filter checkboxes document.querySelectorAll('.clothing-filter-option').forEach(cb => { cb.addEventListener('change', () => { const checked = document.querySelector('.clothing-filter-option:checked'); applyFilter(checked ? checked.value : 'all'); }); }); // Apply filter from URL on load const urlParams = new URLSearchParams(window.location.search); const urlFilter = urlParams.get('filter'); if (urlFilter) { applyFilter(urlFilter); const matchingCb = document.querySelector(`.clothing-filter-option[value="${urlFilter}"]`); if (matchingCb) matchingCb.checked = true; } } // end PLPs /* ════════════════════════════════════════════════════ PAGE: PRODUCT DETAIL (PDP) ════════════════════════════════════════════════════ */ if (document.getElementById('mainImg')) { const mainImg = document.getElementById('mainImg'); document.querySelectorAll('.pdp-thumb').forEach(thumb => { thumb.addEventListener('click', () => { document.querySelectorAll('.pdp-thumb').forEach(t => t.classList.remove('active')); thumb.classList.add('active'); mainImg.src = thumb.dataset.img; }); }); // Size selector document.querySelectorAll('.size-btn:not(.unavailable)').forEach(btn => { btn.addEventListener('click', () => { document.querySelectorAll('.size-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); }); }); // Colour selector document.querySelectorAll('.colour-dot').forEach(dot => { dot.addEventListener('click', () => { document.querySelectorAll('.colour-dot').forEach(d => d.classList.remove('active')); dot.classList.add('active'); document.getElementById('selectedColour').textContent = dot.dataset.name; }); }); // Wishlist toggle const wishBtn = document.getElementById('pdpWishlistBtn'); if (wishBtn) { wishBtn.addEventListener('click', () => { const icon = wishBtn.querySelector('i'); const label = wishBtn.querySelector('span'); const saved = icon.classList.toggle('fas'); icon.classList.toggle('far', !saved); icon.style.color = saved ? '#c0392b' : ''; label.textContent = saved ? 'Saved to Wishlist' : 'Save to Wishlist'; }); } // Accordion document.querySelectorAll('.accord-header').forEach(btn => { btn.addEventListener('click', () => btn.closest('.accord-item').classList.toggle('open')); }); } // end PDP /* ════════════════════════════════════════════════════ LOGIN MODAL & AUTHENTICATION ════════════════════════════════════════════════════ */ const loginBtn = document.getElementById('loginBtn'); const accountBtn = document.getElementById('accountBtn'); const loginModal = document.getElementById('loginModal'); const loginClose = document.getElementById('loginClose'); function openLogin() { if (!loginModal) return; loginModal.classList.add('open'); document.body.style.overflow = 'hidden'; } function closeLogin() { if (!loginModal) return; loginModal.classList.remove('open'); document.body.style.overflow = ''; } if (loginBtn) loginBtn.addEventListener('click', (e) => { e.preventDefault(); openLogin(); }); if (loginClose) loginClose.addEventListener('click', closeLogin); if (loginModal) loginModal.addEventListener('click', e => { if (e.target === loginModal) closeLogin(); }); // Logout dropdown/action if (accountBtn) { const accountMenu = document.getElementById('accountMenu'); accountBtn.addEventListener('click', function(e) { e.stopPropagation(); if (accountMenu) accountMenu.classList.toggle('active'); }); // Close menu when clicking outside document.addEventListener('click', () => { if (accountMenu) accountMenu.classList.remove('active'); }); } const menuLogoutBtn = document.getElementById('menuLogoutBtn'); if (menuLogoutBtn) { menuLogoutBtn.addEventListener('click', function(e) { e.preventDefault(); if (confirm('Are you sure you want to log out?')) { const params = new URLSearchParams(); params.append('action', 'logout'); fetch('auth_action.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params.toString() }) .then(res => res.json()) .then(data => { if (data.success) { window.location.reload(); } }); } }); } // Tabs within login modal document.querySelectorAll('.login-tab').forEach(tab => { tab.addEventListener('click', () => { document.querySelectorAll('.login-tab').forEach(t => t.classList.remove('active')); document.querySelectorAll('.login-panel').forEach(p => p.classList.remove('active')); tab.classList.add('active'); const target = document.getElementById(tab.dataset.target); if (target) target.classList.add('active'); }); }); /* ── Auth form submissions ── */ const submitLogin = document.getElementById('loginSubmitBtn'); if (submitLogin) { submitLogin.addEventListener('click', function() { const email = document.getElementById('loginEmail').value; const pass = document.getElementById('loginPassword').value; const errorDiv = document.getElementById('loginError'); if (errorDiv) errorDiv.style.display = 'none'; if (!email || !pass) { if (errorDiv) { errorDiv.textContent = 'Please enter both email and password.'; errorDiv.style.display = 'block'; } return; } submitLogin.innerHTML = ' Directing...'; const params = new URLSearchParams(); params.append('action', 'login'); params.append('email', email); params.append('password', pass); fetch('auth_action.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params.toString() }) .then(res => { if (!res.ok) throw new Error('Network response was not ok'); return res.json(); }) .then(data => { if (data.success) { window.location.reload(); } else { submitLogin.innerHTML = ' Sign In'; if (errorDiv) { errorDiv.textContent = data.message; errorDiv.style.display = 'block'; } } }) .catch(err => { console.error('Login error:', err); submitLogin.innerHTML = ' Sign In'; if (errorDiv) { errorDiv.textContent = 'An error occurred. Please check your connection.'; errorDiv.style.display = 'block'; } }); }); } /* ── Registration logic ── */ const regSubmit = document.getElementById('registerSubmitBtn'); if (regSubmit) { regSubmit.addEventListener('click', function() { const name = document.getElementById('regName').value; const email = document.getElementById('regEmail').value; const pass = document.getElementById('regPassword').value; const errorDiv = document.getElementById('regError'); if (errorDiv) errorDiv.style.display = 'none'; if (!name || !email || !pass) { if (errorDiv) { errorDiv.textContent = 'Please fill out all fields.'; errorDiv.style.display = 'block'; } return; } regSubmit.innerHTML = ' Creating...'; const params = new URLSearchParams(); params.append('action', 'register'); params.append('full_name', name); params.append('email', email); params.append('password', pass); fetch('auth_action.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params.toString() }) .then(res => { if (!res.ok) throw new Error('Network response was not ok'); return res.json(); }) .then(data => { if (data.success) { // Show success message and login link const panel = document.getElementById('registerPanel'); if (panel) { panel.innerHTML = `
${data.message}