200 lines
6.5 KiB
JavaScript
200 lines
6.5 KiB
JavaScript
/**
|
|
* Welcome rewards floor — loads landing-welcome-rewards.section.html
|
|
* and fills copy from data-* on the placeholder node.
|
|
*
|
|
* Placeholder example:
|
|
* <div
|
|
* data-landing-welcome-rewards
|
|
* data-welcome-title-id="dollar-welcome-title"
|
|
* data-welcome-title-before="Welcome"
|
|
* data-welcome-title-accent="rewards"
|
|
* data-welcome-eyebrow="Limited-time offer"
|
|
* data-welcome-value="$1"
|
|
* data-welcome-sub="ALL CHALLENGES*"
|
|
* data-welcome-code-label="Use code"
|
|
* data-welcome-code="AIFOPROM"
|
|
* data-welcome-cta-text="Claim Now"
|
|
* data-welcome-cta-href="#register-now"
|
|
* data-welcome-copy-success="Code copied!"
|
|
* ></div>
|
|
*/
|
|
(function () {
|
|
var MODULE_URL = '/pages/modules/landing-welcome-rewards.section.html';
|
|
var DEFAULT_COPY_SUCCESS = 'Code copied to clipboard!';
|
|
var copyToastTimer;
|
|
|
|
function readConfig(el) {
|
|
return {
|
|
titleId: el.getAttribute('data-welcome-title-id') || 'landing-welcome-title',
|
|
titleBefore: el.getAttribute('data-welcome-title-before') || '',
|
|
titleAccent: el.getAttribute('data-welcome-title-accent') || '',
|
|
eyebrow: el.getAttribute('data-welcome-eyebrow') || '',
|
|
value: el.getAttribute('data-welcome-value') || '',
|
|
sub: el.getAttribute('data-welcome-sub') || '',
|
|
codeLabel: el.getAttribute('data-welcome-code-label') || '',
|
|
code: el.getAttribute('data-welcome-code') || '',
|
|
ctaText: el.getAttribute('data-welcome-cta-text') || '',
|
|
ctaHref: el.getAttribute('data-welcome-cta-href') || '#register-now',
|
|
note: el.getAttribute('data-welcome-note') || '',
|
|
copySuccess: el.getAttribute('data-welcome-copy-success') || DEFAULT_COPY_SUCCESS,
|
|
};
|
|
}
|
|
|
|
function copyText(text) {
|
|
if (!text) return Promise.resolve();
|
|
if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
|
|
return navigator.clipboard.writeText(text);
|
|
}
|
|
return new Promise(function (resolve, reject) {
|
|
var ta = document.createElement('textarea');
|
|
ta.value = text;
|
|
ta.setAttribute('readonly', '');
|
|
ta.style.position = 'fixed';
|
|
ta.style.left = '-9999px';
|
|
document.body.appendChild(ta);
|
|
ta.select();
|
|
try {
|
|
if (document.execCommand('copy')) resolve();
|
|
else reject(new Error('copy failed'));
|
|
} catch (err) {
|
|
reject(err);
|
|
} finally {
|
|
document.body.removeChild(ta);
|
|
}
|
|
});
|
|
}
|
|
|
|
function getCopyToast() {
|
|
var toast = document.getElementById('landing-welcome-copy-toast');
|
|
if (toast) return toast;
|
|
|
|
toast = document.createElement('div');
|
|
toast.id = 'landing-welcome-copy-toast';
|
|
toast.className = 'landing-welcome-copy-toast';
|
|
toast.setAttribute('role', 'status');
|
|
toast.setAttribute('aria-live', 'polite');
|
|
document.body.appendChild(toast);
|
|
return toast;
|
|
}
|
|
|
|
function showCopyToast(message) {
|
|
var toast = getCopyToast();
|
|
toast.textContent = message;
|
|
toast.classList.add('is-visible');
|
|
window.clearTimeout(copyToastTimer);
|
|
copyToastTimer = window.setTimeout(function () {
|
|
toast.classList.remove('is-visible');
|
|
}, 2400);
|
|
}
|
|
|
|
function bindPromoCodeCopy(codeEl, config) {
|
|
if (!codeEl || !config.code) return;
|
|
|
|
codeEl.setAttribute('aria-label', 'Copy promo code ' + config.code);
|
|
|
|
codeEl.addEventListener('click', function () {
|
|
copyText(config.code)
|
|
.then(function () {
|
|
codeEl.classList.add('is-copied');
|
|
showCopyToast(config.copySuccess);
|
|
window.setTimeout(function () {
|
|
codeEl.classList.remove('is-copied');
|
|
}, 1200);
|
|
})
|
|
.catch(function () {
|
|
showCopyToast('Copy failed. Please copy manually.');
|
|
});
|
|
});
|
|
}
|
|
|
|
function setText(node, value) {
|
|
if (!node) return;
|
|
node.textContent = value;
|
|
}
|
|
|
|
function populateSection(section, config) {
|
|
section.setAttribute('aria-labelledby', config.titleId);
|
|
|
|
var titleEl = section.querySelector('[data-welcome-title]');
|
|
if (titleEl) {
|
|
titleEl.id = config.titleId;
|
|
titleEl.textContent = '';
|
|
|
|
if (config.titleBefore) {
|
|
titleEl.appendChild(document.createTextNode(config.titleBefore));
|
|
}
|
|
|
|
if (config.titleAccent) {
|
|
if (config.titleBefore) {
|
|
titleEl.appendChild(document.createTextNode(' '));
|
|
}
|
|
var accent = document.createElement('span');
|
|
accent.className = 'landing-accent';
|
|
accent.textContent = config.titleAccent;
|
|
titleEl.appendChild(accent);
|
|
}
|
|
}
|
|
|
|
setText(section.querySelector('[data-welcome-eyebrow]'), config.eyebrow);
|
|
setText(section.querySelector('[data-welcome-value]'), config.value);
|
|
setText(section.querySelector('[data-welcome-sub]'), config.sub);
|
|
|
|
var codeWrap = section.querySelector('[data-welcome-code-wrap]');
|
|
if (codeWrap && (config.codeLabel || config.code)) {
|
|
codeWrap.hidden = false;
|
|
setText(section.querySelector('[data-welcome-code-label]'), config.codeLabel);
|
|
var codeEl = section.querySelector('[data-welcome-code]');
|
|
setText(codeEl, config.code);
|
|
bindPromoCodeCopy(codeEl, config);
|
|
}
|
|
|
|
var cta = section.querySelector('[data-welcome-cta]');
|
|
if (cta && config.ctaText) {
|
|
cta.hidden = false;
|
|
cta.textContent = config.ctaText;
|
|
cta.href = config.ctaHref;
|
|
}
|
|
|
|
var note = section.querySelector('[data-welcome-note]');
|
|
if (note && config.note) {
|
|
note.hidden = false;
|
|
note.textContent = config.note;
|
|
}
|
|
}
|
|
|
|
function loadLandingWelcomeRewardsModule() {
|
|
var placeholder = document.querySelector('[data-landing-welcome-rewards]');
|
|
if (!placeholder) return;
|
|
|
|
var config = readConfig(placeholder);
|
|
var parent = placeholder.parentNode;
|
|
|
|
fetch(MODULE_URL, { credentials: 'same-origin' })
|
|
.then(function (res) {
|
|
if (!res.ok) throw new Error('Failed to load ' + MODULE_URL);
|
|
return res.text();
|
|
})
|
|
.then(function (html) {
|
|
var wrap = document.createElement('div');
|
|
wrap.innerHTML = html.trim();
|
|
var section = wrap.firstElementChild;
|
|
if (!section || !parent) return;
|
|
|
|
populateSection(section, config);
|
|
parent.replaceChild(section, placeholder);
|
|
document.dispatchEvent(
|
|
new CustomEvent('aifo:landing-welcome-rewards-ready', { detail: { config: config } })
|
|
);
|
|
})
|
|
.catch(function (err) {
|
|
console.error('[landing-welcome-rewards-module.js]', err);
|
|
});
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', loadLandingWelcomeRewardsModule);
|
|
} else {
|
|
loadLandingWelcomeRewardsModule();
|
|
}
|
|
})();
|