import { t } from "./i18n.js"; import { state } from "./state.js"; import { $ } from "./dom.js"; import { linkRootId, renderLinkBadge, escapeHtml, safeUrl, } from "./ui-utils.js"; import { scoreToEmoji } from "./votes-ui.js"; import { openLightbox } from "./modals-ui.js"; export function renderResults() { const container = $("results-list"); if (!container) return; container.innerHTML = ""; const table = document.createElement("table"); table.className = "results-table"; table.innerHTML = ` ${t("results.rank")} ${t("results.game")} ${t("results.author")} ${t("results.average")} ${t("results.votesList")} ${t("results.myVote")} ${t("results.links")} `; const tbody = table.querySelector("tbody"); const rankByRoot = new Map(); let nextRank = 1; state.results.forEach((r) => { const root = linkRootId(r); let rank = rankByRoot.get(root); if (!rank) { rank = nextRank++; rankByRoot.set(root, rank); } const medal = rank === 1 ? "🥇" : rank === 2 ? "🥈" : rank === 3 ? "🥉" : `${rank}`; const row = document.createElement("tr"); const podiumClass = rank === 1 ? "podium podium-1" : rank === 2 ? "podium podium-2" : rank === 3 ? "podium podium-3" : ""; row.className = podiumClass; const safeName = escapeHtml(r.name); const safeAuthor = escapeHtml(r.author ?? "—"); const safeShot = safeUrl(r.screenshotUrl); const safeGameUrl = safeUrl(r.gameUrl); const safeYoutubeUrl = safeUrl(r.youtubeUrl); row.innerHTML = ` ${medal} ${safeShot ? `${safeName}` : ""}
${safeName} ${renderLinkBadge(r)}
${buildResultMeta(r)}
${safeAuthor || "—"} ${r.average?.toFixed ? r.average.toFixed(1) : r.average} ${formatVotes(r.votes)} ${formatMyVote(r.myVote)} ${safeGameUrl ? `${t("results.link.site")}
` : ""} ${safeYoutubeUrl ? `${t("results.link.youtube")}` : ""} `; tbody.appendChild(row); }); const frame = document.createElement("div"); frame.className = "results-frame"; frame.appendChild(table); container.appendChild(frame); container.querySelectorAll(".clickable-thumb").forEach((img) => { img.addEventListener("click", () => openLightbox(img.src, img.alt)); }); } function buildResultMeta(r) { const hasPlayers = r.minPlayers || r.maxPlayers; const players = hasPlayers ? t("card.players", { min: r.minPlayers ?? "?", max: r.maxPlayers ?? "?", }) : null; const bits = [r.genre ? escapeHtml(r.genre) : null, players].filter( Boolean, ); if (bits.length === 0) return ""; return `
${bits.join(" • ")}
`; } function formatVotes(votes) { if (!Array.isArray(votes) || votes.length === 0) return "⚠️"; const sorted = [...votes].sort((a, b) => a - b); return sorted.map((v) => scoreToEmoji(v)).join(""); } function formatMyVote(score) { if (score == null || Number.isNaN(score)) return "—"; return `${score} ${scoreToEmoji(score)}`; }