/**
* 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);
})();