Spaces:
Running
Running
| // Product Data | |
| const products = [ | |
| // Clothing Items | |
| { | |
| id: 1, | |
| name: "Silk Evening Gown", | |
| category: "clothing", | |
| price: 1299, | |
| originalPrice: 1599, | |
| image: "https://images.unsplash.com/photo-1594633312681-425c7b97ccd1?w=400&q=80", | |
| badge: "NEW", | |
| rating: 5, | |
| description: "Exquisite silk evening gown with intricate beadwork" | |
| }, | |
| { | |
| id: 2, | |
| name: "Cashmere Coat", | |
| category: "clothing", | |
| price: 899, | |
| originalPrice: 1199, | |
| image: "https://images.unsplash.com/photo-1551028719-00167b16eac5?w=400&q=80", | |
| badge: "SALE", | |
| rating: 4.5, | |
| description: "Luxurious 100% cashmere winter coat" | |
| }, | |
| { | |
| id: 3, | |
| name: "Designer Blazer", | |
| category: "clothing", | |
| price: 699, | |
| originalPrice: null, | |
| image: "https://images.unsplash.com/photo-1539533113208-f6df8cc8b543?w=400&q=80", | |
| badge: null, | |
| rating: 4, | |
| description: "Tailored wool blazer with gold buttons" | |
| }, | |
| { | |
| id: 4, | |
| name: "Lace Evening Dress", | |
| category: "clothing", | |
| price: 999, | |
| originalPrice: 1299, | |
| image: "https://images.unsplash.com/photo-1596755094514-f87e34085b2c?w=400&q=80", | |
| badge: "NEW", | |
| rating: 5, | |
| description: "Elegant lace dress perfect for formal occasions" | |
| }, | |
| { | |
| id: 5, | |
| name: "Silk Blouse", | |
| category: "clothing", | |
| price: 449, | |
| originalPrice: null, | |
| image: "https://images.unsplash.com/photo-1583743814966-8936f5b7be1a?w=400&q=80", | |
| badge: null, | |
| rating: 4.5, | |
| description: "Classic silk blouse with French cuffs" | |
| }, | |
| // Bedding Items | |
| { | |
| id: 6, | |
| name: "Egyptian Cotton Set", | |
| category: "bedding", | |
| price: 599, | |
| originalPrice: 799, | |
| image: "https://images.unsplash.com/photo-1586023492125-27b2c045efd7?w=400&q=80", | |
| badge: "BESTSELLER", | |
| rating: 5, | |
| description: "1000 thread count Egyptian cotton bedding set" | |
| }, | |
| { | |
| id: 7, | |
| name: "Silk Duvet Cover", | |
| category: "bedding", | |
| price: 449, | |
| originalPrice: null, | |
| image: "https://images.unsplash.com/photo-1615874959474-d609969a20ed?w=400&q=80", | |
| badge: "NEW", | |
| rating: 4.5, | |
| description: "Luxurious 100% mulberry silk duvet cover" | |
| }, | |
| { | |
| id: 8, | |
| name: "Luxury Throw Pillows", | |
| category: "bedding", | |
| price: 199, | |
| originalPrice: 249, | |
| image: "https://images.unsplash.com/photo-1595526114035-0d45ed16cfbf?w=400&q=80", | |
| badge: null, | |
| rating: 4, | |
| description: "Set of 2 decorative throw pillows with gold embroidery" | |
| }, | |
| { | |
| id: 9, | |
| name: "Premium Comforter", | |
| category: "bedding", | |
| price: 799, | |
| originalPrice: null, | |
| image: "https://images.unsplash.com/photo-1560448204-e02f11c3d0e2?w=400&q=80", | |
| badge: null, | |
| rating: 5, | |
| description: "Hypoallergenic down alternative comforter" | |
| }, | |
| { | |
| id: 10, | |
| name: "Bamboo Sheet Set", | |
| category: "bedding", | |
| price: 349, | |
| originalPrice: 449, | |
| image: "https://images.unsplash.com/photo-1616627561950-6d7e08b38c0a?w=400&q=80", | |
| badge: "ECO", | |
| rating: 4.5, | |
| description: "Sustainable bamboo fiber sheet set" | |
| } | |
| ]; | |
| // Cart State | |
| let cart = JSON.parse(localStorage.getItem('cart')) || []; | |
| let wishlist = JSON.parse(localStorage.getItem('wishlist')) || []; | |
| // Initialize | |
| document.addEventListener('DOMContentLoaded', function() { | |
| feather.replace(); | |
| renderProducts('all'); | |
| updateCartBadge(); | |
| setupEventListeners(); | |
| // Hide loading screen | |
| setTimeout(() => { | |
| document.querySelector('.loading-screen').classList.add('hidden'); | |
| }, 1000); | |
| }); | |
| // Setup Event Listeners | |
| function setupEventListeners() { | |
| // Back to top button | |
| const backToTop = document.getElementById('backToTop'); | |
| window.addEventListener('scroll', () => { | |
| if (window.scrollY > 500) { | |
| backToTop.classList.remove('opacity-0', 'invisible'); | |
| backToTop.classList.add('opacity-100', 'visible'); | |
| } else { | |
| backToTop.classList.add('opacity-0', 'invisible'); | |
| backToTop.classList.remove('opacity-100', 'visible'); | |
| } | |
| }); | |
| } | |
| // Render Products | |
| function renderProducts(category) { | |
| const grid = document.getElementById('products-grid'); | |
| const filteredProducts = category === 'all' | |
| ? products | |
| : category === 'new' | |
| ? products.filter(p => p.badge === 'NEW') | |
| : products.filter(p => p.category === category); | |
| grid.innerHTML = filteredProducts.map(product => ` | |
| <div class="product-card" data-id="${product.id}"> | |
| <div class="product-image-wrapper"> | |
| <img src="${product.image}" alt="${product.name}" class="product-image"> | |
| ${product.badge ? `<span class="product-badge">${product.badge}</span>` : ''} | |
| <button onclick="toggleWishlist(${product.id})" class="wishlist-btn ${wishlist.includes(product.id) ? 'active' : ''}"> | |
| <i data-feather="heart" class="w-5 h-5"></i> | |
| </button> | |
| <div class="product-overlay"> | |
| <div class="product-actions"> | |
| <button onclick="quickView(${product.id})" class="action-btn"> | |
| <i data-feather="eye" class="w-4 h-4 inline mr-1"></i> Quick View | |
| </button> | |
| <button onclick="addToCart(${product.id})" class="action-btn"> | |
| <i data-feather="shopping-cart" class="w-4 h-4 inline mr-1"></i> Add to Cart | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="product-info"> | |
| <h3 class="product-name">${product.name}</h3> | |
| <div class="product-rating"> | |
| ${generateStars(product.rating)} | |
| <span class="text-sm text-gray-500 ml-2">(${product.rating})</span> | |
| </div> | |
| <div class="product-price"> | |
| $${product.price} | |
| ${product.originalPrice ? `<span class="product-original-price">$${product.originalPrice}</span>` : ''} | |
| </div> | |
| </div> | |
| </div> | |
| `).join(''); | |
| feather.replace(); | |
| } | |
| // Generate Star Rating | |
| function generateStars(rating) { | |
| let stars = ''; | |
| for (let i = 1; i <= 5; i++) { | |
| if (i <= Math.floor(rating)) { | |
| stars += '<i data-feather="star" class="star fill-current"></i>'; | |
| } else if (i - 0.5 <= rating) { | |
| stars += '<i data-feather="star" class="star fill-current opacity-50"></i>'; | |
| } else { | |
| stars += '<i data-feather="star" class="star opacity-30"></i>'; | |
| } | |
| } | |
| return stars; | |
| } | |
| // Filter Products | |
| function filterProducts(category) { | |
| // Update active button | |
| document.querySelectorAll('.filter-btn').forEach(btn => { | |
| btn.classList.remove('active', 'bg-amber-500', 'text-white', 'border-amber-500'); | |
| btn.classList.add('border-gray-300', 'text-gray-600'); | |
| }); | |
| event.target.classList.add('active', 'bg-amber-500', 'text-white', 'border-amber-500'); | |
| event.target.classList.remove('border-gray-300', 'text-gray-600'); | |
| renderProducts(category); | |
| } | |
| // Cart Functions | |
| function addToCart(productId) { | |
| const product = products.find(p => p.id === productId); | |
| const existingItem = cart.find(item => item.id === productId); | |
| if (existingItem) { | |
| existingItem.quantity++; | |
| } else { | |
| cart.push({ ...product, quantity: 1 }); | |
| } | |
| localStorage.setItem('cart', JSON.stringify(cart)); | |
| updateCartBadge(); | |
| showNotification('Product added to cart!', 'success'); | |
| openCartSidebar(); | |
| } | |
| function removeFromCart(productId) { | |
| cart = cart.filter(item => item.id !== productId); | |
| localStorage.setItem('cart', JSON.stringify(cart)); | |
| updateCartBadge(); | |
| renderCart(); | |
| } | |
| function updateQuantity(productId, change) { | |
| const item = cart.find(item => item.id === productId); | |
| if (item) { | |
| item.quantity += change; | |
| if (item.quantity <= 0) { | |
| removeFromCart(productId); | |
| } else { | |
| localStorage.setItem('cart', JSON.stringify(cart)); | |
| renderCart(); | |
| } | |
| } | |
| } | |
| function updateCartBadge() { | |
| const totalItems = cart.reduce((sum, item) => sum + item.quantity, 0); | |
| const badge = document.querySelector('.cart-badge'); | |
| if (badge) { | |
| badge.textContent = totalItems; | |
| badge.style.display = totalItems > 0 ? 'flex' : 'none'; | |
| } | |
| } | |
| // Wishlist Functions | |
| function toggleWishlist(productId) { | |
| const index = wishlist.indexOf(productId); | |
| if (index > -1) { | |
| wishlist.splice(index, 1); | |
| showNotification('Removed from wishlist', 'info'); | |
| } else { | |
| wishlist.push(productId); | |
| showNotification('Added to wishlist!', 'success'); | |
| } | |
| localStorage.setItem('wishlist', JSON.stringify(wishlist)); | |
| // Update button state | |
| const btn = event.target.closest('.wishlist-btn'); | |
| btn.classList.toggle('active'); | |
| } | |
| // Quick View | |
| function quickView(productId) { | |
| const product = products.find(p => p.id === productId); | |
| const modal = document.querySelector('.quick-view-modal'); | |
| const content = modal.querySelector('.quick-view-content'); | |
| content.innerHTML = ` | |
| <div class="bg-white rounded-2xl max-w-4xl w-full max-h-[90vh] overflow-y-auto"> | |
| <div class="grid grid-cols-1 md:grid-cols-2"> | |
| <div class="relative"> | |
| <img src="${product.image}" alt="${product.name}" class="w-full h-full object-cover rounded-tl-2xl rounded-bl-2xl"> | |
| ${product.badge ? `<span class="absolute top-4 right-4 px-3 py-1 bg-amber-500 text-white text-xs font-semibold tracking-wider rounded-full">${product.badge}</span>` : ''} | |
| </div> | |
| <div class="p-8"> | |
| <h2 class="text-3xl font-serif mb-4">${product.name}</h2> | |
| <div class="product-rating mb-4"> | |
| ${generateStars(product.rating)} | |
| <span class="text-sm text-gray-500 ml-2">(${product.rating} ratings)</span> | |
| </div> | |
| <p class="text-gray-600 mb-6">${product.description}</p> | |
| <div class="flex items-center gap-4 mb-6"> | |
| <span class="text-3xl font-semibold text-amber-600">$${product.price}</span> | |
| ${product.originalPrice ? `<span class="text-xl text-gray-400 line-through">$${product.originalPrice}</span>` : ''} | |
| </div> | |
| <div class="mb-6"> | |
| <label class="block text-sm font-medium mb-2">Quantity</label> | |
| <div class="flex items-center gap-3"> | |
| <button onclick="updateQuantityInput(-1)" class="w-10 h-10 border border-gray-300 rounded-lg hover:bg-gray-100">-</button> | |
| <input type="number" id="quickViewQuantity" value="1" min="1" class="w-20 text-center border border-gray-300 rounded-lg"> | |
| <button onclick="updateQuantityInput(1)" class="w-10 h-10 border border-gray-300 rounded-lg hover:bg-gray-100">+</button> | |
| </div> | |
| </div> | |
| <div class="flex gap-4"> | |
| <button onclick="addToCartFromQuickView(${product.id})" class="flex-1 px-6 py-3 bg-amber-500 text-white font-medium rounded-lg hover:bg-amber-600 transition-colors"> | |
| Add to Cart | |
| </button> | |
| <button onclick="toggleWishlist(${product.id}); closeQuickView();" class="px-6 py-3 border border-gray-300 rounded-lg hover:bg-gray-100 transition-colors"> | |
| <i data-feather="heart" class="w-5 h-5"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <button onclick="closeQuickView()" class="absolute top-4 right-4 w-10 h-10 bg-white rounded-full flex items-center justify-center hover:bg-gray-100"> | |
| <i data-feather="x" class="w-5 h-5"></i> | |
| </button> | |
| </div> | |
| `; | |
| modal.classList.add('active'); | |
| feather.replace(); | |
| } | |
| function updateQuantityInput(change) { | |
| const input = document.getElementById('quickViewQuantity'); | |
| const newValue = parseInt(input.value) + change; | |
| if (newValue >= 1) { | |
| input.value = newValue; | |
| } | |
| } | |
| function addToCartFromQuickView(productId) { | |
| const quantity = parseInt(document.getElementById('quickViewQuantity').value); | |
| const product = products.find(p => p.id === productId); | |
| const existingItem = cart.find(item => item.id === productId); | |
| if (existingItem) { | |
| existingItem.quantity += quantity; | |
| } else { | |
| cart.push({ ...product, quantity }); | |
| } | |
| localStorage.setItem('cart', JSON.stringify(cart)); | |
| updateCartBadge(); | |
| closeQuickView(); | |
| showNotification('Product added to cart!', 'success'); | |
| openCartSidebar(); | |
| } | |
| function closeQuickView() { | |
| document.querySelector('.quick-view-modal').classList.remove('active'); | |
| } | |
| // Cart Sidebar | |
| function openCartSidebar() { | |
| document.querySelector('.cart-sidebar').classList.add('active'); | |
| document.querySelector('.cart-overlay').classList.add('active'); | |
| renderCart(); | |
| } | |
| function closeCartSidebar() { | |
| document.querySelector('.cart-sidebar').classList.remove('active'); | |
| document.querySelector('.cart-overlay').classList.remove('active'); | |
| } | |
| function renderCart() { | |
| const cartItems = document.querySelector('.cart-items'); | |
| const cartTotal = document.querySelector('.cart-total'); | |
| if (cart.length === 0) { | |
| cartItems.innerHTML = ` | |
| <div class="text-center py-12"> | |
| <i data-feather="shopping-cart" class="w-16 h-16 mx-auto text-gray-300 mb-4"></i> | |
| <p class="text-gray-500">Your cart is empty</p> | |
| </div> | |
| `; | |
| } else { | |
| cartItems.innerHTML = cart.map(item => ` | |
| <div class="flex gap-4 py-4 border-b"> | |
| <img src="${item.image}" alt="${item.name}" class="w-20 h-20 object-cover rounded-lg"> | |
| <div class="flex-1"> | |
| <h4 class="font-medium">${item.name}</h4> | |
| <p class="text-amber-600 font-semibold">$${item.price}</p> | |
| <div class="flex items-center gap-2 mt-2"> | |
| <button onclick="updateQuantity(${item.id}, -1)" class="w-8 h-8 border rounded hover:bg-gray-100">-</button> | |
| <span class="w-12 text-center">${item.quantity}</span> | |
| <button onclick="updateQuantity(${item.id}, 1)" class="w-8 h-8 border rounded hover:bg-gray-100">+</button> | |
| </div> | |
| </div> | |
| <button onclick="removeFromCart(${item.id})" class="text-gray-400 hover:text-red-500"> | |
| <i data-feather="trash-2" class="w-5 h-5"></i> | |
| </button> | |
| </div> | |
| `).join(''); | |
| } | |
| const total = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0); | |
| cartTotal.innerHTML = ` | |
| <div class="border-t pt-4"> | |
| <div class="flex justify-between mb-2"> | |
| <span |