Skip to Content
/** ========================================= * Wishlist Handler (Persistent Heart State) * ========================================= */ (function () { 'use strict'; const STORAGE_KEY = 'odoo_wishlist_products'; /* ----------------------------- Helpers ----------------------------- */ function getStoredWishlist() { try { return JSON.parse(localStorage.getItem(STORAGE_KEY)) || []; } catch (e) { return []; } } function storeWishlist(list) { localStorage.setItem(STORAGE_KEY, JSON.stringify(list)); } function isInWishlist(productId) { return getStoredWishlist().includes(productId); } function addToWishlist(productId) { const list = getStoredWishlist(); if (!list.includes(productId)) { list.push(productId); storeWishlist(list); } } function removeFromWishlist(productId) { const list = getStoredWishlist().filter(id => id !== productId); storeWishlist(list); } function updateHeartUI(productId, active) { document.querySelectorAll( `.js-wishlist-toggle[data-product-id="${productId}"]` ).forEach(btn => { btn.classList.toggle('is-active', active); }); } /* ----------------------------- Sync UI on page load ----------------------------- */ function syncWishlistUI() { const list = getStoredWishlist(); list.forEach(productId => { updateHeartUI(productId, true); }); } /* ----------------------------- Wishlist Toggle ----------------------------- */ async function toggleWishlist(btn) { const productId = parseInt(btn.dataset.productId, 10); if (!productId) return; const active = btn.classList.contains('is-active'); try { if (active) { await fetch('/shop/wishlist/remove', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest', }, body: JSON.stringify({ product_id: productId }), }); removeFromWishlist(productId); updateHeartUI(productId, false); } else { await fetch('/shop/wishlist/add', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest', }, body: JSON.stringify({ product_id: productId }), }); addToWishlist(productId); updateHeartUI(productId, true); } } catch (err) { console.error('Wishlist error:', err); } } /* ----------------------------- Event Binding ----------------------------- */ function bindWishlistEvents() { document.body.addEventListener('click', function (e) { const btn = e.target.closest('.js-wishlist-toggle'); if (!btn) return; e.preventDefault(); toggleWishlist(btn); }); } /* ----------------------------- Init ----------------------------- */ document.addEventListener('DOMContentLoaded', function () { syncWishlistUI(); bindWishlistEvents(); }); })();