/** * Shopping Cart Component * Handles cart dropdown, updates, and interactions */ (function () { "use strict"; class ShoppingCart { constructor() { this.cartToggle = document.getElementById("cartToggle"); this.cartPanel = document.getElementById("cartPanel"); this.cartContent = document.getElementById("cartContent"); this.cartClose = document.getElementById("cartClose"); this.isOpen = false; this.init(); } init() { this.setupEventListeners(); this.render(); } setupEventListeners() { if (this.cartToggle) { this.cartToggle.addEventListener("click", () => this.toggle()); } if (this.cartClose) { this.cartClose.addEventListener("click", () => this.close()); } // Close when clicking outside document.addEventListener("click", (e) => { if (this.isOpen && !e.target.closest(".cart-dropdown-wrapper")) { this.close(); } }); // Listen for cart updates window.addEventListener("cart-updated", () => this.render()); } toggle() { this.isOpen ? this.close() : this.open(); } open() { if (this.cartPanel) { this.cartPanel.classList.add("active"); this.cartPanel.setAttribute("aria-hidden", "false"); this.isOpen = true; this.render(); } } close() { if (this.cartPanel) { this.cartPanel.classList.remove("active"); this.cartPanel.setAttribute("aria-hidden", "true"); this.isOpen = false; } } render() { if (!this.cartContent) return; const cart = window.AppState.cart; if (cart.length === 0) { this.cartContent.innerHTML = '

Your cart is empty

'; this.updateFooter(null); return; } const html = cart.map((item) => this.renderCartItem(item)).join(""); this.cartContent.innerHTML = html; // Add event listeners to cart items this.setupCartItemListeners(); // Update footer with total this.updateFooter(window.AppState.getCartTotal()); } renderCartItem(item) { const imageUrl = item.imageUrl || item.image_url || "/assets/images/placeholder.jpg"; const title = window.Utils.escapeHtml( item.title || item.name || "Product" ); const price = window.Utils.formatCurrency(item.price || 0); const subtotal = window.Utils.formatCurrency( (item.price || 0) * item.quantity ); return `
${title}

${title}

${price}

${item.quantity}

${subtotal}

`; } setupCartItemListeners() { // Remove buttons this.cartContent.querySelectorAll(".cart-item-remove").forEach((btn) => { btn.addEventListener("click", (e) => { const id = parseInt(e.currentTarget.dataset.id); window.AppState.removeFromCart(id); this.render(); }); }); // Quantity buttons this.cartContent.querySelectorAll(".quantity-minus").forEach((btn) => { btn.addEventListener("click", (e) => { const id = parseInt(e.currentTarget.dataset.id); const item = window.AppState.cart.find((item) => item.id === id); if (item && item.quantity > 1) { window.AppState.updateCartQuantity(id, item.quantity - 1); this.render(); } }); }); this.cartContent.querySelectorAll(".quantity-plus").forEach((btn) => { btn.addEventListener("click", (e) => { const id = parseInt(e.currentTarget.dataset.id); const item = window.AppState.cart.find((item) => item.id === id); if (item) { window.AppState.updateCartQuantity(id, item.quantity + 1); this.render(); } }); }); } updateFooter(total) { const footer = this.cartPanel?.querySelector(".dropdown-foot"); if (!footer) return; if (total === null) { footer.innerHTML = 'Continue Shopping'; } else { footer.innerHTML = `
Total: ${window.Utils.formatCurrency(total)}
Continue Shopping `; } } } // Wishlist Component class Wishlist { constructor() { this.wishlistToggle = document.getElementById("wishlistToggle"); this.wishlistPanel = document.getElementById("wishlistPanel"); this.wishlistContent = document.getElementById("wishlistContent"); this.wishlistClose = document.getElementById("wishlistClose"); this.isOpen = false; this.init(); } init() { this.setupEventListeners(); this.render(); } setupEventListeners() { if (this.wishlistToggle) { this.wishlistToggle.addEventListener("click", () => this.toggle()); } if (this.wishlistClose) { this.wishlistClose.addEventListener("click", () => this.close()); } // Close when clicking outside document.addEventListener("click", (e) => { if (this.isOpen && !e.target.closest(".wishlist-dropdown-wrapper")) { this.close(); } }); // Listen for wishlist updates window.addEventListener("wishlist-updated", () => this.render()); } toggle() { this.isOpen ? this.close() : this.open(); } open() { if (this.wishlistPanel) { this.wishlistPanel.classList.add("active"); this.wishlistPanel.setAttribute("aria-hidden", "false"); this.isOpen = true; this.render(); } } close() { if (this.wishlistPanel) { this.wishlistPanel.classList.remove("active"); this.wishlistPanel.setAttribute("aria-hidden", "true"); this.isOpen = false; } } render() { if (!this.wishlistContent) return; const wishlist = window.AppState.wishlist; if (wishlist.length === 0) { this.wishlistContent.innerHTML = '

Your wishlist is empty

'; return; } const html = wishlist .map((item) => this.renderWishlistItem(item)) .join(""); this.wishlistContent.innerHTML = html; // Add event listeners this.setupWishlistItemListeners(); } renderWishlistItem(item) { const imageUrl = item.imageUrl || item.image_url || "/assets/images/placeholder.jpg"; const title = window.Utils.escapeHtml( item.title || item.name || "Product" ); const price = window.Utils.formatCurrency(item.price || 0); return `
${title}

${title}

${price}

`; } setupWishlistItemListeners() { // Remove buttons this.wishlistContent .querySelectorAll(".wishlist-item-remove") .forEach((btn) => { btn.addEventListener("click", (e) => { const id = parseInt(e.currentTarget.dataset.id); window.AppState.removeFromWishlist(id); this.render(); }); }); // Add to cart buttons this.wishlistContent .querySelectorAll(".btn-add-to-cart") .forEach((btn) => { btn.addEventListener("click", (e) => { const id = parseInt(e.currentTarget.dataset.id); const item = window.AppState.wishlist.find( (item) => item.id === id ); if (item) { window.AppState.addToCart(item); } }); }); } } // Initialize when DOM is ready if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", () => { new ShoppingCart(); new Wishlist(); }); } else { new ShoppingCart(); new Wishlist(); } })();