Traduccion para paginas de atleta
This commit is contained in:
parent
56cba7f7ab
commit
e6a45a0369
|
@ -4,45 +4,65 @@
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>Panel del Atleta</title>
|
<title>Panel del Atleta</title>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet" />
|
||||||
<link href="css/estiloAtletaSimulador.css" rel="stylesheet" />
|
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="css/estiloAtletaSimulador.css"/>
|
||||||
|
<link rel="stylesheet" href="css/navbar.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-light">
|
<body class="bg-light">
|
||||||
|
|
||||||
|
<!-- NAV -->
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary sticky-top shadow-sm px-4 py-3">
|
<nav class="navbar navbar-expand-lg navbar-dark bg-primary sticky-top shadow-sm px-4 py-3">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand fw-bold text-white">SwimmingArt</a>
|
<a class="navbar-brand fw-bold text-white">SwimmingArt</a>
|
||||||
<div class="ms-auto d-flex gap-4 align-items-center">
|
<div class="ms-auto d-flex gap-4 align-items-center">
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button class="btn btn-outline-light dropdown-toggle d-flex align-items-center gap-2 px-3 py-1" type="button" id="userDropdown" data-bs-toggle="dropdown">
|
<button class="btn btn-outline-light dropdown-toggle d-flex align-items-center gap-2 px-3 py-1" type="button" id="userDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
<svg width="20" height="20" fill="currentColor" class="bi bi-person-circle" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-person-circle" viewBox="0 0 16 16">
|
||||||
<path d="M11 10a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
|
<path d="M11 10a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
|
||||||
<path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-4.546 12.174c.03-.256.071-.512.124-.767C4.28 10.798 5.94 10 8 10s3.72.798 4.422 2.407c.053.255.094.511.124.767A7 7 0 0 0 8 1z"/>
|
<path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-4.546 12.174c.03-.256.071-.512.124-.767C4.28 10.798 5.94 10 8 10s3.72.798 4.422 2.407c.053.255.094.511.124.767A7 7 0 0 0 8 1z"/>
|
||||||
</svg>
|
</svg>
|
||||||
<span id="nombreUsuarioHeader" class="fw-semibold">Usuario</span>
|
<span id="nombreUsuarioHeader" class="fw-semibold">Usuario</span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu dropdown-menu-end text-center p-3"
|
<ul class="dropdown-menu dropdown-menu-end text-center p-3"
|
||||||
style="background-color: #0d6efd; color: white; border-radius: 0 0 8px 8px;">
|
aria-labelledby="userDropdown"
|
||||||
<li>
|
style="background-color: #0d6efd; color: white; border-radius: 0 0 8px 8px; min-width: 100%; max-width: 250px;">
|
||||||
<select id="langSelector" class="form-select form-select-sm mb-3 bg-white text-dark border-0 rounded">
|
<!-- Mostrar rol -->
|
||||||
|
<li class="mb-2">
|
||||||
|
<span id="nombreUsuarioDropdown" class="fw-semibold text-white d-block" data-i18n="role">Atleta</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Selector de idioma -->
|
||||||
|
<li class="mb-1">
|
||||||
|
<div class="d-flex align-items-center justify-content-center gap-2 w-100">
|
||||||
|
<i class="bi bi-globe" style="color: white; font-size: 1rem;"></i>
|
||||||
|
<select id="langSelector" class="form-select form-select-sm" style="border: none; border-radius: 6px; max-width: 140px;">
|
||||||
<option value="es">Español</option>
|
<option value="es">Español</option>
|
||||||
<option value="en">English</option>
|
<option value="en">English</option>
|
||||||
<option value="fr">Français</option>
|
<option value="fr">Français</option>
|
||||||
</select>
|
</select>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Botón salir -->
|
||||||
|
<li>
|
||||||
|
<button class="btn btn-danger btn-sm w-100" onclick="logout()" data-i18n="logout">Salir</button>
|
||||||
</li>
|
</li>
|
||||||
<li><button class="btn btn-danger btn-sm w-100" onclick="logout()">Salir</button></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
<!-- CONTENIDO PRINCIPAL -->
|
||||||
<div class="container py-5">
|
<div class="container py-5">
|
||||||
<h2 class="fw-bold fs-3 mb-2 text-center text-primary">Equipos Disponibles</h2>
|
<h2 class="fw-bold fs-3 mb-2 text-center text-primary" data-i18n="titulo">Equipos Disponibles</h2>
|
||||||
<p class="text-muted text-center mb-4">Consulta las competencias en las que estás asignado</p>
|
<p class="text-muted text-center mb-4" data-i18n="subtitulo">Consulta las competencias en las que estás asignado</p>
|
||||||
<div id="rutinas-list" class="row justify-content-center"></div>
|
<div id="rutinas-list" class="row justify-content-center"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Scripts -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<script src="js/atleta.js"></script>
|
<script src="js/atleta.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,9 +1,99 @@
|
||||||
document.addEventListener("DOMContentLoaded", async () => {
|
const traducciones = {
|
||||||
|
es: {
|
||||||
|
logout: "Salir",
|
||||||
|
role: "Atleta",
|
||||||
|
titulo: "Equipos Disponibles",
|
||||||
|
subtitulo: "Consulta las competencias en las que estás asignado",
|
||||||
|
sinSesion: "No se encontró tu sesión. Inicia sesión nuevamente.",
|
||||||
|
sinAsignacion: "No estás asignado a ninguna formación aún.",
|
||||||
|
errorCarga: "Error al cargar tus asignaciones.",
|
||||||
|
rutinaSinNombre: "Rutina sin nombre",
|
||||||
|
formacion: "Formación",
|
||||||
|
duracion: "Duración",
|
||||||
|
notas: "Notas",
|
||||||
|
rol: "Rol",
|
||||||
|
id: "ID",
|
||||||
|
figura: "Figura",
|
||||||
|
verSimulacion: "Ver simulación"
|
||||||
|
},
|
||||||
|
en: {
|
||||||
|
logout: "Logout",
|
||||||
|
role: "Athlete",
|
||||||
|
titulo: "Available Teams",
|
||||||
|
subtitulo: "Check the competitions you are assigned to",
|
||||||
|
sinSesion: "Session not found. Please log in again.",
|
||||||
|
sinAsignacion: "You are not assigned to any formation yet.",
|
||||||
|
errorCarga: "Error loading your assignments.",
|
||||||
|
rutinaSinNombre: "Unnamed routine",
|
||||||
|
formacion: "Formation",
|
||||||
|
duracion: "Duration",
|
||||||
|
notas: "Notes",
|
||||||
|
rol: "Role",
|
||||||
|
id: "ID",
|
||||||
|
figura: "Figure",
|
||||||
|
verSimulacion: "View simulation"
|
||||||
|
},
|
||||||
|
fr: {
|
||||||
|
logout: "Se déconnecter",
|
||||||
|
role: "Athlète",
|
||||||
|
titulo: "Équipes disponibles",
|
||||||
|
subtitulo: "Consultez les compétitions auxquelles vous êtes affecté",
|
||||||
|
sinSesion: "Session introuvable. Veuillez vous reconnecter.",
|
||||||
|
sinAsignacion: "Vous n'êtes affecté à aucune formation pour le moment.",
|
||||||
|
errorCarga: "Erreur lors du chargement de vos affectations.",
|
||||||
|
rutinaSinNombre: "Routine sans nom",
|
||||||
|
formacion: "Formation",
|
||||||
|
duracion: "Durée",
|
||||||
|
notas: "Remarques",
|
||||||
|
rol: "Rôle",
|
||||||
|
id: "ID",
|
||||||
|
figura: "Figure",
|
||||||
|
verSimulacion: "Voir la simulation"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let langActual = 'es';
|
||||||
|
|
||||||
|
function translateStatic() {
|
||||||
|
document.querySelector('[data-i18n="logout"]').textContent = traducciones[langActual].logout;
|
||||||
|
document.querySelector('h2').textContent = traducciones[langActual].titulo;
|
||||||
|
document.querySelector('p.text-muted').textContent = traducciones[langActual].subtitulo;
|
||||||
|
|
||||||
|
const rolEl = document.querySelector('[data-i18n="role"]');
|
||||||
|
if (rolEl) rolEl.textContent = traducciones[langActual].role;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('langSelector')?.addEventListener('change', async (e) => {
|
||||||
|
langActual = e.target.value;
|
||||||
|
translateStatic();
|
||||||
|
cargarAsignaciones();
|
||||||
|
|
||||||
|
const userId = sessionStorage.getItem("userId");
|
||||||
|
if (userId) {
|
||||||
|
await fetch(`/api/users/${userId}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ language: langActual })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function logout() {
|
||||||
|
sessionStorage.clear();
|
||||||
|
alert("Sesión cerrada");
|
||||||
|
window.location.href = "../index.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
function verSimulador(rutinaId, index) {
|
||||||
|
window.location.href = `simulador.html?routineId=${rutinaId}&formationIndex=${index}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function cargarAsignaciones() {
|
||||||
const atletaId = sessionStorage.getItem("userId");
|
const atletaId = sessionStorage.getItem("userId");
|
||||||
const contenedor = document.getElementById("rutinas-list");
|
const contenedor = document.getElementById("rutinas-list");
|
||||||
|
|
||||||
if (!atletaId) {
|
if (!atletaId) {
|
||||||
contenedor.innerHTML = "<p>No se encontró tu sesión. Inicia sesión nuevamente.</p>";
|
contenedor.innerHTML = `<p>${traducciones[langActual].sinSesion}</p>`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,27 +103,28 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||||
|
|
||||||
const formaciones = await res.json();
|
const formaciones = await res.json();
|
||||||
if (formaciones.length === 0) {
|
if (formaciones.length === 0) {
|
||||||
contenedor.innerHTML = "<p>No estás asignado a ninguna formación aún.</p>";
|
contenedor.innerHTML = `<p>${traducciones[langActual].sinAsignacion}</p>`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contenedor.innerHTML = '';
|
||||||
formaciones.forEach(f => {
|
formaciones.forEach(f => {
|
||||||
const card = document.createElement("div");
|
const card = document.createElement("div");
|
||||||
card.className = "card text-start my-3 shadow-sm";
|
card.className = "card text-start my-3 shadow-sm";
|
||||||
|
|
||||||
card.innerHTML = `
|
card.innerHTML = `
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title text-primary fw-bold">${f.rutinaNombre || "Rutina sin nombre"}</h5>
|
<h5 class="card-title text-primary fw-bold">${f.rutinaNombre || traducciones[langActual].rutinaSinNombre}</h5>
|
||||||
<h6 class="card-subtitle mb-2 text-muted">Formación: ${f.nombreColoquial || "(sin nombre)"}</h6>
|
<h6 class="card-subtitle mb-2 text-muted">${traducciones[langActual].formacion}: ${f.nombreColoquial || "(sin nombre)"}</h6>
|
||||||
<p class="card-text small mb-1">
|
<p class="card-text small mb-1">
|
||||||
<strong>Duración:</strong> ${f.duracion || "?"}s<br>
|
<strong>${traducciones[langActual].duracion}:</strong> ${f.duracion || "?"}s<br>
|
||||||
<strong>Notas:</strong> ${f.notasTacticas || "Sin notas"}<br>
|
<strong>${traducciones[langActual].notas}:</strong> ${f.notasTacticas || "—"}<br>
|
||||||
<strong>Rol:</strong> ${f.atleta.rol || "N/A"} |
|
<strong>${traducciones[langActual].rol}:</strong> ${f.atleta.rol || "N/A"} |
|
||||||
<strong>ID:</strong> ${f.atleta.idPersonalizado || "N/A"} |
|
<strong>${traducciones[langActual].id}:</strong> ${f.atleta.idPersonalizado || "N/A"} |
|
||||||
<strong>Figura:</strong> ${f.atleta.figura || "—"}
|
<strong>${traducciones[langActual].figura}:</strong> ${f.atleta.figura || "—"}
|
||||||
</p>
|
</p>
|
||||||
<button class="btn btn-sm btn-outline-success" onclick="verSimulador('${f.rutinaId}', ${f.index})">
|
<button class="btn btn-sm btn-outline-success" onclick="verSimulador('${f.rutinaId}', ${f.index})">
|
||||||
Ver simulación
|
${traducciones[langActual].verSimulacion}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@ -41,24 +132,12 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("❌ Error al obtener formaciones:", err);
|
console.error("❌ Error al obtener formaciones:", err);
|
||||||
contenedor.innerHTML = "<p>Error al cargar tus asignaciones.</p>";
|
contenedor.innerHTML = `<p>${traducciones[langActual].errorCarga}</p>`;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
function verSimulador(rutinaId, index) {
|
|
||||||
window.location.href = `simulador.html?routineId=${rutinaId}&formationIndex=${index}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function logout() {
|
async function loadUserInfoYIdioma() {
|
||||||
sessionStorage.clear();
|
|
||||||
alert("Sesión cerrada");
|
|
||||||
window.location.href = "../index.html";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mostrar nombre de usuario
|
|
||||||
window.addEventListener("DOMContentLoaded", async () => {
|
|
||||||
const userId = sessionStorage.getItem("userId");
|
const userId = sessionStorage.getItem("userId");
|
||||||
|
|
||||||
if (!userId) return;
|
if (!userId) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -68,7 +147,18 @@ window.addEventListener("DOMContentLoaded", async () => {
|
||||||
if (user?.name) {
|
if (user?.name) {
|
||||||
document.getElementById("nombreUsuarioHeader").textContent = user.name;
|
document.getElementById("nombreUsuarioHeader").textContent = user.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user?.language && traducciones[user.language]) {
|
||||||
|
langActual = user.language;
|
||||||
|
const selector = document.getElementById('langSelector');
|
||||||
|
if (selector) selector.value = langActual;
|
||||||
|
}
|
||||||
|
|
||||||
|
translateStatic();
|
||||||
|
cargarAsignaciones();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("❌ Error al obtener usuario:", err);
|
console.error("❌ Error al obtener usuario:", err);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", loadUserInfoYIdioma);
|
||||||
|
|
|
@ -1,7 +1,92 @@
|
||||||
|
const traducciones = {
|
||||||
|
es: {
|
||||||
|
"nav.init": "Panel Atleta",
|
||||||
|
logout: "Salir",
|
||||||
|
role: "Atleta",
|
||||||
|
"sim.title": "Cargando rutina...",
|
||||||
|
"sim.play": "▶ Reproducir",
|
||||||
|
"sim.pause": "⏸ Pausar",
|
||||||
|
"sim.timeline": "Línea de Tiempo"
|
||||||
|
},
|
||||||
|
en: {
|
||||||
|
"nav.init": "Athlete Panel",
|
||||||
|
logout: "Logout",
|
||||||
|
role: "Athlete",
|
||||||
|
"sim.title": "Loading routine...",
|
||||||
|
"sim.play": "▶ Play",
|
||||||
|
"sim.pause": "⏸ Pause",
|
||||||
|
"sim.timeline": "Timeline"
|
||||||
|
},
|
||||||
|
fr: {
|
||||||
|
"nav.init": "Panneau Athlète",
|
||||||
|
logout: "Se déconnecter",
|
||||||
|
role: "Athlète",
|
||||||
|
"sim.title": "Chargement de la routine...",
|
||||||
|
"sim.play": "▶ Lecture",
|
||||||
|
"sim.pause": "⏸ Pause",
|
||||||
|
"sim.timeline": "Ligne du Temps"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let langActual = 'es';
|
||||||
|
|
||||||
|
function t(clave) {
|
||||||
|
return traducciones[langActual]?.[clave] || clave;
|
||||||
|
}
|
||||||
|
|
||||||
|
function translateStatic() {
|
||||||
|
const mapping = {
|
||||||
|
'nav.init': '[data-i18n="nav.init"]',
|
||||||
|
'logout': '[data-i18n="logout"]',
|
||||||
|
'sim.title': '#tituloRutina',
|
||||||
|
'sim.timeline': '[data-i18n="sim.timeline"]',
|
||||||
|
'sim.play': '#playPauseBtn',
|
||||||
|
'role': '[data-i18n="role"]'
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const [clave, selector] of Object.entries(mapping)) {
|
||||||
|
const el = document.querySelector(selector);
|
||||||
|
if (el) el.textContent = t(clave);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('langSelector')?.addEventListener('change', async (e) => {
|
||||||
|
langActual = e.target.value;
|
||||||
|
translateStatic();
|
||||||
|
|
||||||
|
const userId = sessionStorage.getItem("userId");
|
||||||
|
if (userId) {
|
||||||
|
await fetch(`/api/users/${userId}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ language: langActual })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", async () => {
|
document.addEventListener("DOMContentLoaded", async () => {
|
||||||
const rutinaId = new URLSearchParams(window.location.search).get("routineId");
|
const rutinaId = new URLSearchParams(window.location.search).get("routineId");
|
||||||
const formationIndex = parseInt(new URLSearchParams(window.location.search).get("formationIndex"));
|
const formationIndex = parseInt(new URLSearchParams(window.location.search).get("formationIndex"));
|
||||||
|
|
||||||
|
const userId = sessionStorage.getItem("userId");
|
||||||
|
if (userId) {
|
||||||
|
try {
|
||||||
|
const user = await fetch(`/api/users/${userId}`).then(res => res.json());
|
||||||
|
if (user?.language && traducciones[user.language]) {
|
||||||
|
langActual = user.language;
|
||||||
|
const selector = document.getElementById("langSelector");
|
||||||
|
if (selector) selector.value = langActual;
|
||||||
|
}
|
||||||
|
if (user?.name) {
|
||||||
|
document.getElementById("nombreUsuarioHeader").textContent = user.name;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("❌ Error al obtener usuario:", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
translateStatic();
|
||||||
|
|
||||||
if (!rutinaId || isNaN(formationIndex)) {
|
if (!rutinaId || isNaN(formationIndex)) {
|
||||||
return alert("No se proporcionó ID de rutina o índice de formación.");
|
return alert("No se proporcionó ID de rutina o índice de formación.");
|
||||||
}
|
}
|
||||||
|
@ -22,13 +107,14 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||||
|
|
||||||
if (rutina.musicUrl) {
|
if (rutina.musicUrl) {
|
||||||
audioPlayer.src = rutina.musicUrl;
|
audioPlayer.src = rutina.musicUrl;
|
||||||
|
playBtn.textContent = t("sim.play");
|
||||||
playBtn.onclick = () => {
|
playBtn.onclick = () => {
|
||||||
if (audioPlayer.paused) {
|
if (audioPlayer.paused) {
|
||||||
audioPlayer.play();
|
audioPlayer.play();
|
||||||
playBtn.textContent = "⏸ Pausar";
|
playBtn.textContent = t("sim.pause");
|
||||||
} else {
|
} else {
|
||||||
audioPlayer.pause();
|
audioPlayer.pause();
|
||||||
playBtn.textContent = "▶ Reproducir";
|
playBtn.textContent = t("sim.play");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
@ -58,7 +144,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||||
const divPiscina = document.getElementById("piscina");
|
const divPiscina = document.getElementById("piscina");
|
||||||
divPiscina.style.width = `${piscinaWidth}px`;
|
divPiscina.style.width = `${piscinaWidth}px`;
|
||||||
divPiscina.style.height = `${piscinaHeight}px`;
|
divPiscina.style.height = `${piscinaHeight}px`;
|
||||||
divPiscina.style.background = "#d4f0ff"; // Azul claro
|
divPiscina.style.background = "#d4f0ff";
|
||||||
document.getElementById("piscinaContainer").style.width = `${piscinaWidth + 20}px`;
|
document.getElementById("piscinaContainer").style.width = `${piscinaWidth + 20}px`;
|
||||||
|
|
||||||
function dibujarCuadricula(layer, ancho, alto, tamano = 45) {
|
function dibujarCuadricula(layer, ancho, alto, tamano = 45) {
|
||||||
|
@ -126,9 +212,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||||
points: [atleta.direccion.x1, atleta.direccion.y1, atleta.direccion.x2, atleta.direccion.y2],
|
points: [atleta.direccion.x1, atleta.direccion.y1, atleta.direccion.x2, atleta.direccion.y2],
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
dash: [4, 4],
|
dash: [4, 4]
|
||||||
pointerLength: 10,
|
|
||||||
pointerWidth: 10
|
|
||||||
});
|
});
|
||||||
layer.add(dir);
|
layer.add(dir);
|
||||||
}
|
}
|
||||||
|
@ -144,10 +228,8 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pintar solo esta formación
|
|
||||||
formacion.atletas.forEach(dibujarAtleta);
|
formacion.atletas.forEach(dibujarAtleta);
|
||||||
|
|
||||||
// Mostrar título visual
|
|
||||||
const block = document.createElement("button");
|
const block = document.createElement("button");
|
||||||
block.className = "btn btn-outline-primary btn-sm me-2 step";
|
block.className = "btn btn-outline-primary btn-sm me-2 step";
|
||||||
block.textContent = `${formacion.nombreColoquial || `Formación ${formationIndex + 1}`} (${formacion.duracion || '?'}s)`;
|
block.textContent = `${formacion.nombreColoquial || `Formación ${formationIndex + 1}`} (${formacion.duracion || '?'}s)`;
|
||||||
|
|
|
@ -5,35 +5,50 @@
|
||||||
<title>Simulador de Rutina</title>
|
<title>Simulador de Rutina</title>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet"/>
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet"/>
|
||||||
<link href="css/estiloAtletaSimulador.css" rel="stylesheet" />
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
|
||||||
|
|
||||||
|
<link href="css/estiloAtletaSimulador.css" rel="stylesheet" />
|
||||||
|
<link rel="stylesheet" href="css/navbar.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-light">
|
<body class="bg-light">
|
||||||
|
<!-- NAV -->
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary sticky-top shadow-sm px-4 py-3">
|
<nav class="navbar navbar-expand-lg navbar-dark bg-primary sticky-top shadow-sm px-4 py-3">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand fw-bold text-white">SwimmingArt</a>
|
<a class="navbar-brand fw-bold text-white">SwimmingArt</a>
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
<div class="ms-auto d-flex gap-4 align-items-center">
|
<div class="ms-auto d-flex gap-4 align-items-center">
|
||||||
<a href="atleta.html" class="nav-link text-white">Volver al Panel</a>
|
<a href="atleta.html" class="nav-link text-white" data-i18n="nav.init">Panel Atleta</a>
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button class="btn btn-outline-light dropdown-toggle d-flex align-items-center gap-2 px-3 py-1" type="button" id="userDropdown" data-bs-toggle="dropdown">
|
<button class="btn btn-outline-light dropdown-toggle d-flex align-items-center gap-2 px-3 py-1" type="button" id="userDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
<svg width="20" height="20" fill="currentColor" class="bi bi-person-circle" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-person-circle" viewBox="0 0 16 16">
|
||||||
<path d="M11 10a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
|
<path d="M11 10a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
|
||||||
<path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-4.546 12.174c.03-.256.071-.512.124-.767C4.28 10.798 5.94 10 8 10s3.72.798 4.422 2.407c.053.255.094.511.124.767A7 7 0 0 0 8 1z"/>
|
<path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-4.546 12.174c.03-.256.071-.512.124-.767C4.28 10.798 5.94 10 8 10s3.72.798 4.422 2.407c.053.255.094.511.124.767A7 7 0 0 0 8 1z"/>
|
||||||
</svg>
|
</svg>
|
||||||
<span id="nombreUsuarioHeader" class="fw-semibold">Usuario</span>
|
<span id="nombreUsuarioHeader" class="fw-semibold">Usuario</span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu dropdown-menu-end text-center p-3" style="background-color: #0d6efd; color: white; border-radius: 0 0 8px 8px;">
|
<ul class="dropdown-menu dropdown-menu-end text-center p-3"
|
||||||
<li>
|
aria-labelledby="userDropdown"
|
||||||
<select id="langSelector" class="form-select form-select-sm mb-3 bg-white text-dark border-0 rounded">
|
style="background-color: #0d6efd; color: white; border-radius: 0 0 8px 8px; min-width: 100%; max-width: 250px;">
|
||||||
|
<!-- Mostrar rol -->
|
||||||
|
<li class="mb-2">
|
||||||
|
<span id="nombreUsuarioDropdown" class="fw-semibold text-white d-block" data-i18n="role">Atleta</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Selector de idioma -->
|
||||||
|
<li class="mb-1">
|
||||||
|
<div class="d-flex align-items-center justify-content-center gap-2 w-100">
|
||||||
|
<i class="bi bi-globe" style="color: white; font-size: 1rem;"></i>
|
||||||
|
<select id="langSelector" class="form-select form-select-sm" style="border: none; border-radius: 6px; max-width: 140px;">
|
||||||
<option value="es">Español</option>
|
<option value="es">Español</option>
|
||||||
<option value="en">English</option>
|
<option value="en">English</option>
|
||||||
<option value="fr">Français</option>
|
<option value="fr">Français</option>
|
||||||
</select>
|
</select>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Botón salir -->
|
||||||
|
<li>
|
||||||
|
<button class="btn btn-danger btn-sm w-100" onclick="logout()" data-i18n="logout">Salir</button>
|
||||||
</li>
|
</li>
|
||||||
<li><button class="btn btn-danger btn-sm w-100" onclick="logout()">Salir</button></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,7 +56,7 @@
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="container py-5">
|
<div class="container py-5">
|
||||||
<h2 id="tituloRutina" class="text-center fw-bold text-primary mb-2">Cargando rutina...</h2>
|
<h2 id="tituloRutina" class="text-center fw-bold text-primary mb-2" data-i18n="sim.title">Cargando rutina...</h2>
|
||||||
<p class="text-center fs-6">
|
<p class="text-center fs-6">
|
||||||
<span id="tipoRutina" class="badge bg-info"></span>
|
<span id="tipoRutina" class="badge bg-info"></span>
|
||||||
<span id="modalidadRutina" class="badge bg-secondary ms-2"></span>
|
<span id="modalidadRutina" class="badge bg-secondary ms-2"></span>
|
||||||
|
@ -49,7 +64,7 @@
|
||||||
|
|
||||||
<div class="text-center my-4">
|
<div class="text-center my-4">
|
||||||
<audio id="audioPlayer" controls class="mb-2 w-100" style="max-width: 500px;"></audio>
|
<audio id="audioPlayer" controls class="mb-2 w-100" style="max-width: 500px;"></audio>
|
||||||
<button id="playPauseBtn" class="btn btn-outline-primary btn-sm">▶ Reproducir</button>
|
<button id="playPauseBtn" class="btn btn-outline-primary btn-sm" data-i18n="sim.play">▶ Reproducir</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="piscinaContainer" class="border rounded p-2 shadow-sm mx-auto mb-4 bg-white" style="max-width: fit-content;">
|
<div id="piscinaContainer" class="border rounded p-2 shadow-sm mx-auto mb-4 bg-white" style="max-width: fit-content;">
|
||||||
|
@ -57,11 +72,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-start mt-4">
|
<div class="text-start mt-4">
|
||||||
<h5 class="fw-semibold">Línea de Tiempo</h5>
|
<h5 class="fw-semibold" data-i18n="sim.timeline">Línea de Tiempo</h5>
|
||||||
<div id="lineaTiempo" class="d-flex flex-wrap gap-2"></div>
|
<div id="lineaTiempo" class="d-flex flex-wrap gap-2"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Scripts -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/konva@8.3.12/konva.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/konva@8.3.12/konva.min.js"></script>
|
||||||
<script src="js/simulador.js"></script>
|
<script src="js/simulador.js"></script>
|
||||||
|
|
Loading…
Reference in New Issue