elegance-emporium / script.js
dodey917's picture
Make this code look good more: and add further and functional
1d550c4 verified
// 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