From 9baf20b56971093d0913659b8e4999bf323fecbb Mon Sep 17 00:00:00 2001 From: devRaGonSa <97627393+devRaGonSa@users.noreply.github.com> Date: Tue, 19 May 2026 11:35:28 +0200 Subject: [PATCH] fix: load dynamic recent matches in historical UI * fix: load dynamic recent matches in historical UI * fix: load dynamic recent matches in historical UI --- frontend/assets/js/historico-recent-live.js | 160 ++++++++++++++++++++ frontend/historico.html | 1 + 2 files changed, 161 insertions(+) create mode 100644 frontend/assets/js/historico-recent-live.js diff --git a/frontend/assets/js/historico-recent-live.js b/frontend/assets/js/historico-recent-live.js new file mode 100644 index 0000000..c382fbe --- /dev/null +++ b/frontend/assets/js/historico-recent-live.js @@ -0,0 +1,160 @@ +(() => { + const RECENT_MATCHES_ENDPOINT = "/api/historical/recent-matches"; + const REFRESH_DELAYS_MS = [150, 1000, 3000]; + + document.addEventListener("DOMContentLoaded", () => { + REFRESH_DELAYS_MS.forEach((delay) => { + window.setTimeout(() => { + void refreshDynamicRecentMatches(); + }, delay); + }); + + document.querySelectorAll("[data-server-slug]").forEach((button) => { + button.addEventListener("click", () => { + REFRESH_DELAYS_MS.forEach((delay) => { + window.setTimeout(() => { + void refreshDynamicRecentMatches(button.dataset.serverSlug); + }, delay); + }); + }); + }); + }); + + async function refreshDynamicRecentMatches(forcedServerSlug) { + const listNode = document.getElementById("recent-matches-list"); + const stateNode = document.getElementById("recent-matches-state"); + const metaNode = document.getElementById("recent-matches-snapshot-meta"); + const noteNode = document.getElementById("recent-matches-note"); + if (!listNode || !stateNode || !metaNode) { + return; + } + + const backendBaseUrl = + document.body.dataset.backendBaseUrl || "http://127.0.0.1:8000"; + const serverSlug = normalizeDynamicServerSlug(forcedServerSlug || readServerFromUrl()); + + try { + const response = await fetch( + `${backendBaseUrl}${RECENT_MATCHES_ENDPOINT}?server=${encodeURIComponent( + serverSlug, + )}&limit=10`, + { cache: "no-store" }, + ); + if (!response.ok) { + throw new Error(`HTTP ${response.status}`); + } + const payload = await response.json(); + const data = payload?.data || {}; + const items = Array.isArray(data.items) ? data.items : []; + if (!items.length) { + setDynamicState(stateNode, "No hay partidas recientes disponibles para este alcance."); + listNode.innerHTML = ""; + metaNode.textContent = "Datos recientes sin partidas disponibles."; + return; + } + + listNode.innerHTML = items.map((item) => renderDynamicRecentMatchCard(item)).join(""); + stateNode.hidden = true; + if (noteNode) { + noteNode.textContent = "Lista dinamica de partidas registradas por el modelo RCON reciente."; + } + metaNode.textContent = buildDynamicRecentMeta(data, items); + } catch (error) { + setDynamicState(stateNode, "No se pudieron cargar las partidas recientes dinamicas.", true); + metaNode.textContent = "Error al leer las partidas recientes dinamicas."; + } + } + + function readServerFromUrl() { + return new URLSearchParams(window.location.search).get("server") || "all-servers"; + } + + function normalizeDynamicServerSlug(value) { + const normalized = String(value || "").trim(); + if (["comunidad-hispana-01", "comunidad-hispana-02", "all-servers"].includes(normalized)) { + return normalized; + } + return "all-servers"; + } + + function renderDynamicRecentMatchCard(item) { + if (typeof window.renderRecentMatchCard === "function") { + return window.renderRecentMatchCard(item); + } + const mapName = item?.map?.pretty_name || item?.map?.name || "Mapa no disponible"; + const serverName = item?.server?.name || "Servidor no disponible"; + const closedAt = item?.closed_at || item?.ended_at || item?.started_at; + return ` +
+
+
+

Partida ${escapeDynamicHtml(item?.match_id || "sin id")}

+

${escapeDynamicHtml(mapName)}

+
+
+ ${escapeDynamicHtml(formatDynamicScore(item?.result))} +
+
+
+

Servidor

${escapeDynamicHtml(serverName)}
+

Cierre

${escapeDynamicHtml(formatDynamicTimestamp(closedAt))}
+

Jugadores

${escapeDynamicHtml(formatDynamicNumber(item?.player_count))}
+

Marcador

${escapeDynamicHtml(formatDynamicScore(item?.result))}
+
+
+ `; + } + + function buildDynamicRecentMeta(data, items) { + const newest = items[0]?.closed_at || items[0]?.ended_at || items[0]?.started_at; + const source = data.selected_source || data.source || "rcon"; + const captureText = newest ? `Actualizado: ${formatDynamicTimestamp(newest)}` : "Actualizado recientemente"; + return `${captureText} | Fuente: ${source}`; + } + + function setDynamicState(node, message, isError = false) { + node.textContent = message; + node.hidden = false; + node.classList.toggle("is-error", Boolean(isError)); + } + + function formatDynamicTimestamp(value) { + if (!value) { + return "Fecha no disponible"; + } + const date = new Date(value); + if (Number.isNaN(date.getTime())) { + return String(value); + } + return new Intl.DateTimeFormat("es-ES", { + day: "numeric", + month: "numeric", + year: "2-digit", + hour: "2-digit", + minute: "2-digit", + }).format(date); + } + + function formatDynamicNumber(value) { + const number = Number(value); + return Number.isFinite(number) ? new Intl.NumberFormat("es-ES").format(number) : "0"; + } + + function formatDynamicScore(result) { + const allied = result?.allied_score; + const axis = result?.axis_score; + if (Number.isFinite(Number(allied)) && Number.isFinite(Number(axis))) { + return `${allied} - ${axis}`; + } + return "- - -"; + } + + function escapeDynamicHtml(value) { + return String(value ?? "") + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """) + .replaceAll("'", "'"); + } +})(); diff --git a/frontend/historico.html b/frontend/historico.html index 5862cec..3fa7417 100644 --- a/frontend/historico.html +++ b/frontend/historico.html @@ -223,5 +223,6 @@ +