← back to Apartmentwallpaper

public/buybutton.js

71 lines

/* Apartment Wallpaper — on-site buying via the Shopify Buy Button SDK.
 * Customers add to cart + check out WITHOUT leaving apartmentwallpaper.com
 * (checkout opens in Shopify's secure hosted modal; never sends them to DW).
 *
 * Needs a Storefront access token — injected by the server as window.AW_CFG
 * ({domain, storefrontToken}). Until the token is set, Add-to-Cart hides and
 * the Sample flow remains the only CTA (graceful, never broken).
 */
(function () {
  var CFG = window.AW_CFG || {};
  if (!CFG.storefrontToken || !CFG.domain) {
    // No token yet — leave Sample-only. Mark body so CSS can hide .buy-btn.
    document.documentElement.classList.add('aw-no-buy');
    return;
  }
  var SDK = 'https://sdks.shopifycdn.com/buy-button/latest/buybutton.js';
  var client, ui, cartComp;

  function load(cb) {
    if (window.ShopifyBuy && window.ShopifyBuy.UI) return cb();
    var s = document.createElement('script');
    s.async = true; s.src = SDK; s.onload = cb;
    s.onerror = function () { document.documentElement.classList.add('aw-no-buy'); };
    document.head.appendChild(s);
  }

  function init() {
    client = window.ShopifyBuy.buildClient({ domain: CFG.domain, storefrontAccessToken: CFG.storefrontToken });
    ui = window.ShopifyBuy.UI.init(client);
    var mount = document.createElement('div'); mount.id = 'aw-cart'; document.body.appendChild(mount);
    ui.createComponent('cart', {
      node: mount,
      options: {
        cart: {
          startOpen: false,
          text: { title: 'Your Cart', button: 'Checkout', total: 'Subtotal', notice: 'Shipping & taxes calculated at checkout' },
          styles: { button: { 'background-color': '#1a1a1a', ':hover': { 'background-color': '#333' }, 'border-radius': '6px' } }
        },
        toggle: { styles: { toggle: { 'background-color': '#1a1a1a', ':hover': { 'background-color': '#333' } } } }
      }
    });
  }

  // Add the first non-sample variant of a Shopify product to the cart, open it.
  function addToCart(productId, btn) {
    if (!client) return;
    var orig = btn.textContent; btn.disabled = true; btn.textContent = 'Adding…';
    client.product.fetch(productId).then(function (product) {
      var v = (product.variants || []).filter(function (x) { return !/sample/i.test((x.title || '') + (x.sku || '')); });
      var variant = (v[0] || product.variants[0]);
      if (!variant) throw new Error('no variant');
      var cart = ui.components.cart[0];
      return cart.addVariantToCart(variant, 1).then(function () { cart.open(); });
    }).then(function () {
      btn.textContent = 'Added ✓'; setTimeout(function () { btn.disabled = false; btn.textContent = orig; }, 1800);
    }).catch(function () {
      btn.textContent = 'Sold out'; setTimeout(function () { btn.disabled = false; btn.textContent = orig; }, 1800);
    });
  }

  // Delegate clicks on any .buy-btn[data-pid] (cards + product modal).
  document.addEventListener('click', function (e) {
    var b = e.target.closest && e.target.closest('.buy-btn[data-pid]');
    if (!b) return;
    e.preventDefault(); e.stopPropagation();
    addToCart('gid://shopify/Product/' + b.getAttribute('data-pid'), b);
  });

  load(init);
})();