Flyer

3.7 ( 3  Reviews )
$24.00
×
/** * FREE GIFT AUTOMATION — Waytoplay Toys * Automatically adds the Flyer (free gift) when cart reaches €75, * and removes it when the cart drops below €75. * * Works alongside the existing "Happy Holidays!" Buy X Get Y discount * which handles the price reduction at checkout. * * Theme: Showcase * Free gift: Flyer (variant ID 48114081399130) * Threshold: €75.00 */ (function () { const FREE_GIFT_VARIANT_ID = 48114081399130; const THRESHOLD_CENTS = 7500; // €75.00 const GIFT_PROPERTY_KEY = '_free_gift'; const GIFT_PROPERTY_VALUE = 'happy-holidays'; let isEvaluating = false; // ── Helpers ──────────────────────────────────────────────────────────────── async function fetchCart() { const res = await fetch('/cart.js'); return res.json(); } async function addGift() { await fetch('/cart/add.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: FREE_GIFT_VARIANT_ID, quantity: 1, properties: { [GIFT_PROPERTY_KEY]: GIFT_PROPERTY_VALUE }, }), }); } async function removeGift() { // Find the specific line number of the gift (1-based index in Shopify) const cart = await fetchCart(); const lineIdx = cart.items.findIndex(isGiftItem); if (lineIdx === -1) return; await fetch('/cart/change.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ line: lineIdx + 1, quantity: 0 }), }); } function isGiftItem(item) { return ( item.variant_id === FREE_GIFT_VARIANT_ID && item.properties && item.properties[GIFT_PROPERTY_KEY] === GIFT_PROPERTY_VALUE ); } /** * Subtotal excluding the gift itself, so its price doesn't affect * the threshold calculation. */ function subtotalWithoutGift(cart) { return cart.items.reduce((sum, item) => { return isGiftItem(item) ? sum : sum + item.line_price; }, 0); } // ── Refresh the Showcase cart drawer ────────────────────────────────────── function refreshCart() { // Showcase theme uses a custom element / event-based cart drawer. // Try the most common event names used by Showcase and similar themes: document.dispatchEvent(new CustomEvent('cart:refresh')); document.dispatchEvent(new CustomEvent('theme:cart:update')); // Also dispatch on window for themes that listen there: window.dispatchEvent(new CustomEvent('cart:refresh')); // Re-fetch and update the cart count badge if the theme exposes it: fetch('/cart.js') .then(r => r.json()) .then(cart => { // Update any cart count elements the theme renders document.querySelectorAll('[data-cart-count], .cart-count, .js-cart-count').forEach(el => { el.textContent = cart.item_count; }); }) .catch(() => {}); } // ── Core logic ───────────────────────────────────────────────────────────── async function evaluateGift() { if (isEvaluating) return; isEvaluating = true; try { const cart = await fetchCart(); const subtotal = subtotalWithoutGift(cart); const giftInCart = cart.items.some(isGiftItem); const qualifies = subtotal >= THRESHOLD_CENTS; if (qualifies && !giftInCart) { await addGift(); refreshCart(); } else if (!qualifies && giftInCart) { await removeGift(); refreshCart(); } } catch (e) { console.warn('[FreeGift]', e); } finally { isEvaluating = false; } } // ── Intercept cart mutations ─────────────────────────────────────────────── const _origFetch = window.fetch; window.fetch = async function (...args) { const url = typeof args[0] === 'string' ? args[0] : (args[0]?.url ?? ''); const isCartMutation = /\/cart\/(add|change|update)\.js/.test(url); const response = await _origFetch.apply(this, args); if (isCartMutation) { // Wait a tick so the cart has settled before we evaluate response.clone().json().then(() => { setTimeout(evaluateGift, 300); }).catch(() => {}); } return response; }; // ── Check on page load ──────────────────────────────────────────────────── document.addEventListener('DOMContentLoaded', evaluateGift); })();