// ============================ // Quiz logic + tracking + UI // ============================ // ---- Config (easy to edit) ---- // Mentor avatar image to show in the result block const MENTOR_AVATAR_URL = './assets/img/mentor-us.png'; // WhatsApp phone (international format, digits only) const WHATSAPP_NUMBER = '16815131712'; // WhatsApp link mode switch: // true = use the short link SHORT_WHATSAPP_URL (no prefilled text) // false = use the classic wa.me/phone?text=... URL with encoded text const USE_SHORT_WHATSAPP_LINK = true; // Short link URL (for example your ws/short-link system, such as https://sdlink.cc/us-checkup) // When short-link mode is enabled, buttons will jump directly to this URL. const SHORT_WHATSAPP_URL = 'https://tiao.ws/vaBaeb'; // Educational "study price band" for some common US indices (edit as needed) const INDEX_STUDY_BANDS = [ { labelHtml: 'S&P 500 (SPX)', band: '4,500 – 4,650' }, { labelHtml: 'Dow Jones (DJI)', band: '35,000 – 36,200' }, { labelHtml: 'Nasdaq 100 (NDX)', band: '15,500 – 16,400' }, { labelHtml: 'Russell 2000 (RUT)', band: '1,800 – 1,950' } // NOTE: These are illustrative placeholders for education only. Update freely. ]; // Optional educational study bands for some tickers const TICKER_STUDY_BANDS = { 'AAPL': '$170 – $185', 'MSFT': '$360 – $390', 'JNJ': '$145 – $158', 'XOM': '$100 – $113' // Add more if you wish }; // Live ticker: sample US-style names for "success" messages const LIVE_TICKER_NAMES = [ 'James T.', 'Linda R.', 'Barbara K.', 'Thomas P.', 'Donna S.', 'Michael W.', 'Patricia H.', 'Robert B.', 'Karen L.', 'David G.' ]; // Frequency (ms) of the floating success notice rotation const LIVE_TICKER_INTERVAL = 6000; // ---- Google/GTAG helper ---- function trackEvent(name, params) { var payload = params || {}; if (typeof gtag === 'function') { gtag('event', name, payload); } else { window.dataLayer = window.dataLayer || []; window.dataLayer.push(Object.assign({ event: name }, payload)); } } // Build WhatsApp URL depending on link mode function buildWhatsAppUrl(message) { // Short-link mode: return the short URL directly if (USE_SHORT_WHATSAPP_LINK && SHORT_WHATSAPP_URL) { return SHORT_WHATSAPP_URL; } // Classic mode: wa.me + encoded message text const encoded = encodeURIComponent(message || ''); return `https://wa.me/${WHATSAPP_NUMBER}?text=${encoded}`; } // ---- Footer year ---- const yearEl = document.getElementById('year'); if (yearEl) yearEl.textContent = new Date().getFullYear(); // ---- Quiz state & elements ---- const state = {}; const q1 = document.getElementById('q1'); const q2 = document.getElementById('q2'); const bar = document.getElementById('bar'); const quizCard = document.getElementById('quiz'); const tickerInput = document.getElementById('tickerInput'); const q1Next = document.getElementById('q1Next'); const q1Skip = document.getElementById('q1Skip'); const setProgress = (p) => { if (!bar) return; bar.style.width = p + '%'; bar.setAttribute('aria-valuenow', String(p)); }; // Generic show/hide helpers const show = (el) => { if (!el) return; el.classList.remove('hide'); el.style.display = ''; }; const hide = (el) => { if (!el) return; el.classList.add('hide'); el.style.display = 'none'; }; // ---- Build indices HTML block ---- function buildIndexSnapshotHtml() { const items = INDEX_STUDY_BANDS.map(i => { return `
  • ${i.labelHtml}Study band: ${i.band}
  • `; }).join(''); return `

    US Index Snapshot (Educational)

    Illustrative “study price bands” only — not advice. Edit these ranges in INDEX_STUDY_BANDS.

    `; } // ---- Suggested ticker band (educational) ---- function getTickerBand(ticker) { if (!ticker) return '—'; return TICKER_STUDY_BANDS[ticker] || 'To be included in your educational summary'; } // ---- Render result ---- function renderCompleted() { if (!quizCard) return; setProgress(100); const ticker = (state.ticker || '').toUpperCase(); const focus = state['2'] || 'Calm general overview'; const baseText = `Hi, I would like to receive a neutral, educational AI Stock Checkup for ${ticker || 'US stocks'} (${focus}). I understand this is not investment advice.`; const waUrl = buildWhatsAppUrl(baseText); // Result HTML quizCard.innerHTML = `

    Thank you. Your checkup request is ready.

    Based on your answers ${ticker ? `(${ticker} · ${focus})` : `(${focus})`} we can prepare a neutral, easy-to-read summary for you. It is short, factual, and designed for investors who want clarity without sales pressure.

    Mentor avatar
    Senior Markets Research Team
    Risk-aware, retirement-focused perspective
    Educational study price band for ${ticker || 'your selected stock'}
    ${getTickerBand(ticker)}

    No fees. No trading access. No phone calls. You can mute or stop the messages at any time. This material is educational and not individualized investment advice.

    ${buildIndexSnapshotHtml()}
    `; // Track completion trackEvent('checkup_quiz_completed', { quiz_step: 'completed', ticker: ticker || 'none', focus }); // CTA tracking const waCtaBtn = document.getElementById('waCtaBtn'); if (waCtaBtn) { waCtaBtn.addEventListener('click', function () { trackEvent('checkup_whatsapp_click', { event_category: 'engagement', event_label: 'WhatsApp CTA', ticker: ticker || 'none', focus }); // Optional Google Ads conversion: // gtag('event', 'conversion', { 'send_to': 'AW-XXXXXXX/CONVERSION_LABEL' }); }); } const riskCtaBtn = document.getElementById('riskCtaBtn'); if (riskCtaBtn) { riskCtaBtn.addEventListener('click', function () { trackEvent('checkup_risk_notice_click', { event_category: 'engagement', event_label: 'Risk notice' }); }); } // Scroll into view quizCard.scrollIntoView({ behavior: 'smooth', block: 'start' }); } // ---- Step 1: Next ---- if (q1Next && tickerInput) { q1Next.addEventListener('click', () => { const raw = tickerInput.value.trim(); if (!raw) { tickerInput.classList.add('input-error'); tickerInput.focus(); trackEvent('checkup_q1_empty_submit', { quiz_step: 'q1', error: 'empty_ticker' }); return; } tickerInput.classList.remove('input-error'); const ticker = raw.toUpperCase(); state.ticker = ticker; state['1'] = ticker; setProgress(50); hide(q1); show(q2); trackEvent('checkup_q1_next_click', { quiz_step: 'q1', ticker_entered: ticker }); }); } // ---- Step 1: Skip ---- if (q1Skip) { q1Skip.addEventListener('click', () => { state.ticker = ''; state['1'] = 'Skipped'; setProgress(50); hide(q1); show(q2); trackEvent('checkup_q1_skip_click', { quiz_step: 'q1', ticker_entered: 'skipped' }); }); } // ---- Step 2: select preference ---- document.querySelectorAll('#q2 .qItem').forEach((btn) => { btn.addEventListener('click', () => { const a = btn.dataset.a || ''; document.querySelectorAll('#q2 .qItem').forEach((x) => x.setAttribute('aria-checked', 'false')); btn.setAttribute('aria-checked', 'true'); state['2'] = a; trackEvent('checkup_q2_select', { quiz_step: 'q2', preference: a }); renderCompleted(); }); }); // ---- Usage / cookie banner ---- (function () { const banner = document.getElementById('cookieBanner'); const accept = document.getElementById('acceptCookies'); const closeBtn = document.getElementById('closeCookies'); if (!banner) return; const accepted = localStorage.getItem('ai_us_cookieAccepted'); const dismissed = sessionStorage.getItem('ai_us_cookieDismissed'); if (!accepted && !dismissed) banner.style.display = 'flex'; accept?.addEventListener('click', () => { localStorage.setItem('ai_us_cookieAccepted', 'true'); banner.style.display = 'none'; trackEvent('checkup_usage_notice_accept', { source: 'cookie_banner' }); }); closeBtn?.addEventListener('click', () => { sessionStorage.setItem('ai_us_cookieDismissed', 'true'); banner.style.display = 'none'; trackEvent('checkup_usage_notice_close', { source: 'cookie_banner' }); }); })(); // ---- Live success ticker (rotating) ---- (function () { const bar = document.getElementById('liveTicker'); const textEl = document.getElementById('liveTickerText'); if (!bar || !textEl) return; let i = 0; function setNextMessage() { const name = LIVE_TICKER_NAMES[i % LIVE_TICKER_NAMES.length]; textEl.textContent = `${name} just received the checkup successfully`; i++; } // Show bar and start rotation bar.style.display = 'block'; setNextMessage(); let timer = setInterval(() => { bar.classList.remove('pop'); // reset animation class void bar.offsetWidth; // reflow to restart animation setNextMessage(); bar.classList.add('pop'); }, LIVE_TICKER_INTERVAL); // Pause on hover bar.addEventListener('mouseenter', () => clearInterval(timer)); bar.addEventListener('mouseleave', () => { timer = setInterval(() => { bar.classList.remove('pop'); void bar.offsetWidth; setNextMessage(); bar.classList.add('pop'); }, LIVE_TICKER_INTERVAL); }); })();