/** * Cart Drawer Component * Manages the cart sidebar with add/remove/update functionality */ (function() { const drawer = document.getElementById('cart-drawer'); const emptyState = document.querySelector('[data-cart-empty]'); const itemsContainer = document.querySelector('[data-cart-items]'); const checkoutBtn = document.querySelector('[data-cart-checkout]'); const closeButtons = document.querySelectorAll('[data-cart-close]'); const totalDisplay = document.querySelector('[data-cart-total]'); const headerCartBtn = document.querySelector('[data-cart-open]'); const headerCartCount = document.querySelector('[data-cart-count]'); // Get translated text const removeText = drawer.dataset.textRemove || 'Remove'; let currentCart = null; let cartInstance = null; // Wait for ShopifyCart to be available function initCartDrawer() { if (typeof ShopifyCart === 'undefined') { setTimeout(initCartDrawer, 100); return; } cartInstance = new ShopifyCart({ domain: 'nv7cqv-bu.myshopify.com', storefrontAccessToken: 'dec3d35a2554384d149c72927d1cfd1b' }); // Initialize event listeners setupEventListeners(); } function setupEventListeners() { // Close drawer closeButtons.forEach(btn => { btn.addEventListener('click', closeDrawer); }); // Open drawer from header button if (headerCartBtn) { headerCartBtn.addEventListener('click', openDrawer); } // Checkout button checkoutBtn.addEventListener('click', () => { if (currentCart?.checkoutUrl) { window.location.href = currentCart.checkoutUrl; } }); // Listen for custom cart update events document.addEventListener('cart:updated', (e) => { currentCart = e.detail.cart; renderCart(); openDrawer(); }); } function openDrawer() { drawer.classList.add('is-open'); document.body.style.overflow = 'hidden'; } function closeDrawer() { drawer.classList.remove('is-open'); document.body.style.overflow = ''; } function calculateTotal() { if (!currentCart || !currentCart.lines) return 0; return currentCart.lines.edges.reduce((total, edge) => { const item = edge.node; const price = parseFloat(item.merchandise.price.amount); const quantity = item.quantity; return total + (price * quantity); }, 0); } function formatPrice(amount, currency = 'EUR') { return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: currency }).format(amount); } function updateCartCount() { if (!currentCart || !currentCart.lines || currentCart.lines.edges.length === 0) { if (headerCartCount) { headerCartCount.textContent = ''; } return; } // Calculate total quantity const totalQty = currentCart.lines.edges.reduce((sum, edge) => { return sum + edge.node.quantity; }, 0); if (headerCartCount) { headerCartCount.textContent = totalQty > 0 ? totalQty : ''; } } function renderCart() { if (!currentCart || !currentCart.lines || currentCart.lines.edges.length === 0) { emptyState.classList.remove('hidden'); itemsContainer.classList.add('hidden'); checkoutBtn.disabled = true; if (totalDisplay) { totalDisplay.textContent = '0,00 €'; } updateCartCount(); return; } emptyState.classList.add('hidden'); itemsContainer.classList.remove('hidden'); checkoutBtn.disabled = false; // Calculate and display total const total = calculateTotal(); const currency = currentCart.lines.edges[0]?.node.merchandise.price.currencyCode || 'EUR'; if (totalDisplay) { totalDisplay.textContent = formatPrice(total, currency); } // Update header cart count updateCartCount(); // Render cart items itemsContainer.innerHTML = currentCart.lines.edges.map(edge => { const item = edge.node; const merchandise = item.merchandise; return `

${merchandise.product.title}

${merchandise.title !== 'Default Title' ? `

${merchandise.title}

` : ''}

${formatPrice(parseFloat(merchandise.price.amount), merchandise.price.currencyCode)}

${item.quantity}
`; }).join(''); // Attach event listeners to quantity buttons attachQuantityListeners(); } function attachQuantityListeners() { const buttons = itemsContainer.querySelectorAll('[data-action]'); buttons.forEach(btn => { btn.addEventListener('click', async (e) => { const action = e.target.dataset.action; const lineId = e.target.dataset.lineId; await handleQuantityChange(action, lineId); }); }); } async function handleQuantityChange(action, lineId) { if (!cartInstance || !currentCart) return; // Find the line item const line = currentCart.lines.edges.find(edge => edge.node.id === lineId); if (!line) return; const currentQty = line.node.quantity; let newQty = currentQty; if (action === 'increase') { newQty = currentQty + 1; } else if (action === 'decrease') { newQty = Math.max(0, currentQty - 1); } else if (action === 'remove') { newQty = 0; } // Update cart via API try { itemsContainer.classList.add('is-loading'); const query = ` mutation cartLinesUpdate($cartId: ID!, $lines: [CartLineUpdateInput!]!) { cartLinesUpdate(cartId: $cartId, lines: $lines) { cart { id checkoutUrl lines(first: 10) { edges { node { id quantity merchandise { ... on ProductVariant { id title price { amount currencyCode } product { title } } } } } } } userErrors { field message } } } `; const data = await cartInstance.query(query, { cartId: currentCart.id, lines: [{ id: lineId, quantity: newQty }] }); if (data.cartLinesUpdate.userErrors.length > 0) { throw new Error(data.cartLinesUpdate.userErrors[0].message); } currentCart = data.cartLinesUpdate.cart; renderCart(); } catch (error) { console.error('Error updating cart:', error); alert('Erreur lors de la mise à jour du panier'); } finally { itemsContainer.classList.remove('is-loading'); } } // Public API window.CartDrawer = { open: openDrawer, close: closeDrawer, updateCart: (cart) => { currentCart = cart; renderCart(); } }; // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initCartDrawer); } else { initCartDrawer(); } })();