Polish public page navigation and copy
This commit is contained in:
@@ -0,0 +1,139 @@
|
|||||||
|
---
|
||||||
|
id: TASK-203
|
||||||
|
title: Public pages navigation and copy polish
|
||||||
|
status: done
|
||||||
|
type: frontend
|
||||||
|
team: Frontend Senior
|
||||||
|
supporting_teams:
|
||||||
|
- Experto en interfaz
|
||||||
|
roadmap_item: foundation
|
||||||
|
priority: medium
|
||||||
|
---
|
||||||
|
|
||||||
|
# TASK-203 - Public pages navigation and copy polish
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Reorganizar la navegacion superior y normalizar el layout visual de `index`, `historico`, `stats` y `ranking` para que compartan una navegacion publica coherente, una cabecera visual alineada y textos visibles corregidos en UTF-8.
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Las paginas publicas principales ya exponen el producto, pero hoy mezclan botones sueltos dentro del hero, encabezados desalineados y varios textos mal codificados o demasiado tecnicos para usuarios normales. Esta tarea corrige solo la capa visual y de copy en `frontend/`, sin tocar backend, endpoints, logica de datos, Elo/MMR pausado, Comunidad Hispana #03 ni assets/SVGs de armas.
|
||||||
|
|
||||||
|
Preserve the current product identity: Spanish-speaking HLL Vietnam community, military/Vietnam/tactical/sober visual direction and controlled repository evolution.
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
1. Inspeccionar el HTML, CSS y JS compartidos de las paginas publicas afectadas.
|
||||||
|
2. Crear o reutilizar una navegacion superior global para `index`, `historico`, `stats` y `ranking`.
|
||||||
|
3. Alinear el hero de `stats` y `ranking` con la composicion visual usada por `index` y `historico`.
|
||||||
|
4. Limpiar botones duplicados dentro del hero y simplificar el copy visible sin cambiar logica de datos.
|
||||||
|
5. Corregir textos visibles con problemas de codificacion en las paginas afectadas y validar el resultado por inspeccion.
|
||||||
|
|
||||||
|
## Files to Read First
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `ai/repo-context.md`
|
||||||
|
- `ai/architecture-index.md`
|
||||||
|
- `frontend/index.html`
|
||||||
|
- `frontend/historico.html`
|
||||||
|
- `frontend/assets/css/styles.css`
|
||||||
|
|
||||||
|
## Expected Files to Modify
|
||||||
|
|
||||||
|
- `ai/tasks/done/TASK-203-public-pages-navigation-and-copy-polish.md`
|
||||||
|
- `frontend/index.html`
|
||||||
|
- `frontend/historico.html`
|
||||||
|
- `frontend/stats.html`
|
||||||
|
- `frontend/ranking.html`
|
||||||
|
- `frontend/assets/css/styles.css`
|
||||||
|
- `frontend/assets/js/stats.js`
|
||||||
|
- `frontend/assets/js/ranking.js`
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
|
||||||
|
- Keep the change minimal.
|
||||||
|
- Preserve HLL Vietnam project identity.
|
||||||
|
- Do not introduce unnecessary frameworks or dependencies.
|
||||||
|
- Do not implement backend functionality unless the task explicitly requires it.
|
||||||
|
- Do not expand Elo/MMR, historical workers or RCON server #03 handling unless the task explicitly requires it.
|
||||||
|
- Do not overwrite repository-specific context with generic platform template text.
|
||||||
|
- No ejecutar `ai-platform run`.
|
||||||
|
- No modificar `backend/`, scripts de validacion backend, endpoints, logica de datos, assets/SVGs de armas ni siluetas.
|
||||||
|
- No reactivar Elo/MMR ni reintroducir Comunidad Hispana #03.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
Before completing the task ensure:
|
||||||
|
|
||||||
|
- `index.html`, `historico.html`, `stats.html` y `ranking.html` muestran navegacion superior con acceso a Inicio, Historico, Stats y Ranking
|
||||||
|
- `index.html` mantiene `Unirse al Discord` dentro del hero
|
||||||
|
- `stats.html` y `ranking.html` muestran imagen/icono de comunidad en hero
|
||||||
|
- `stats.html` y `ranking.html` ya no muestran `Backend operativo`
|
||||||
|
- no aparecen textos mal codificados visibles como `Público`, `Públicos`, `Año`, `AÃo`, `Histórico`
|
||||||
|
- `ranking.html` ya no muestra `Fuente` en el panel visible de tabla activa
|
||||||
|
- `git diff --name-only` matches the expected scope
|
||||||
|
- no unrelated files were modified
|
||||||
|
- integration tests are run when relevant and configured
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
Archivos modificados:
|
||||||
|
|
||||||
|
- `frontend/index.html`
|
||||||
|
- `frontend/historico.html`
|
||||||
|
- `frontend/stats.html`
|
||||||
|
- `frontend/ranking.html`
|
||||||
|
- `frontend/assets/css/styles.css`
|
||||||
|
- `frontend/assets/js/stats.js`
|
||||||
|
- `frontend/assets/js/ranking.js`
|
||||||
|
- `ai/tasks/done/TASK-203-public-pages-navigation-and-copy-polish.md`
|
||||||
|
|
||||||
|
Navegacion nueva:
|
||||||
|
|
||||||
|
- Se anadio una navegacion superior comun en las cuatro paginas publicas con acceso directo a Inicio, Historico, Stats y Ranking.
|
||||||
|
- El estado activo se marca por pagina y la navegacion queda separada del hero como banda superior de tabs tacticos.
|
||||||
|
|
||||||
|
Textos corregidos:
|
||||||
|
|
||||||
|
- Se corrigieron textos visibles relacionados con Historico, publico/publicos, estadisticas, metrica, limite y ano/anual.
|
||||||
|
- En HTML se usaron entidades para asegurar render correcto en entorno Windows y lectura segura en navegador.
|
||||||
|
- En JS visible se usaron escapes Unicode donde hacia falta para evitar mojibake.
|
||||||
|
|
||||||
|
Botones movidos:
|
||||||
|
|
||||||
|
- En `index`, `Stats`, `Ranking` y `Ver historico propio` salieron del hero y pasaron a la navegacion global.
|
||||||
|
- En `historico`, `Volver inicio` y `Stats` se sustituyeron por la navegacion global, y se anadio acceso directo a Ranking.
|
||||||
|
- En `stats` y `ranking`, los enlaces de retorno cruzado del hero se sustituyeron por la navegacion global.
|
||||||
|
|
||||||
|
Elementos retirados:
|
||||||
|
|
||||||
|
- Se elimino el badge visible de backend en `stats` y `ranking`.
|
||||||
|
- Se elimino el campo visual `Fuente` del panel visible de metadata en `ranking`.
|
||||||
|
|
||||||
|
Validaciones ejecutadas:
|
||||||
|
|
||||||
|
- Revision por inspeccion de `frontend/index.html`, `frontend/historico.html`, `frontend/stats.html` y `frontend/ranking.html`.
|
||||||
|
- Verificacion de navegacion superior comun en las cuatro paginas.
|
||||||
|
- Verificacion de que `Unirse al Discord` permanece en el hero de `index`.
|
||||||
|
- Verificacion de que `stats` y `ranking` incluyen `logo.png` en el hero.
|
||||||
|
- Verificacion de que ya no existen `id="stats-backend-state"` ni `id="ranking-backend-state"` en HTML.
|
||||||
|
- Verificacion de que `ranking.js` ya no genera la tarjeta visible `Fuente`.
|
||||||
|
- Revision de `git status --short --untracked-files=all` y `git diff --name-only`.
|
||||||
|
- Confirmacion de que no hay cambios en `backend/` ni en `scripts/`.
|
||||||
|
|
||||||
|
Tests:
|
||||||
|
|
||||||
|
- No se ejecutaron scripts de validacion frontend existentes porque los scripts disponibles no son ligeros para este alcance y uno de ellos (`scripts/run-stats-validation.ps1`) exige el chip `stats-backend-state`, eliminado intencionadamente por esta task. No se modifico ese script por estar fuera de alcance.
|
||||||
|
|
||||||
|
Confirmaciones de alcance:
|
||||||
|
|
||||||
|
- No se tocaron `backend/`, endpoints, logica de datos, scripts backend, Elo/MMR ni Comunidad Hispana #03.
|
||||||
|
- No se tocaron assets/SVGs de armas. Los cambios ya presentes en `frontend/assets/img/weapons/` y `ai/system-metrics.md` eran previos y se dejaron intactos.
|
||||||
|
|
||||||
|
## Change Budget
|
||||||
|
|
||||||
|
- Prefer fewer than 5 modified files.
|
||||||
|
- Prefer changes under 200 lines when feasible.
|
||||||
|
- Split the work into follow-up tasks if limits are exceeded.
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
:root {
|
:root {
|
||||||
--bg: #0f120d;
|
--bg: #0f120d;
|
||||||
--bg-deep: #090b08;
|
--bg-deep: #090b08;
|
||||||
--bg-elevated: rgba(27, 33, 24, 0.92);
|
--bg-elevated: rgba(27, 33, 24, 0.92);
|
||||||
@@ -85,6 +85,58 @@ a {
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.public-nav {
|
||||||
|
width: min(var(--page-shell-width), calc(100vw - (var(--page-shell-gutter) * 2)));
|
||||||
|
margin: 0 auto 16px;
|
||||||
|
padding: 10px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
gap: 12px;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 22px;
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(24, 30, 22, 0.9), rgba(10, 13, 9, 0.96)),
|
||||||
|
radial-gradient(circle at top center, rgba(183, 201, 125, 0.08), transparent 40%);
|
||||||
|
box-shadow: var(--shadow-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-nav__link {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 50px;
|
||||||
|
padding: 0 18px;
|
||||||
|
border: 1px solid rgba(159, 168, 141, 0.22);
|
||||||
|
border-radius: 999px;
|
||||||
|
background: linear-gradient(180deg, rgba(18, 23, 16, 0.88), rgba(10, 12, 9, 0.96));
|
||||||
|
color: var(--text-soft);
|
||||||
|
font-size: 0.82rem;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
transition:
|
||||||
|
transform 160ms ease,
|
||||||
|
border-color 160ms ease,
|
||||||
|
background 160ms ease,
|
||||||
|
color 160ms ease,
|
||||||
|
box-shadow 160ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-nav__link:hover,
|
||||||
|
.public-nav__link:focus-visible {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
border-color: rgba(210, 182, 118, 0.48);
|
||||||
|
background: linear-gradient(180deg, rgba(43, 50, 36, 0.94), rgba(16, 20, 14, 0.98));
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-nav__link.is-active {
|
||||||
|
border-color: rgba(183, 201, 125, 0.42);
|
||||||
|
background: linear-gradient(180deg, rgba(183, 201, 125, 0.22), rgba(89, 101, 58, 0.28));
|
||||||
|
color: var(--text);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
.hero {
|
.hero {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -920,6 +972,11 @@ h2 {
|
|||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stats-hero .hero__brand,
|
||||||
|
.ranking-hero .hero__brand {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.stats-search-form {
|
.stats-search-form {
|
||||||
margin: 0 0 14px;
|
margin: 0 0 14px;
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -1401,6 +1458,10 @@ h2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 760px) {
|
@media (max-width: 760px) {
|
||||||
|
.public-nav {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
.servers-grid,
|
.servers-grid,
|
||||||
.servers-grid--section,
|
.servers-grid--section,
|
||||||
.clans-grid {
|
.clans-grid {
|
||||||
@@ -1430,6 +1491,18 @@ h2 {
|
|||||||
font-size: 0.98rem;
|
font-size: 0.98rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.public-nav {
|
||||||
|
padding: 8px;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-nav__link {
|
||||||
|
min-height: 46px;
|
||||||
|
padding-inline: 12px;
|
||||||
|
font-size: 0.74rem;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
}
|
||||||
|
|
||||||
.stats-search-form__fields {
|
.stats-search-form__fields {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
@@ -1475,7 +1548,8 @@ h2 {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.secondary-button {
|
.secondary-button,
|
||||||
|
.public-nav__link {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1541,3 +1615,4 @@ h2 {
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
const backendBaseUrl = document.body.dataset.backendBaseUrl || "http://127.0.0.1:8000";
|
const backendBaseUrl = document.body.dataset.backendBaseUrl || "http://127.0.0.1:8000";
|
||||||
const form = document.getElementById("ranking-form");
|
const form = document.getElementById("ranking-form");
|
||||||
const timeframeSelect = document.getElementById("ranking-timeframe");
|
const timeframeSelect = document.getElementById("ranking-timeframe");
|
||||||
@@ -185,7 +185,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
if (isAnnual) {
|
if (isAnnual) {
|
||||||
setFilterNote(
|
setFilterNote(
|
||||||
"El ranking anual sigue limitado a kills porque solo esa metrica tiene lectura snapshot segura.",
|
"El ranking anual sigue limitado a kills porque solo esa m\u00e9trica tiene lectura snapshot segura.",
|
||||||
"warning",
|
"warning",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@@ -272,7 +272,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
if (!isBackendOnline) {
|
if (!isBackendOnline) {
|
||||||
setRankingState("error", "Backend no disponible. El ranking queda en estado offline.");
|
setRankingState("error", "Backend no disponible. El ranking queda en estado offline.");
|
||||||
renderEmptyState(
|
renderEmptyState(
|
||||||
"No fue posible contactar el backend. Reintenta cuando el servicio vuelva a estar operativo.",
|
"No fue posible contactar el backend. Reintenta cuando el servicio vuelva a estar disponible.",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -281,8 +281,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
if (timeframe === "annual") {
|
if (timeframe === "annual") {
|
||||||
year = Number.parseInt(String(yearInput?.value || "").trim(), 10);
|
year = Number.parseInt(String(yearInput?.value || "").trim(), 10);
|
||||||
if (!Number.isFinite(year) || year <= 0) {
|
if (!Number.isFinite(year) || year <= 0) {
|
||||||
setRankingState("error", "El ano solicitado no es valido.");
|
setRankingState("error", "El a\u00f1o solicitado no es v\u00e1lido.");
|
||||||
renderEmptyState("Corrige el ano y vuelve a consultar el ranking anual.");
|
renderEmptyState("Corrige el a\u00f1o y vuelve a consultar el ranking anual.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -322,7 +322,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
setBackendState("Backend no disponible", false);
|
setBackendState("Backend no disponible", false);
|
||||||
setRankingState("error", "Error controlado al cargar el ranking.");
|
setRankingState("error", "Error controlado al cargar el ranking.");
|
||||||
renderEmptyState(
|
renderEmptyState(
|
||||||
"La lectura del ranking fallo en este intento. Revisa el backend o actualiza la pagina.",
|
"La lectura del ranking fall\u00f3 en este intento. Revisa el backend o actualiza la p\u00e1gina.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,20 +343,20 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
) {
|
) {
|
||||||
setRankingState("warning", "El ranking anual solo admite kills por ahora.");
|
setRankingState("warning", "El ranking anual solo admite kills por ahora.");
|
||||||
renderEmptyState(
|
renderEmptyState(
|
||||||
"Las metricas extra estan disponibles en semanal y mensual. El ranking anual sigue limitado a kills mientras no existan snapshots seguros adicionales.",
|
"Las m\u00e9tricas extra est\u00e1n disponibles en semanal y mensual. El ranking anual sigue limitado a kills mientras no existan snapshots seguros adicionales.",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (statusCode === 400 && normalizedMessage.includes("metric")) {
|
if (statusCode === 400 && normalizedMessage.includes("metric")) {
|
||||||
setRankingState("warning", "La metrica solicitada no esta soportada.");
|
setRankingState("warning", "La m\u00e9trica solicitada no est\u00e1 soportada.");
|
||||||
renderEmptyState(
|
renderEmptyState(
|
||||||
"Usa kills, deaths, teamkills, partidas jugadas, K/D o kills por partida.",
|
"Usa kills, deaths, teamkills, partidas jugadas, K/D o kills por partida.",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (statusCode === 400 && normalizedMessage.includes("year")) {
|
if (statusCode === 400 && normalizedMessage.includes("year")) {
|
||||||
setRankingState("warning", "El ranking anual requiere un ano valido.");
|
setRankingState("warning", "El ranking anual requiere un a\u00f1o v\u00e1lido.");
|
||||||
renderEmptyState("Define un ano valido para consultar la lectura anual.");
|
renderEmptyState("Define un a\u00f1o v\u00e1lido para consultar la lectura anual.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (statusCode === 400 && normalizedMessage.includes("timeframe")) {
|
if (statusCode === 400 && normalizedMessage.includes("timeframe")) {
|
||||||
@@ -398,7 +398,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
if (timeframe === "annual" && snapshotStatus === "missing") {
|
if (timeframe === "annual" && snapshotStatus === "missing") {
|
||||||
setRankingState("warning", "El snapshot anual solicitado aun no fue generado.");
|
setRankingState("warning", "El snapshot anual solicitado aun no fue generado.");
|
||||||
renderEmptyState(
|
renderEmptyState(
|
||||||
"No existe snapshot anual para el ano y servidor elegidos. Este estado es informativo y no implica caida del backend.",
|
"No existe snapshot anual para el a\u00f1o y servidor elegidos. Este estado es informativo y no implica ca\u00edda del backend.",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -441,10 +441,9 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
const cards = [
|
const cards = [
|
||||||
{ label: "Periodo activo", value: labelForTimeframe(timeframe), active: true },
|
{ label: "Periodo activo", value: labelForTimeframe(timeframe), active: true },
|
||||||
{ label: "Servidor activo", value: labelForServer(data.server_id), active: true },
|
{ label: "Servidor activo", value: labelForServer(data.server_id), active: true },
|
||||||
{ label: "Metrica activa", value: labelForMetric(metric), active: true },
|
{ label: "M\u00e9trica activa", value: labelForMetric(metric), active: true },
|
||||||
{ label: "Limite", value: `Top ${safeInt(data.limit, safeInt(defaultLimit, 20))}` },
|
{ label: "L\u00edmite", value: `Top ${safeInt(data.limit, safeInt(defaultLimit, 20))}` },
|
||||||
{ label: "Ventana", value: labelForWindow(data) },
|
{ label: "Ventana", value: labelForWindow(data) },
|
||||||
{ label: "Fuente", value: String(source.read_model || "No disponible") },
|
|
||||||
{ label: "Actualizado", value: formatDateTime(source.generated_at) },
|
{ label: "Actualizado", value: formatDateTime(source.generated_at) },
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -490,7 +489,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
function labelForWindow(data) {
|
function labelForWindow(data) {
|
||||||
if (String(data.timeframe || "") === "annual") {
|
if (String(data.timeframe || "") === "annual") {
|
||||||
return `Ano ${safeInt(data.year, currentYear)}`;
|
return `A\u00f1o ${safeInt(data.year, currentYear)}`;
|
||||||
}
|
}
|
||||||
return String(data.window_label || data.window_kind || "Ventana activa");
|
return String(data.window_label || data.window_kind || "Ventana activa");
|
||||||
}
|
}
|
||||||
@@ -586,3 +585,4 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
.replaceAll("'", "'");
|
.replaceAll("'", "'");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
const backendBaseUrl = document.body.dataset.backendBaseUrl || "http://127.0.0.1:8000";
|
const backendBaseUrl = document.body.dataset.backendBaseUrl || "http://127.0.0.1:8000";
|
||||||
const searchForm = document.getElementById("stats-search-form");
|
const searchForm = document.getElementById("stats-search-form");
|
||||||
const searchInput = document.getElementById("stats-search-input");
|
const searchInput = document.getElementById("stats-search-input");
|
||||||
@@ -39,22 +39,22 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
"Error al buscar jugadores. Verifica backend y reintenta.",
|
"Error al buscar jugadores. Verifica backend y reintenta.",
|
||||||
searchReadyPrefix: "Se encontraron ",
|
searchReadyPrefix: "Se encontraron ",
|
||||||
searchReadySuffix:
|
searchReadySuffix:
|
||||||
" jugador(es). Selecciona uno para ver sus estadisticas.",
|
" jugador(es). Selecciona uno para ver sus estad\u00edsticas.",
|
||||||
searchShortQueryHelp:
|
searchShortQueryHelp:
|
||||||
"Usa al menos 1 caracter para iniciar la busqueda.",
|
"Usa al menos 1 car\u00e1cter para iniciar la b\u00fasqueda.",
|
||||||
profileLoading: "Cargando estadisticas personales...",
|
profileLoading: "Cargando estad\u00edsticas personales...",
|
||||||
profileNoStats:
|
profileNoStats:
|
||||||
"Jugador sin estadisticas suficientes para mostrar datos personales.",
|
"Jugador sin estad\u00edsticas suficientes para mostrar datos personales.",
|
||||||
profileError: "No fue posible cargar las estadisticas del jugador.",
|
profileError: "No fue posible cargar las estad\u00edsticas del jugador.",
|
||||||
annualLoading: "Cargando ranking anual...",
|
annualLoading: "Cargando ranking anual...",
|
||||||
annualMissing:
|
annualMissing:
|
||||||
"No hay snapshot generado para el ano solicitado. Mostrara estado missing hasta que exista.",
|
"No hay snapshot generado para el a\u00f1o solicitado. Mostrar\u00e1 estado pending hasta que exista.",
|
||||||
annualReadyEmpty:
|
annualReadyEmpty:
|
||||||
"Snapshot anual listo pero sin datos para el ano y servidor seleccionado.",
|
"Ranking anual listo, pero sin datos para el a\u00f1o y servidor seleccionados.",
|
||||||
annualUnsupportedMetric:
|
annualUnsupportedMetric:
|
||||||
"La metrica anual solicitada no esta soportada en V1.",
|
"La m\u00e9trica anual solicitada no est\u00e1 soportada en V1.",
|
||||||
annualMetricInvalid:
|
annualMetricInvalid:
|
||||||
"Parametro de ranking anual invalido. Usa metric=kills en V1.",
|
"Par\u00e1metro de ranking anual inv\u00e1lido. Usa metric=kills en V1.",
|
||||||
annualReadyPrefix: "Ranking anual listo para",
|
annualReadyPrefix: "Ranking anual listo para",
|
||||||
weeklyPlaceholder:
|
weeklyPlaceholder:
|
||||||
"Sin datos semanales. El ranking semanal se actualiza al cargar un jugador.",
|
"Sin datos semanales. El ranking semanal se actualiza al cargar un jugador.",
|
||||||
@@ -69,7 +69,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
monthlyWindowUnavailableSummary:
|
monthlyWindowUnavailableSummary:
|
||||||
"Resumen mensual no disponible temporalmente.",
|
"Resumen mensual no disponible temporalmente.",
|
||||||
profileReadyTitle: "Perfil personal",
|
profileReadyTitle: "Perfil personal",
|
||||||
profileEmptyTitle: "Selecciona un jugador para ver sus estadisticas.",
|
profileEmptyTitle: "Selecciona un jugador para ver sus estad\u00edsticas.",
|
||||||
partialProfileLoadWarning:
|
partialProfileLoadWarning:
|
||||||
"Algunos bloques de ranking no se cargaron; se mantienen los disponibles.",
|
"Algunos bloques de ranking no se cargaron; se mantienen los disponibles.",
|
||||||
};
|
};
|
||||||
@@ -78,8 +78,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
if (searchHelpNode) {
|
if (searchHelpNode) {
|
||||||
searchHelpNode.textContent =
|
searchHelpNode.textContent =
|
||||||
"Usa el buscador para encontrar un jugador. Al seleccionar uno veras resumen semanal y mensual. " +
|
"Usa el buscador para encontrar un jugador. Al seleccionar uno ver\u00e1s resumen semanal y mensual. " +
|
||||||
"El ranking anual se consulta por separado con el ano indicado.";
|
"El ranking anual se consulta por separado con el a\u00f1o indicado.";
|
||||||
}
|
}
|
||||||
|
|
||||||
setBackendState(messages.backendChecking, false);
|
setBackendState(messages.backendChecking, false);
|
||||||
@@ -176,7 +176,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
setBackendState(messages.backendOnline, true);
|
setBackendState(messages.backendOnline, true);
|
||||||
setAnnualState(
|
setAnnualState(
|
||||||
"neutral",
|
"neutral",
|
||||||
"Backend disponible. Selecciona un ano para cargar el ranking anual (kills).",
|
"Backend disponible. Selecciona un a\u00f1o para cargar el ranking anual (kills).",
|
||||||
);
|
);
|
||||||
void loadAnnualRanking();
|
void loadAnnualRanking();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -252,7 +252,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
const year = resolveAnnualYear();
|
const year = resolveAnnualYear();
|
||||||
if (year === null) {
|
if (year === null) {
|
||||||
setAnnualState("error", "El ano ingresado no es valido.");
|
setAnnualState("error", "El a\u00f1o ingresado no es v\u00e1lido.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
setAnnualState(
|
setAnnualState(
|
||||||
"neutral",
|
"neutral",
|
||||||
`${messages.annualReadyPrefix} ${serverId}, ano ${year}, metrica ${metric}`,
|
`${messages.annualReadyPrefix} ${serverId}, a\u00f1o ${year}, m\u00e9trica ${metric}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
annualContentNode.innerHTML = `
|
annualContentNode.innerHTML = `
|
||||||
@@ -353,7 +353,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
<p class="stats-summary-title">Top ${limit} anual</p>
|
<p class="stats-summary-title">Top ${limit} anual</p>
|
||||||
<div class="stats-annual-meta">
|
<div class="stats-annual-meta">
|
||||||
<p><strong>Servidor:</strong> ${escapeHtml(serverId)}</p>
|
<p><strong>Servidor:</strong> ${escapeHtml(serverId)}</p>
|
||||||
<p><strong>Metrica:</strong> ${escapeHtml(metric)}</p>
|
<p><strong>M\u00e9trica:</strong> ${escapeHtml(metric)}</p>
|
||||||
<p><strong>Partidas fuente:</strong> ${safeInt(sourceMatches, 0)}</p>
|
<p><strong>Partidas fuente:</strong> ${safeInt(sourceMatches, 0)}</p>
|
||||||
<p><strong>Actualizado:</strong> ${escapeHtml(generatedAt || "No disponible")}</p>
|
<p><strong>Actualizado:</strong> ${escapeHtml(generatedAt || "No disponible")}</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -755,8 +755,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
const metric = escapeHtml(String(ranking.metric || annualMetric));
|
const metric = escapeHtml(String(ranking.metric || annualMetric));
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<p><strong>Posicion:</strong> ${rank}</p>
|
<p><strong>Posici\u00f3n:</strong> ${rank}</p>
|
||||||
<p><strong>Metric:</strong> ${metric}</p>
|
<p><strong>M\u00e9trica:</strong> ${metric}</p>
|
||||||
<p>${escapeHtml(formatWindowRange(ranking))}</p>
|
<p>${escapeHtml(formatWindowRange(ranking))}</p>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -783,7 +783,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
if (Number.isFinite(safeParseNumber(ranking.ranking_position))) {
|
if (Number.isFinite(safeParseNumber(ranking.ranking_position))) {
|
||||||
return {
|
return {
|
||||||
tone: "ok",
|
tone: "ok",
|
||||||
title: `Posicion #${safeInt(ranking.ranking_position, 0)}`,
|
title: `Posici\u00f3n #${safeInt(ranking.ranking_position, 0)}`,
|
||||||
detail: `Jugador posicionado en el ranking ${label} activo por kills.`,
|
detail: `Jugador posicionado en el ranking ${label} activo por kills.`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -902,3 +902,4 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
.replaceAll("'", "'");
|
.replaceAll("'", "'");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,35 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="es">
|
<html lang="es">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Historico propio de HLL Vietnam con ranking semanal y partidas recientes por servidor."
|
content="Histórico propio de HLL Vietnam con ranking semanal y partidas recientes por servidor."
|
||||||
/>
|
/>
|
||||||
<title>Historico - HLL Vietnam</title>
|
<title>Histórico - HLL Vietnam</title>
|
||||||
<link rel="stylesheet" href="./assets/css/styles.css" />
|
<link rel="stylesheet" href="./assets/css/styles.css" />
|
||||||
<link rel="stylesheet" href="./assets/css/historico.css" />
|
<link rel="stylesheet" href="./assets/css/historico.css" />
|
||||||
</head>
|
</head>
|
||||||
<body data-backend-base-url="http://127.0.0.1:8000">
|
<body data-backend-base-url="http://127.0.0.1:8000">
|
||||||
<div class="page-shell historical-shell">
|
<div class="page-shell historical-shell">
|
||||||
|
<nav class="public-nav" aria-label="Navegación pública principal">
|
||||||
|
<a class="public-nav__link" href="./index.html">
|
||||||
|
Inicio
|
||||||
|
</a>
|
||||||
|
<a class="public-nav__link is-active" href="./historico.html" aria-current="page">
|
||||||
|
Histórico
|
||||||
|
</a>
|
||||||
|
<a class="public-nav__link" href="./stats.html">
|
||||||
|
Stats
|
||||||
|
</a>
|
||||||
|
<a class="public-nav__link" href="./ranking.html">
|
||||||
|
Ranking
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
<header class="hero historical-hero">
|
<header class="hero historical-hero">
|
||||||
<div class="hero__overlay"></div>
|
<div class="hero__overlay"></div>
|
||||||
<div class="hero__content historical-hero__content">
|
<div class="hero__content historical-hero__content">
|
||||||
<div class="historical-hero__topline">
|
|
||||||
<a class="secondary-button secondary-button--ghost" href="./index.html">
|
|
||||||
VOLVER INICIO
|
|
||||||
</a>
|
|
||||||
<a class="secondary-button secondary-button--ghost" href="./stats.html">
|
|
||||||
STATS
|
|
||||||
</a>
|
|
||||||
<p class="eyebrow">Historico propio</p>
|
|
||||||
</div>
|
|
||||||
<div class="historical-hero__layout historical-hero__layout--registry">
|
<div class="historical-hero__layout historical-hero__layout--registry">
|
||||||
<div class="logo-frame historical-logo-frame">
|
<div class="logo-frame historical-logo-frame">
|
||||||
<img
|
<img
|
||||||
@@ -38,6 +43,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="historical-hero__copy">
|
<div class="historical-hero__copy">
|
||||||
<div>
|
<div>
|
||||||
|
<p class="eyebrow eyebrow--section">Histórico propio</p>
|
||||||
<h1 class="historical-hero__title">
|
<h1 class="historical-hero__title">
|
||||||
Registro de la
|
Registro de la
|
||||||
<span class="hero__title-accent">Comunidad Hispana</span>
|
<span class="hero__title-accent">Comunidad Hispana</span>
|
||||||
@@ -47,7 +53,7 @@
|
|||||||
de nuestros servidores.
|
de nuestros servidores.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="historical-selector" aria-label="Seleccion de servidor">
|
<div class="historical-selector" aria-label="Selección de servidor">
|
||||||
<button
|
<button
|
||||||
class="historical-selector__button is-active"
|
class="historical-selector__button is-active"
|
||||||
type="button"
|
type="button"
|
||||||
@@ -96,7 +102,7 @@
|
|||||||
<div class="historical-summary-grid" id="historical-summary">
|
<div class="historical-summary-grid" id="historical-summary">
|
||||||
<article class="historical-stat-card">
|
<article class="historical-stat-card">
|
||||||
<p>Estado</p>
|
<p>Estado</p>
|
||||||
<strong>Cargando datos historicos</strong>
|
<strong>Cargando datos históricos</strong>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -106,7 +112,7 @@
|
|||||||
<div class="panel__shell">
|
<div class="panel__shell">
|
||||||
<div class="panel__header historical-panel__header">
|
<div class="panel__header historical-panel__header">
|
||||||
<div>
|
<div>
|
||||||
<p class="eyebrow eyebrow--section">Rankings historicos</p>
|
<p class="eyebrow eyebrow--section">Rankings históricos</p>
|
||||||
<h2 id="weekly-ranking-title">Ranking del alcance activo</h2>
|
<h2 id="weekly-ranking-title">Ranking del alcance activo</h2>
|
||||||
<p class="historical-panel__note" id="weekly-window-note">
|
<p class="historical-panel__note" id="weekly-window-note">
|
||||||
Cargando rango del ranking...
|
Cargando rango del ranking...
|
||||||
@@ -144,7 +150,7 @@
|
|||||||
class="historical-tabs"
|
class="historical-tabs"
|
||||||
id="weekly-leaderboard-tabs"
|
id="weekly-leaderboard-tabs"
|
||||||
role="tablist"
|
role="tablist"
|
||||||
aria-label="Metricas del ranking"
|
aria-label="Métricas del ranking"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="historical-tab is-active"
|
class="historical-tab is-active"
|
||||||
@@ -207,7 +213,7 @@
|
|||||||
<div class="panel__header historical-panel__header">
|
<div class="panel__header historical-panel__header">
|
||||||
<div>
|
<div>
|
||||||
<p class="eyebrow eyebrow--section">Partidas recientes</p>
|
<p class="eyebrow eyebrow--section">Partidas recientes</p>
|
||||||
<h2 id="recent-matches-title">Ultimas partidas registradas</h2>
|
<h2 id="recent-matches-title">Últimas partidas registradas</h2>
|
||||||
<p class="historical-panel__note" id="recent-matches-note">
|
<p class="historical-panel__note" id="recent-matches-note">
|
||||||
Lista de partidas ya registradas.
|
Lista de partidas ya registradas.
|
||||||
</p>
|
</p>
|
||||||
@@ -230,3 +236,4 @@
|
|||||||
<script src="./assets/js/historico-recent-live.js"></script>
|
<script src="./assets/js/historico-recent-live.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,20 @@
|
|||||||
data-server-refresh-ms="300000"
|
data-server-refresh-ms="300000"
|
||||||
>
|
>
|
||||||
<div class="page-shell">
|
<div class="page-shell">
|
||||||
|
<nav class="public-nav" aria-label="Navegación pública principal">
|
||||||
|
<a class="public-nav__link is-active" href="./index.html" aria-current="page">
|
||||||
|
Inicio
|
||||||
|
</a>
|
||||||
|
<a class="public-nav__link" href="./historico.html">
|
||||||
|
Histórico
|
||||||
|
</a>
|
||||||
|
<a class="public-nav__link" href="./stats.html">
|
||||||
|
Stats
|
||||||
|
</a>
|
||||||
|
<a class="public-nav__link" href="./ranking.html">
|
||||||
|
Ranking
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
<header class="hero">
|
<header class="hero">
|
||||||
<div class="hero__overlay"></div>
|
<div class="hero__overlay"></div>
|
||||||
<div class="hero__content">
|
<div class="hero__content">
|
||||||
@@ -36,7 +50,7 @@
|
|||||||
<span class="hero__title-accent">HLL</span>
|
<span class="hero__title-accent">HLL</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="hero__text">
|
<p class="hero__text">
|
||||||
Centro de reunion para escuadras, eventos y acceso directo al
|
Centro de reunión para escuadras, eventos y acceso directo al
|
||||||
Discord oficial de la comunidad.
|
Discord oficial de la comunidad.
|
||||||
</p>
|
</p>
|
||||||
<div class="hero__actions">
|
<div class="hero__actions">
|
||||||
@@ -48,15 +62,6 @@
|
|||||||
>
|
>
|
||||||
Unirse al Discord
|
Unirse al Discord
|
||||||
</a>
|
</a>
|
||||||
<a class="secondary-button" href="./stats.html">
|
|
||||||
Stats
|
|
||||||
</a>
|
|
||||||
<a class="secondary-button" href="./ranking.html">
|
|
||||||
Ranking
|
|
||||||
</a>
|
|
||||||
<a class="secondary-button" href="./historico.html">
|
|
||||||
Ver historico propio
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -88,7 +93,7 @@
|
|||||||
<div class="panel__shell">
|
<div class="panel__shell">
|
||||||
<div class="panel__header panel__header--servers">
|
<div class="panel__header panel__header--servers">
|
||||||
<div>
|
<div>
|
||||||
<p class="eyebrow eyebrow--section">Servidores públicos</p>
|
<p class="eyebrow eyebrow--section">Servidores públicos</p>
|
||||||
<h2 id="servers-title">Estado actual de servidores</h2>
|
<h2 id="servers-title">Estado actual de servidores</h2>
|
||||||
</div>
|
</div>
|
||||||
<p class="status-chip status-chip--fallback" id="servers-badge">
|
<p class="status-chip status-chip--fallback" id="servers-badge">
|
||||||
@@ -96,11 +101,11 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p class="panel__intro panel__intro--tight">
|
<p class="panel__intro panel__intro--tight">
|
||||||
El panel muestra el ultimo estado disponible consultado de los servidores.
|
El panel muestra el último estado disponible consultado de los servidores.
|
||||||
</p>
|
</p>
|
||||||
<div class="panel__actions panel__actions--compact">
|
<div class="panel__actions panel__actions--compact">
|
||||||
<a class="secondary-button secondary-button--compact" href="./historico.html">
|
<a class="secondary-button secondary-button--compact" href="./historico.html">
|
||||||
Abrir zona historico
|
Abrir zona histórico
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="servers-grid" id="servers-list" aria-live="polite">
|
<div class="servers-grid" id="servers-list" aria-live="polite">
|
||||||
@@ -132,3 +137,4 @@
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,44 +1,54 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="es">
|
<html lang="es">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Ranking global de HLL Vietnam con filtros por periodo, servidor y limite."
|
content="Ranking global de HLL Vietnam con filtros por periodo, servidor y límite."
|
||||||
/>
|
/>
|
||||||
<title>Ranking - HLL Vietnam</title>
|
<title>Ranking - HLL Vietnam</title>
|
||||||
<link rel="stylesheet" href="./assets/css/styles.css" />
|
<link rel="stylesheet" href="./assets/css/styles.css" />
|
||||||
</head>
|
</head>
|
||||||
<body data-backend-base-url="http://127.0.0.1:8000">
|
<body data-backend-base-url="http://127.0.0.1:8000">
|
||||||
<div class="page-shell stats-page-shell">
|
<div class="page-shell stats-page-shell">
|
||||||
|
<nav class="public-nav" aria-label="Navegación pública principal">
|
||||||
|
<a class="public-nav__link" href="./index.html">
|
||||||
|
Inicio
|
||||||
|
</a>
|
||||||
|
<a class="public-nav__link" href="./historico.html">
|
||||||
|
Histórico
|
||||||
|
</a>
|
||||||
|
<a class="public-nav__link" href="./stats.html">
|
||||||
|
Stats
|
||||||
|
</a>
|
||||||
|
<a class="public-nav__link is-active" href="./ranking.html" aria-current="page">
|
||||||
|
Ranking
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
<header class="hero stats-hero ranking-hero">
|
<header class="hero stats-hero ranking-hero">
|
||||||
<div class="hero__overlay"></div>
|
<div class="hero__overlay"></div>
|
||||||
<div class="hero__content">
|
<div class="hero__content">
|
||||||
|
<div class="hero__brand">
|
||||||
|
<div class="logo-frame">
|
||||||
|
<img
|
||||||
|
src="./assets/img/logo.png"
|
||||||
|
alt="Logo oficial de la comunidad HLL Vietnam"
|
||||||
|
class="logo-frame__image"
|
||||||
|
width="1024"
|
||||||
|
height="1044"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div class="hero__copy">
|
<div class="hero__copy">
|
||||||
<p class="eyebrow eyebrow--section">Seccion Ranking</p>
|
<p class="eyebrow eyebrow--section">Sección Ranking</p>
|
||||||
<h1 class="hero__title">
|
<h1 class="hero__title">
|
||||||
Ranking
|
Ranking
|
||||||
<span class="hero__title-accent">Global</span>
|
<span class="hero__title-accent">Global</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="hero__text">
|
<p class="hero__text">
|
||||||
Consulta los lideres publicos por metrica con lectura RCON-first,
|
Consulta los líderes públicos de la comunidad, cambia de periodo y servidor sin salir de la página y revisa quién destaca en cada ventana.
|
||||||
cambia periodo y servidor sin salir de la pagina, y deja Stats para
|
|
||||||
revisar el rendimiento de un jugador concreto.
|
|
||||||
</p>
|
</p>
|
||||||
<p class="status-chip status-chip--fallback" id="ranking-backend-state">
|
|
||||||
Comprobando disponibilidad del backend
|
|
||||||
</p>
|
|
||||||
<div class="hero__actions stats__hero-actions">
|
|
||||||
<a class="secondary-button secondary-button--ghost" href="./index.html">
|
|
||||||
Volver al inicio
|
|
||||||
</a>
|
|
||||||
<a class="secondary-button secondary-button--compact" href="./stats.html">
|
|
||||||
Stats
|
|
||||||
</a>
|
|
||||||
<a class="secondary-button secondary-button--compact" href="./historico.html">
|
|
||||||
Historico
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -49,11 +59,10 @@
|
|||||||
<div class="panel__shell">
|
<div class="panel__shell">
|
||||||
<div class="panel__header">
|
<div class="panel__header">
|
||||||
<p class="eyebrow eyebrow--section">Filtros de lectura</p>
|
<p class="eyebrow eyebrow--section">Filtros de lectura</p>
|
||||||
<h2>Top publico por ventana</h2>
|
<h2>Top público por ventana</h2>
|
||||||
</div>
|
</div>
|
||||||
<p class="panel__intro panel__intro--tight">
|
<p class="panel__intro panel__intro--tight">
|
||||||
El ranking expone solo la lectura publica de lideres. Para busqueda
|
El ranking expone la lectura pública de líderes. Para búsqueda individual usa la sección Stats.
|
||||||
individual usa la seccion Stats.
|
|
||||||
</p>
|
</p>
|
||||||
<form class="ranking-form" id="ranking-form">
|
<form class="ranking-form" id="ranking-form">
|
||||||
<div class="ranking-form__grid">
|
<div class="ranking-form__grid">
|
||||||
@@ -74,7 +83,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<label class="stats-search-form__label" for="ranking-metric">
|
<label class="stats-search-form__label" for="ranking-metric">
|
||||||
Metrica
|
Métrica
|
||||||
<select class="ranking-select" id="ranking-metric" name="metric">
|
<select class="ranking-select" id="ranking-metric" name="metric">
|
||||||
<option value="kills">Kills totales</option>
|
<option value="kills">Kills totales</option>
|
||||||
<option value="deaths">Deaths</option>
|
<option value="deaths">Deaths</option>
|
||||||
@@ -85,7 +94,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<label class="stats-search-form__label" for="ranking-limit">
|
<label class="stats-search-form__label" for="ranking-limit">
|
||||||
Limite
|
Límite
|
||||||
<select class="ranking-select" id="ranking-limit" name="limit">
|
<select class="ranking-select" id="ranking-limit" name="limit">
|
||||||
<option value="5">Top 5</option>
|
<option value="5">Top 5</option>
|
||||||
<option value="10">Top 10</option>
|
<option value="10">Top 10</option>
|
||||||
@@ -95,7 +104,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<label class="stats-search-form__label" for="ranking-year" id="ranking-year-wrap" hidden>
|
<label class="stats-search-form__label" for="ranking-year" id="ranking-year-wrap" hidden>
|
||||||
Ano
|
Año
|
||||||
<input
|
<input
|
||||||
class="stats-search-input"
|
class="stats-search-input"
|
||||||
id="ranking-year"
|
id="ranking-year"
|
||||||
@@ -109,7 +118,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<p class="ranking-form__note" id="ranking-filter-note">
|
<p class="ranking-form__note" id="ranking-filter-note">
|
||||||
Ranking compara top globales. Para buscar un jugador concreto usa Stats.
|
Consulta líderes públicos y cambia de periodo o servidor sin salir de la página.
|
||||||
</p>
|
</p>
|
||||||
<div class="hero__actions ranking-form__actions">
|
<div class="hero__actions ranking-form__actions">
|
||||||
<button class="discord-button" type="submit">Actualizar ranking</button>
|
<button class="discord-button" type="submit">Actualizar ranking</button>
|
||||||
@@ -159,3 +168,4 @@
|
|||||||
<script src="./assets/js/ranking.js"></script>
|
<script src="./assets/js/ranking.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
@@ -1,43 +1,54 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="es">
|
<html lang="es">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Consulta estadisticas personales de jugadores en el panel Stats de HLL Vietnam."
|
content="Consulta estadísticas personales de jugadores en el panel Stats de HLL Vietnam."
|
||||||
/>
|
/>
|
||||||
<title>Stats - HLL Vietnam</title>
|
<title>Stats - HLL Vietnam</title>
|
||||||
<link rel="stylesheet" href="./assets/css/styles.css" />
|
<link rel="stylesheet" href="./assets/css/styles.css" />
|
||||||
</head>
|
</head>
|
||||||
<body data-backend-base-url="http://127.0.0.1:8000">
|
<body data-backend-base-url="http://127.0.0.1:8000">
|
||||||
<div class="page-shell stats-page-shell">
|
<div class="page-shell stats-page-shell">
|
||||||
|
<nav class="public-nav" aria-label="Navegación pública principal">
|
||||||
|
<a class="public-nav__link" href="./index.html">
|
||||||
|
Inicio
|
||||||
|
</a>
|
||||||
|
<a class="public-nav__link" href="./historico.html">
|
||||||
|
Histórico
|
||||||
|
</a>
|
||||||
|
<a class="public-nav__link is-active" href="./stats.html" aria-current="page">
|
||||||
|
Stats
|
||||||
|
</a>
|
||||||
|
<a class="public-nav__link" href="./ranking.html">
|
||||||
|
Ranking
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
<header class="hero stats-hero">
|
<header class="hero stats-hero">
|
||||||
<div class="hero__overlay"></div>
|
<div class="hero__overlay"></div>
|
||||||
<div class="hero__content">
|
<div class="hero__content">
|
||||||
|
<div class="hero__brand">
|
||||||
|
<div class="logo-frame">
|
||||||
|
<img
|
||||||
|
src="./assets/img/logo.png"
|
||||||
|
alt="Logo oficial de la comunidad HLL Vietnam"
|
||||||
|
class="logo-frame__image"
|
||||||
|
width="1024"
|
||||||
|
height="1044"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div class="hero__copy">
|
<div class="hero__copy">
|
||||||
<p class="eyebrow eyebrow--section">Seccion Stats</p>
|
<p class="eyebrow eyebrow--section">Sección Stats</p>
|
||||||
<h1 class="hero__title">
|
<h1 class="hero__title">
|
||||||
Estadisticas
|
Estadísticas
|
||||||
<span class="hero__title-accent">Personales</span>
|
<span class="hero__title-accent">Personales</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="hero__text">
|
<p class="hero__text">
|
||||||
Busca un jugador por nombre o ID y revisa sus resultados semanales, mensuales
|
Busca un jugador por nombre o ID y revisa sus resultados semanales, mensuales y ranking anual.
|
||||||
y ranking anual con base en datos materializados.
|
|
||||||
</p>
|
</p>
|
||||||
<p class="status-chip status-chip--fallback" id="stats-backend-state">
|
|
||||||
Comprobando disponibilidad del backend
|
|
||||||
</p>
|
|
||||||
<div class="hero__actions stats__hero-actions">
|
|
||||||
<a class="secondary-button secondary-button--ghost" href="./index.html">
|
|
||||||
Volver al inicio
|
|
||||||
</a>
|
|
||||||
<a class="secondary-button secondary-button--compact" href="./ranking.html">
|
|
||||||
Ranking
|
|
||||||
</a>
|
|
||||||
<a class="secondary-button secondary-button--compact" href="./historico.html">
|
|
||||||
Historico
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -51,7 +62,7 @@
|
|||||||
<h2>Buscar por nombre o ID</h2>
|
<h2>Buscar por nombre o ID</h2>
|
||||||
</div>
|
</div>
|
||||||
<p class="panel__intro panel__intro--tight" id="stats-search-help">
|
<p class="panel__intro panel__intro--tight" id="stats-search-help">
|
||||||
Usa al menos 1 caracter para buscar. Al seleccionar un jugador se cargan sus
|
Usa al menos 1 carácter para buscar. Al seleccionar un jugador se cargarán sus
|
||||||
stats y ranking semanal y mensual. El ranking anual se consulta por separado.
|
stats y ranking semanal y mensual. El ranking anual se consulta por separado.
|
||||||
</p>
|
</p>
|
||||||
<form class="stats-search-form" id="stats-search-form">
|
<form class="stats-search-form" id="stats-search-form">
|
||||||
@@ -66,7 +77,7 @@
|
|||||||
name="query"
|
name="query"
|
||||||
placeholder="Ej: Rambo o 76561198000000000"
|
placeholder="Ej: Rambo o 76561198000000000"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
aria-label="Texto de busqueda de jugadores"
|
aria-label="Texto de búsqueda de jugadores"
|
||||||
/>
|
/>
|
||||||
<button class="discord-button" type="submit" aria-label="Buscar jugador por nombre o ID">
|
<button class="discord-button" type="submit" aria-label="Buscar jugador por nombre o ID">
|
||||||
Buscar jugador
|
Buscar jugador
|
||||||
@@ -118,7 +129,7 @@
|
|||||||
El ranking anual usa snapshots pre-computados para evitar recalcular toda la temporada en cada consulta.
|
El ranking anual usa snapshots pre-computados para evitar recalcular toda la temporada en cada consulta.
|
||||||
</p>
|
</p>
|
||||||
<form class="stats-annual-form" id="stats-annual-form">
|
<form class="stats-annual-form" id="stats-annual-form">
|
||||||
<label class="stats-search-form__label" for="stats-annual-year">Ano</label>
|
<label class="stats-search-form__label" for="stats-annual-year">Año</label>
|
||||||
<div class="stats-search-form__fields">
|
<div class="stats-search-form__fields">
|
||||||
<input
|
<input
|
||||||
class="stats-search-input"
|
class="stats-search-input"
|
||||||
@@ -126,7 +137,7 @@
|
|||||||
type="number"
|
type="number"
|
||||||
min="2019"
|
min="2019"
|
||||||
value=""
|
value=""
|
||||||
aria-label="Ano del ranking anual"
|
aria-label="Año del ranking anual"
|
||||||
aria-describedby="stats-annual-state"
|
aria-describedby="stats-annual-state"
|
||||||
/>
|
/>
|
||||||
<button class="discord-button" type="submit" aria-label="Cargar ranking anual">
|
<button class="discord-button" type="submit" aria-label="Cargar ranking anual">
|
||||||
@@ -135,7 +146,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<p class="stats-state stats-state--neutral" id="stats-annual-state" role="status" aria-live="polite">
|
<p class="stats-state stats-state--neutral" id="stats-annual-state" role="status" aria-live="polite">
|
||||||
Esperando ano para cargar el ranking anual (Top 20 por kills).
|
Esperando año para cargar el ranking anual (Top 20 por kills).
|
||||||
</p>
|
</p>
|
||||||
<div class="stats-annual-table-wrap" id="stats-annual-content" aria-live="polite"></div>
|
<div class="stats-annual-table-wrap" id="stats-annual-content" aria-live="polite"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -147,3 +158,4 @@
|
|||||||
<script src="./assets/js/stats.js"></script>
|
<script src="./assets/js/stats.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user