feat: add viewer voting on user answers with leaderboard scoring

Viewers can now vote for their favourite audience answers during the
30-second voting window. Votes are persisted to the DB at round end
and aggregated as SUM(votes) in the JUGADORES leaderboard.

- db.ts: add persistUserAnswerVotes(); switch getPlayerScores() to SUM(votes)
- game.ts: add userAnswerVotes to RoundState; persist votes before saveRound
- server.ts: add userAnswerVoters map + /api/vote/respuesta endpoint
- frontend.tsx: add userAnswerVotes type; vote state/handler in App; ▲ buttons in Arena
- frontend.css: flex layout for user-answer rows; user-vote-btn styles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-05 18:26:09 +01:00
parent fe5bb5a5c2
commit 40c919fc64
5 changed files with 182 additions and 12 deletions

View File

@@ -796,6 +796,53 @@ body {
.user-answer {
font-size: 13px;
line-height: 1.4;
display: flex;
align-items: center;
gap: 8px;
justify-content: space-between;
}
.user-answer__main {
flex: 1;
min-width: 0;
}
.user-answer__vote {
display: flex;
align-items: center;
gap: 5px;
flex-shrink: 0;
}
.user-vote-btn {
background: none;
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text-muted);
font-size: 10px;
padding: 2px 7px;
cursor: pointer;
transition: border-color 0.15s, color 0.15s;
line-height: 1.4;
}
.user-vote-btn:hover {
border-color: #444;
color: var(--text-dim);
}
.user-vote-btn--active {
border-color: var(--accent);
color: var(--accent);
}
.user-vote-count {
font-family: var(--mono);
font-size: 11px;
font-weight: 700;
color: var(--text-muted);
min-width: 14px;
text-align: right;
}
.user-answer__name {