<script>
(function () {
const productId = {{ product.id }};
const root = document.querySelector('[data-bonus-campaign]');
if (!root) return;
const pillEl = root.querySelector('[data-bonus-campaign-pill]');
const timerEl = root.querySelector('[data-bonus-campaign-timer]');
let timer = null;
// "Ends in 2d 14h" / "Ends in 3h 20m" / "Ends in 12m", or null once it has ended
function formatTimeLeft(endsAt) {
const msLeft = new Date(endsAt) - Date.now();
if (msLeft <= 0) return null;
const days = Math.floor(msLeft / 86400000);
const hours = Math.floor((msLeft % 86400000) / 3600000);
const minutes = Math.floor((msLeft % 3600000) / 60000);
if (days > 0) return `Ends in ${days}d ${hours}h`;
if (hours > 0) return `Ends in ${hours}h ${minutes}m`;
return `Ends in ${Math.max(minutes, 1)}m`;
}
function hide() {
root.hidden = true;
if (timer) clearInterval(timer);
}
function render(campaign, unit) {
const timeLeft = formatTimeLeft(campaign.endsAt);
if (!timeLeft) return hide();
if (campaign.type === 'multiplier') {
pillEl.textContent = `${campaign.multiplier}× ${unit} this weekend`;
} else {
// Spend-threshold campaign: show the lowest tier
const tier = campaign.tiers[0];
pillEl.textContent = `Spend ${tier.spendFormatted}, get ${tier.bonusFormatted} bonus`;
}
timerEl.textContent = timeLeft;
root.hidden = false;
// Keep the countdown ticking without calling the SDK again
if (timer) clearInterval(timer);
timer = setInterval(() => {
const next = formatTimeLeft(campaign.endsAt);
if (!next) return hide();
timerEl.textContent = next;
}, 60000);
}
async function init() {
const campaignResp = await MageSDK.getProductBonusCampaign({ productId });
if (!campaignResp.success || !campaignResp.data) return hide();
// Pick the wording for the shop's loyalty mode
const rulesResp = await MageSDK.getEarningRules();
const unit = rulesResp.success && rulesResp.data.loyaltyMode === 'store_credit' ? 'store credit' : 'points';
render(campaignResp.data, unit);
}
if (window.MageSDK) {
init();
} else {
document.addEventListener('mage-sdk-loaded', init);
}
})();
</script>