+
+
+ #${escapeHtml(item?.ranking_position || "-")}
+
+
+
Puntuacion MVP
+
${escapeHtml(
+ Number.isFinite(scoreValue) ? scoreValue.toFixed(1) : "0.0",
+ )}
+
+
+
+ ${escapeHtml(
+ item?.player?.name || "Jugador no identificado",
+ )}
+
+
+
+
+ `;
+}
+
function setState(node, message, isError = false) {
node.textContent = message;
node.hidden = false;
@@ -807,6 +963,10 @@ function buildLeaderboardSnapshotKey(serverSlug, timeframeKey, metricKey) {
return `leaderboard:${serverSlug}:${timeframeKey}:${metricKey}`;
}
+function buildMonthlyMvpSnapshotKey(serverSlug) {
+ return `monthly-mvp:${serverSlug}`;
+}
+
function buildRangeLabel(start, end) {
if (!start && !end) {
return "";
@@ -848,7 +1008,7 @@ function buildCoveragePeriodLabel(coverage, timeRange, serverSlug) {
function buildSummaryNote(summaryBasis, weeklyWindowDays, coverage, serverSlug) {
const basisLabel =
summaryBasis === "snapshot-precomputed"
- ? "el snapshot precalculado del historico local"
+ ? "el historico local"
: "el historico persistido disponible";
const status = coverage?.status;
void weeklyWindowDays;
@@ -857,7 +1017,7 @@ function buildSummaryNote(summaryBasis, weeklyWindowDays, coverage, serverSlug)
return `Este bloque resume ${basisLabel}. La cobertura registrada todavia es inicial y puede crecer en los proximos dias.`;
}
if (serverSlug === "all-servers") {
- return `Resumen global servido desde ${basisLabel} y combinado solo con los servidores que ya tienen historico disponible.`;
+ return `Resumen de los servidore desde ${basisLabel} y combinado solo los servidores actuales de la comunidad.`;
}
return `Resumen servido desde ${basisLabel}.`;
}
@@ -867,7 +1027,7 @@ function buildWeeklyWindowNote(payload) {
const timeframeLabel = getLeaderboardTimeframeConfig(
payload?.timeframe || activeLeaderboardTimeframe,
).shortLabel;
- return `No existe un snapshot ${timeframeLabel} listo para esta metrica en el alcance activo.`;
+ return `No existen datos en ${timeframeLabel} suficientes para esta metrica en el rango activo.`;
}
const start = formatTimestamp(payload?.window_start);
@@ -899,6 +1059,26 @@ function buildRecentMatchesNote(serverSlug) {
return `Lista de cierres ya registrados para ${getHistoricalServerLabel(serverSlug)}.`;
}
+function buildMonthlyMvpNote(payload) {
+ if (!payload?.found) {
+ return "El Top 3 mensual aparecera cuando exista un snapshot MVP listo para este alcance.";
+ }
+ const periodLabel =
+ payload?.window_label && payload?.month_key
+ ? `${payload.window_label} (${formatMonthKey(payload.month_key)})`
+ : formatMonthKey(payload?.month_key);
+ const eligiblePlayers = formatNumber(payload?.eligible_players_count);
+ return `${periodLabel || "Periodo mensual activo"}. ${eligiblePlayers} jugadores cumplen los umbrales de elegibilidad.`;
+}
+
+function buildMonthlyMvpFooter(item, payload) {
+ const hoursPlayed = Number(item?.totals?.time_seconds) / 3600;
+ const monthLabel = formatMonthKey(payload?.month_key);
+ return `${monthLabel || "Mes activo"} · ${formatNumber(
+ item?.matches_considered,
+ )} partidas · ${formatDecimal(hoursPlayed, 1)} h jugadas`;
+}
+
function buildSnapshotMetaText(payload, missingMessage) {
if (!payload?.generated_at) {
return missingMessage;
@@ -977,6 +1157,35 @@ function formatNumber(value) {
return new Intl.NumberFormat("es-ES").format(parsedValue);
}
+function formatDecimal(value, fractionDigits = 1) {
+ const parsedValue = Number(value);
+ if (!Number.isFinite(parsedValue)) {
+ return "0";
+ }
+
+ return new Intl.NumberFormat("es-ES", {
+ minimumFractionDigits: fractionDigits,
+ maximumFractionDigits: fractionDigits,
+ }).format(parsedValue);
+}
+
+function formatMonthKey(monthKey) {
+ if (!monthKey) {
+ return "";
+ }
+
+ const value = new Date(`${monthKey}-01T00:00:00Z`);
+ if (Number.isNaN(value.getTime())) {
+ return monthKey;
+ }
+
+ return new Intl.DateTimeFormat("es-ES", {
+ month: "long",
+ year: "numeric",
+ timeZone: "UTC",
+ }).format(value);
+}
+
function formatTimestamp(timestamp) {
if (!timestamp) {
return "Fecha no disponible";
diff --git a/frontend/historico.html b/frontend/historico.html
index ea5afe8..d7c6b0c 100644
--- a/frontend/historico.html
+++ b/frontend/historico.html
@@ -81,7 +81,7 @@