/**
* Crowd Pulse Quiz Panel
*/
import { escapeHTML, setHTML } from '../utils/dom.js';
export class CrowdPulsePanel {
constructor(containerEl, crowdPulseService) {
this.containerEl = containerEl;
this.crowdPulseService = crowdPulseService;
}
render() {
if (!this.containerEl) return;
setHTML(this.containerEl, `
🧠
Waiting for match events...
AI-generated prediction questions will appear here
`);
this.updateLeaderboard();
}
showQuestion(question) {
const quizArea = this.containerEl?.querySelector('#active-quiz-area');
if (!quizArea) return;
const safeQuestion = escapeHTML(question?.question || question?.text || 'Who will score next?');
const safeOptions = Array.isArray(question?.options) && question.options.length
? question.options.map((opt) => escapeHTML(opt))
: ['Yes', 'No'];
setHTML(quizArea, `
LIVE PREDICTION
${safeQuestion}
${safeOptions.map((opt, idx) => `
`).join('')}
`);
// Update an offscreen announcer to ensure screen readers detect the new question
const announcer = this.containerEl?.querySelector('#active-quiz-announcer');
if (announcer) {
// set textContent separately to trigger live region announcements
announcer.textContent = safeQuestion;
}
quizArea.querySelectorAll('.quiz-opt-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
const idx = parseInt(e.currentTarget.dataset.idx, 10);
this.submitVote(question.id, idx);
});
});
}
submitVote(questionId, idx) {
if (!this.crowdPulseService) return;
const res = this.crowdPulseService.submitAnswer(questionId, idx);
const quizArea = this.containerEl?.querySelector('#active-quiz-area');
const percentage = 40 + Math.round((String(questionId || '').charCodeAt(0) || 0) % 35) + (idx * 3) % 15;
const pct = Math.min(95, Math.max(15, percentage));
if (quizArea) {
const isCorrect = res.isCorrect;
const resultText = isCorrect ? 'Correct! +10 pts' : 'Wrong prediction';
setHTML(quizArea, `
${isCorrect ? '✅' : '❌'}
${isCorrect ? 'Correct! +10 pts' : 'Wrong prediction'}
${pct}% of fans voted similarly
`);
// Announce the result through the offscreen announcer for assistive tech
const announcer = this.containerEl?.querySelector('#active-quiz-announcer');
if (announcer) announcer.textContent = resultText;
}
this.updateLeaderboard();
}
updateLeaderboard() {
if (!this.crowdPulseService) return;
const tbody = this.containerEl?.querySelector('#leaderboard-body');
if (!tbody) return;
const data = this.crowdPulseService.getLeaderboard();
setHTML(tbody, data.map((p, idx) => {
const rank = Number.isFinite(Number(idx)) ? idx + 1 : '';
const name = escapeHTML(p?.name || 'Fan');
const score = Number.isFinite(Number(p?.score)) ? Number(p.score) : 0;
const streak = Number.isFinite(Number(p?.streak)) ? Number(p.streak) : 0;
const isUser = p?.id === 'p5';
return `
| ${rank} |
${name} |
${score} |
🔥 ${streak} |
`;
}).join(''));
}
}