/** * Build Your Box - Final Version (Exclusive Subscription) * - Tiered discount: ₹700+ → 30%, ₹1200+ → 33% * - Duplicate SKUs allowed (quantity model); "ADD MORE" once in box * - Monthly-first pricing; "How It Works" onboarding; "Add to My Box" * - Direct isolated checkout; charges full 6 months (checkoutMultiplier = months) */ class BuildYourBox { constructor() { this.section = document.querySelector('.build-your-box-section'); if (!this.section) return; this.sectionId = this.section.dataset.sectionId; this.discountPercent = parseInt(this.section.dataset.discount) || 0; this.minSubtotal = 70000; // ₹700 in cents (raw MONTHLY MRP) this.months = 6; this.daysPerMonth = 30; this.checkoutMultiplier = this.months; this.checkoutBtn = this.section.querySelector('.byb-checkout-btn'); this.totalPriceEl = this.section.querySelector('[data-total-price]'); this.savingsEl = this.section.querySelector('[data-savings]'); this.savingsContainer = this.section.querySelector('.byb-savings'); this.stickyFooter = this.section.querySelector('.byb-sticky-footer'); this.sixMonthTotalEl = null; this.tierHintEl = null; this.monthlyLeadEl = null; this.perDayEl = null; this.selectedProducts = []; this.init(); } init() { this.ensureHowItWorks(); this.renameMonthlyTotalLabel(); this.ensureMonthlyLead(); this.ensureTierHintLine(); this.ensureSixMonthLine(); this.ensurePerDayLine(); this.interceptAddToCart(); this.bindEvents(); this.updateUI(); this.initStickyFooter(); } getSubtotal() { return this.selectedProducts.reduce((sum, p) => sum + p.productPrice * p.qty, 0); } getCount() { return this.selectedProducts.reduce((sum, p) => sum + p.qty, 0); } getQtyForProduct(productId) { return this.selectedProducts .filter(p => p.productId === productId) .reduce((sum, p) => sum + p.qty, 0); } ensureHowItWorks() { if (this.section.querySelector('.byb-how-it-works')) return; const anchor = this.section.querySelector('.byb-subheading-wrapper') || this.section.querySelector('.hometitle'); if (!anchor) return; const steps = [ { n: '1', t: 'Pick your products', d: 'Choose your favourites below' }, { n: '2', t: 'Reach ₹700/month', d: 'Unlock 30% off (₹1200+ for 33%)' }, { n: '3', t: 'Order once', d: 'Get a 6-month subscription box' }, { n: '4', t: 'Save every month', d: 'Up to 33% vs buying normally' } ]; const wrap = document.createElement('div'); wrap.className = 'byb-how-it-works'; wrap.innerHTML = '
How it works
' + '
' + steps.map(s => '
' + s.n + '' + '
' + s.t + '' + s.d + '
' ).join('') + '
'; anchor.insertAdjacentElement('afterend', wrap); } renameMonthlyTotalLabel() { const monthlyLine = this.section.querySelector('.byb-total'); if (!monthlyLine) return; const label = monthlyLine.querySelector('.byb-total-label'); if (label) label.textContent = 'MONTHLY TOTAL'; } ensureMonthlyLead() { if (this.monthlyLeadEl) return; const summaryLeft = this.section.querySelector('.byb-summary-left'); if (!summaryLeft) return; const lead = document.createElement('div'); lead.className = 'byb-monthly-lead'; lead.innerHTML = 'Only ' + '' + this.formatMoney(0) + '' + '/month'; summaryLeft.insertAdjacentElement('afterbegin', lead); this.monthlyLeadEl = lead; } ensureTierHintLine() { if (this.tierHintEl) return; const monthlyLine = this.section.querySelector('.byb-total'); if (!monthlyLine) return; const hint = document.createElement('div'); hint.className = 'byb-tier-hint'; monthlyLine.insertAdjacentElement('afterend', hint); this.tierHintEl = hint; } ensureSixMonthLine() { if (this.sixMonthTotalEl) return; const anchor = this.tierHintEl || this.section.querySelector('.byb-total'); if (!anchor) return; const line = document.createElement('div'); line.className = 'byb-total byb-total--six-month'; const label = document.createElement('span'); label.className = 'byb-total-label'; label.textContent = `${this.months} MONTH TOTAL`; const value = document.createElement('span'); value.className = 'byb-total-price byb-six-month-price'; value.innerHTML = this.formatMoney(0); line.appendChild(label); line.appendChild(value); anchor.insertAdjacentElement('afterend', line); this.sixMonthTotalEl = value; } ensurePerDayLine() { if (this.perDayEl) return; const anchor = this.section.querySelector('.byb-total--six-month') || this.sixMonthTotalEl; if (!anchor) return; const line = document.createElement('div'); line.className = 'byb-per-day'; anchor.insertAdjacentElement('afterend', line); this.perDayEl = line; } getTierPercent(subtotal) { if (subtotal >= 120000) return 33; if (subtotal >= 70000) return 30; return 0; } getTierCode(subtotal) { if (subtotal >= 120000) return 'BOX33'; if (subtotal >= 70000) return 'BOX30'; return ''; } interceptAddToCart() { this.section.addEventListener('click', (e) => { const btn = e.target.closest('.add-single-product, .unified-atc-btn'); if (btn && !btn.classList.contains('sold-out')) { const wrapper = btn.closest('.byb-product-wrapper'); if (wrapper) { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); this.handleProductAdd(wrapper, btn); return false; } } }, true); this.section.addEventListener('submit', (e) => { const form = e.target; const wrapper = form.closest('.byb-product-wrapper'); if (wrapper) { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); const btn = form.querySelector('.add-single-product, .unified-atc-btn'); if (btn) this.handleProductAdd(wrapper, btn); return false; } }, true); const forms = this.section.querySelectorAll('form[action*="/cart/add"]'); forms.forEach(form => { const wrapper = form.closest('.byb-product-wrapper'); if (wrapper) { form.addEventListener('submit', (e) => { e.preventDefault(); return false; }); } }); } bindEvents() { this.section.addEventListener('click', (e) => { const variantBtn = e.target.closest('.unified-variant-btn'); if (variantBtn && !variantBtn.disabled) { setTimeout(() => { const wrapper = variantBtn.closest('.byb-product-wrapper'); if (wrapper) this.updateWrapperVariantData(wrapper); }, 100); } }); if (this.checkoutBtn) { this.checkoutBtn.addEventListener('click', () => this.handleCheckout()); } window.addEventListener('scroll', () => this.handleScroll()); } updateWrapperVariantData(wrapper) { const variantSelect = wrapper.querySelector('.variant-option-js'); if (variantSelect) { const selectedOption = variantSelect.querySelector('option:checked'); if (selectedOption) { const variantId = selectedOption.dataset.id; const price = selectedOption.dataset.price; const addBtn = wrapper.querySelector('.unified-atc-btn, .add-single-product'); if (addBtn && variantId) addBtn.dataset.variantId = variantId; if (variantId && price) { wrapper.dataset.currentVariantId = variantId; wrapper.dataset.currentVariantPrice = this.extractPrice(price); } } } } extractPrice(priceString) { const match = String(priceString).match(/[\d,]+\.?\d*/); if (match) { const numStr = match[0].replace(/,/g, ''); return Math.round(parseFloat(numStr) * 100); } return 0; } rememberOriginalButtonLabel(wrapper) { const btn = wrapper.querySelector('.unified-atc-btn, .add-single-product'); if (btn && btn.dataset.originalLabel === undefined) { btn.dataset.originalLabel = 'Add to My Box'; } return btn; } setCardButtonState(productId) { const wrapper = this.section.querySelector(`.byb-product-wrapper[data-product-id="${productId}"]`); if (!wrapper) return; const btn = this.rememberOriginalButtonLabel(wrapper); if (!btn) return; const inBox = this.getQtyForProduct(productId) > 0; const labelTarget = btn.querySelector('.atc-text, .btn-text') || btn; if (inBox) { labelTarget.textContent = 'ADD MORE'; btn.classList.add('byb-added'); wrapper.classList.add('selected'); } else { labelTarget.textContent = btn.dataset.originalLabel || 'Add to My Box'; btn.classList.remove('byb-added'); wrapper.classList.remove('selected'); } } refreshAllCardButtons() { const wrappers = this.section.querySelectorAll('.byb-product-wrapper[data-product-id]'); wrappers.forEach(w => this.setCardButtonState(w.dataset.productId)); } handleProductAdd(wrapper, button) { const productId = wrapper.dataset.productId; const productTitle = wrapper.dataset.productTitle; this.rememberOriginalButtonLabel(wrapper); let variantId = button.dataset.variantId || wrapper.dataset.currentVariantId; if (!variantId) { const variantSelect = wrapper.querySelector('.variant-option-js'); if (variantSelect) { const selectedOption = variantSelect.querySelector('option:checked, option[selected]'); if (selectedOption) variantId = selectedOption.dataset.id; } } const priceEl = wrapper.querySelector('.unified-current-price'); let productPrice = 0; if (priceEl) productPrice = this.extractPrice(priceEl.textContent); const existing = this.selectedProducts.find(p => p.variantId === variantId && variantId); if (existing) { existing.qty += 1; existing.productPrice = productPrice; } else { this.selectedProducts.push({ productId, variantId, productTitle, productPrice, qty: 1 }); } this.updateUI(); } initStickyFooter() { if (this.stickyFooter) this.stickyFooter.classList.remove('hidden'); } handleScroll() { if (!this.stickyFooter) return; const sectionRect = this.section.getBoundingClientRect(); const sectionBottom = sectionRect.bottom; const windowHeight = window.innerHeight; if (sectionBottom < 0 || sectionRect.top > windowHeight) { this.stickyFooter.classList.add('hidden'); } else { this.stickyFooter.classList.remove('hidden'); } } updateUI() { const units = []; this.selectedProducts.forEach((p) => { for (let q = 0; q < p.qty; q++) units.push(p); }); const slotsContainer = this.section.querySelector('.byb-slots'); if (slotsContainer) { slotsContainer.innerHTML = ''; units.forEach((product, i) => { const slot = document.createElement('div'); slot.className = 'byb-slot filled'; const imgWrapper = document.createElement('div'); imgWrapper.style.cssText = 'position:absolute;top:0;left:0;width:100%;height:100%;border-radius:8px;overflow:hidden;'; const img = document.createElement('img'); const wrapper = this.section.querySelector(`.byb-product-wrapper[data-product-id="${product.productId}"]`); if (wrapper) { const productImg = wrapper.querySelector('img'); if (productImg) { img.src = productImg.src; img.alt = product.productTitle; img.style.cssText = 'width:100%;height:100%;object-fit:cover;'; } } imgWrapper.appendChild(img); slot.appendChild(imgWrapper); const removeBtn = document.createElement('div'); removeBtn.className = 'slot-remove'; removeBtn.innerHTML = '×'; removeBtn.setAttribute('data-variant-id', product.variantId); removeBtn.addEventListener('click', (e) => { e.stopPropagation(); this.removeUnit(product.variantId); }); slot.appendChild(removeBtn); slotsContainer.appendChild(slot); if (i < units.length - 1) { const separator = document.createElement('div'); separator.className = 'byb-slot-separator'; separator.textContent = '+'; slotsContainer.appendChild(separator); } }); } this.refreshAllCardButtons(); const subtotal = this.getSubtotal(); const tierPercent = this.getTierPercent(subtotal); const discount = (subtotal * tierPercent) / 100; const total = subtotal - discount; // monthly net const sixMonthSubtotal = subtotal * this.months; const sixMonthTotal = total * this.months; const sixMonthSavings = discount * this.months; const perDay = total / this.daysPerMonth; // net monthly / 30 // C: Monthly-first lead if (this.monthlyLeadEl) { this.monthlyLeadEl.querySelector('.byb-lead-amount').innerHTML = this.formatMoney(total); } if (this.totalPriceEl) { this.totalPriceEl.innerHTML = discount > 0 ? `${this.formatMoney(subtotal)} ${this.formatMoney(total)}` : this.formatMoney(total); } if (this.tierHintEl) { this.tierHintEl.innerHTML = this.buildTierHint(subtotal, tierPercent); } if (this.sixMonthTotalEl) { this.sixMonthTotalEl.innerHTML = discount > 0 ? `${this.formatMoney(sixMonthSubtotal)} ${this.formatMoney(sixMonthTotal)}` : this.formatMoney(sixMonthTotal); } if (this.perDayEl) { this.perDayEl.innerHTML = subtotal > 0 ? `Less than ${this.formatMoney(perDay)}/day` : ''; } if (this.savingsContainer && discount > 0) { this.savingsEl.innerHTML = `${this.formatMoney(sixMonthSavings)} (${tierPercent}% OFF)`; this.savingsContainer.style.display = 'flex'; } else if (this.savingsContainer) { this.savingsContainer.style.display = 'none'; } const incompleteText = this.checkoutBtn.querySelector('.incomplete-text'); const completeText = this.checkoutBtn.querySelector('.complete-text'); const amountRequirementMet = subtotal >= this.minSubtotal; if (amountRequirementMet) { this.checkoutBtn.disabled = false; incompleteText.style.display = 'none'; completeText.style.display = ''; completeText.textContent = tierPercent > 0 ? `ORDER NOW — SAVE ${tierPercent}%` : 'ORDER NOW'; } else { this.checkoutBtn.disabled = true; incompleteText.textContent = `ADD ${this.formatMoney(this.minSubtotal)} OR MORE`; incompleteText.style.display = ''; completeText.style.display = 'none'; } } buildTierHint(subtotal, tierPercent) { const t1 = 70000, t2 = 120000; if (subtotal === 0) { return `🎁 Spend ₹700/month for 30% OFF — or ₹1200+ for 33% OFF!`; } if (tierPercent === 0) { return `🔓 Add ${this.formatMoney(t1 - subtotal)} more to unlock 30% OFF (then ${this.formatMoney(t2 - subtotal)} more for 33% OFF)`; } if (tierPercent === 30) { return `✅ You unlocked 30% OFF! Add ${this.formatMoney(t2 - subtotal)} more to upgrade to 33% OFF`; } return `🏆 Max savings unlocked — you're getting 33% OFF!`; } removeUnit(variantId) { const idx = this.selectedProducts.findIndex(p => p.variantId === variantId); if (idx > -1) { this.selectedProducts[idx].qty -= 1; if (this.selectedProducts[idx].qty <= 0) { this.selectedProducts.splice(idx, 1); } this.updateUI(); this.showNotification('Item removed', 'info'); } } handleCheckout() { const subtotal = this.getSubtotal(); if (subtotal < this.minSubtotal) { this.showNotification(`Minimum amount ${this.formatMoney(this.minSubtotal)} required`, 'error'); return; } const missing = this.selectedProducts.some(p => !p.variantId); if (missing) { this.showNotification('Please pick a size for each product before checkout.', 'error'); return; } this.checkoutBtn.classList.add('loading'); this.checkoutBtn.disabled = true; const tierCode = this.getTierCode(subtotal); const items = this.selectedProducts .map(p => `${Number(p.variantId)}:${p.qty * this.checkoutMultiplier}`) .join(','); let url = `/cart/${items}?checkout`; if (tierCode) url += `&discount=${encodeURIComponent(tierCode)}`; window.location.href = url; } formatMoney(cents) { return `₹${(cents / 100).toFixed(0)}`; } showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `byb-notification byb-notification--${type}`; notification.textContent = message; Object.assign(notification.style, { position: 'fixed', top: '20px', right: '20px', padding: '16px 24px', background: type === 'success' ? '#4caf50' : type === 'error' ? '#f44336' : '#ff9800', color: 'white', borderRadius: '6px', boxShadow: '0 4px 12px rgba(0,0,0,0.15)', zIndex: '10000', fontSize: '14px', fontWeight: '600', maxWidth: '300px', animation: 'slideInRight 0.3s ease' }); const style = document.createElement('style'); style.textContent = ` @keyframes slideInRight { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes slideOutRight { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } } `; document.head.appendChild(style); document.body.appendChild(notification); setTimeout(() => { notification.style.animation = 'slideOutRight 0.3s ease'; setTimeout(() => { notification.remove(); style.remove(); }, 300); }, 3000); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { new BuildYourBox(); }); } else { new BuildYourBox(); } document.addEventListener('shopify:section:load', (event) => { if (event.target.querySelector('.build-your-box-section')) { new BuildYourBox(); } }); /* Single style block: orange button fix + monthly-lead + how-it-works + mobile ribbon */ (function(){ if (document.getElementById('byb-responsive-styles')) return; var s = document.createElement('style'); s.id = 'byb-responsive-styles'; s.textContent = '.build-your-box-section .byb-product-wrapper.selected .unified-atc-btn:not(.sold-out),.build-your-box-section .byb-product-wrapper.selected .unified-atc-btn.byb-added:not(.sold-out),.build-your-box-section .byb-product-wrapper.selected .add-single-product:not(.sold-out){background:#bf570a!important;background-color:#bf570a!important;border-color:#bf570a!important;color:#fff!important;}.build-your-box-section .byb-product-wrapper.selected .unified-atc-btn:not(.sold-out):hover{background:#a84d09!important;background-color:#a84d09!important;}.byb-how-it-works{max-width:1000px;margin:8px auto 20px;padding:0 16px;}.byb-hiw-title{font-weight:700;font-size:16px;text-align:center;margin-bottom:12px;color:#21685a;}.byb-hiw-steps{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;}.byb-hiw-step{display:flex;align-items:center;gap:10px;background:#f6fbf9;border:1px solid #d6ebe4;border-radius:10px;padding:10px 14px;flex:1 1 200px;max-width:240px;}.byb-hiw-num{flex:0 0 28px;width:28px;height:28px;border-radius:50%;background:#21685a;color:#fff;font-weight:700;display:flex;align-items:center;justify-content:center;font-size:14px;}.byb-hiw-text{display:flex;flex-direction:column;line-height:1.25;}.byb-hiw-text b{font-size:13px;}.byb-hiw-text span{font-size:12px;color:#5a6b66;}.byb-monthly-lead{display:flex;align-items:baseline;gap:4px;margin-bottom:4px;}.byb-lead-only{font-size:13px;color:#5a6b66;}.byb-lead-amount{font-size:26px;font-weight:800;color:#bf570a;}.byb-lead-suffix{font-size:14px;font-weight:600;color:#5a6b66;}.byb-per-day{font-size:12px;color:#237804;margin-top:2px;}@media (max-width:749px){.byb-hiw-steps{flex-direction:column;}.byb-hiw-step{max-width:none;flex:1 1 auto;}.byb-footer-content{flex-direction:column!important;gap:8px!important;padding:8px 12px!important;}.byb-summary{flex-direction:column!important;gap:6px!important;width:100%!important;}.byb-summary-left{width:100%!important;}.byb-checkout-btn{width:100%!important;padding:12px 16px!important;font-size:14px!important;}.byb-slots{justify-content:center!important;flex-wrap:wrap!important;gap:8px!important;}.byb-slot{width:44px!important;height:44px!important;}.byb-lead-amount{font-size:22px!important;}.byb-total-label{font-size:11px!important;}.byb-total-price{font-size:13px!important;}.byb-tier-hint{font-size:11px!important;margin-top:4px!important;}.byb-hint-line{padding:4px 8px!important;}.byb-savings{font-size:12px!important;}}'; document.head.appendChild(s); })();