document.addEventListener('DOMContentLoaded', () => { const productGrid = document.getElementById('product-grid'); const loader = document.getElementById('loader'); let products = []; // Cart State let cartCount = 0; // --- Event Listeners for Filters --- document.getElementById('filter-all').addEventListener('click', () => filterProducts('all')); document.getElementById('filter-tech').addEventListener('click', () => filterProducts('tech')); document.getElementById('filter-design').addEventListener('click', () => filterProducts('design')); // --- Function: Fetch Data --- async function loadProducts() { // Show Loader loader.style.display = 'flex'; productGrid.innerHTML = ''; try { // Attempt to fetch from local data.json file const response = await fetch('data.json'); if (!response.ok) throw new Error("HTTP error"); products = await response.json(); } catch (error) { console.warn('Could not load data.json (likely due to CORS on local file system). Using fallback data.', error); // Fallback Data if JSON fetch fails products = [ { id: 1, name: "Wireless Headphones", price: 299, category: "tech", image: "http://static.photos/technology/640x360/1", rating: 4.8 }, { id: 2, name: "Mechanical Keyboard", price: 149, category: "tech", image: "http://static.photos/workspace/640x360/2", rating: 4.7 }, { id: 3, name: "Modern Lamp", price: 89, category: "design", image: "http://static.photos/interior/640x360/3", rating: 4.5 }, { id: 4, name: "Smart Watch", price: 399, category: "tech", image: "http://static.photos/technology/640x360/6", rating: 4.6 } ]; } finally { // Hide Loader loader.style.display = 'none'; renderProducts(products); } } // --- Function: Render Products --- function renderProducts(items) { productGrid.innerHTML = ''; items.forEach(product => { const card = document.createElement('shop-card'); // Set attributes for the web component card.setAttribute('name', product.name); card.setAttribute('price', product.price); card.setAttribute('category', product.category); card.setAttribute('image', product.image); card.setAttribute('rating', product.rating); productGrid.appendChild(card); }); } // --- Function: Filter Products --- function filterProducts(category) { // Update active button styles const buttons = document.querySelectorAll('button[id^="filter-"]'); buttons.forEach(btn => { if (btn.id === `filter-${category}`) { btn.classList.remove('bg-white', 'text-gray-600'); btn.classList.add('bg-primary', 'text-white'); } else { btn.classList.remove('bg-primary', 'text-white'); btn.classList.add('bg-white', 'text-gray-600'); } }); if (category === 'all') { renderProducts(products); } else { const filtered = products.filter(p => p.category === category); renderProducts(filtered); } } // --- Global Event Listener: Add to Cart --- // We listen for a custom event dispatched from inside the Shadow DOM of the Web Component window.addEventListener('add-to-cart', (e) => { cartCount++; updateCartDisplay(); showToast(`Added ${e.detail.productName} to cart!`); }); // --- Global Event Listener: Remove Product --- window.addEventListener('remove-product', (e) => { const card = e.detail.element; card.style.opacity = '0'; card.style.transform = 'scale(0.9)'; setTimeout(() => { card.remove(); }, 300); showToast('Product removed.'); }); function updateCartDisplay() { // We dispatch an event to the navbar since we can't easily access its shadow DOM internals directly window.dispatchEvent(new CustomEvent('update-cart-count', { detail: { count: cartCount } })); } // --- Function: Show Toast Notification --- function showToast(message) { const container = document.getElementById('toast-container'); const toast = document.createElement('div'); toast.className = 'toast-enter bg-dark text-white px-6 py-3 rounded-lg shadow-xl flex items-center gap-3'; toast.innerHTML = ` ${message} `; container.appendChild(toast); feather.replace(); // Refresh icons in new element // Remove after 3 seconds setTimeout(() => { toast.classList.remove('toast-enter'); toast.classList.add('toast-exit'); setTimeout(() => { toast.remove(); }, 300); }, 3000); } // Initialize loadProducts(); });