/** * Cart Store * Manages shopping cart state with localStorage persistence * Dispatches 'cart-updated' events when cart changes */ const CART_STORAGE_KEY = "milinda-cart"; class CartStore { constructor() { this.items = this.loadFromStorage(); } /** * Load cart from localStorage */ loadFromStorage() { try { const stored = localStorage.getItem(CART_STORAGE_KEY); return stored ? JSON.parse(stored) : []; } catch (e) { console.error("Failed to load cart from storage:", e); return []; } } /** * Save cart to localStorage */ saveToStorage() { try { localStorage.setItem(CART_STORAGE_KEY, JSON.stringify(this.items)); } catch (e) { console.error("Failed to save cart to storage:", e); } } /** * Dispatch cart-updated event */ notifyUpdate() { window.dispatchEvent( new CustomEvent("cart-updated", { detail: { items: this.items, count: this.getItemCount(), total: this.getTotal(), }, }) ); } /** * Add item to cart * @param {Object} item - Item to add { title, author, price, type, image } */ addItem(item) { // Check if item already exists (by title and type) const existingIndex = this.items.findIndex( (i) => i.title === item.title && i.type === item.type ); if (existingIndex >= 0) { // Increment quantity this.items[existingIndex].quantity += 1; } else { // Add new item this.items.push({ ...item, quantity: 1, addedAt: Date.now(), }); } this.saveToStorage(); this.notifyUpdate(); return this.items; } /** * Remove item from cart * @param {number} index - Index of item to remove */ removeItem(index) { if (index >= 0 && index < this.items.length) { this.items.splice(index, 1); this.saveToStorage(); this.notifyUpdate(); } return this.items; } /** * Update item quantity * @param {number} index - Index of item * @param {number} quantity - New quantity */ updateQuantity(index, quantity) { if (index >= 0 && index < this.items.length) { if (quantity <= 0) { this.removeItem(index); } else { this.items[index].quantity = quantity; this.saveToStorage(); this.notifyUpdate(); } } return this.items; } /** * Clear all items from cart */ clear() { this.items = []; this.saveToStorage(); this.notifyUpdate(); return this.items; } /** * Get all items */ getItems() { return this.items; } /** * Get total item count (sum of quantities) */ getItemCount() { return this.items.reduce((sum, item) => sum + item.quantity, 0); } /** * Get cart total price */ getTotal() { return this.items.reduce((sum, item) => { // Parse price like "€ 24,95" to number const priceStr = item.price || "0"; const price = parseFloat( priceStr.replace(/[€$£\s]/g, "").replace(",", ".") ); return sum + price * item.quantity; }, 0); } } // Create singleton instance const cart = new CartStore(); // Export for module use export default cart; // Also attach to window for global access window.cartStore = cart;