document.addEventListener('DOMContentLoaded', async () => {
const userId = sessionStorage.getItem("userId");
if (!userId) {
alert("Sesión expirada, inicia sesión de nuevo.");
window.location.href = "index.html";
return;
}
try {
const res = await fetch(`/api/users/${userId}`);
const user = await res.json();
if (user?.name) {
document.getElementById("nombreUsuarioHeader").textContent = user.name;
}
let lang = 'es'; // valor por defecto
// 1. Determinar idioma
if (sessionStorage.getItem('langJustChanged') === 'true') {
lang = sessionStorage.getItem('lang') || user.language || 'es';
} else if (sessionStorage.getItem('lang')) {
lang = sessionStorage.getItem('lang');
} else if (user.language) {
lang = user.language;
sessionStorage.setItem('lang', lang);
}
window.tLang = lang;
localStorage.setItem('lang', lang); // opcional si usas localStorage
// 🌀 Recarga solo una vez con delay para evitar parpadeo inmediato
if (!sessionStorage.getItem('langLoadedOnce')) {
sessionStorage.setItem('langLoadedOnce', 'true');
setTimeout(() => location.reload(), 100); //
return;
}
// ✅ Aplicar traducciones después de confirmar idioma
const selector = document.getElementById("langSelector");
if (selector) selector.value = lang;
aplicarTraducciones();
actualizarTextosDinamicos();
} catch (err) {
console.error("❌ Error al obtener datos del usuario:", err);
}
const rutinaId = new URLSearchParams(window.location.search).get('routineId');
if (!rutinaId) return alert('No se proporcionó ID de rutina.');
const select = document.getElementById('selectAtleta');
const tituloRutina = document.getElementById('tituloRutina');
const tipoRutina = document.getElementById('tipoRutina');
const modalidadRutina = document.getElementById('modalidadRutina');
const inputFigura = document.getElementById('figura');
const btnEditarFormacion = document.getElementById('btnEditarFormacion');
const btnGuardarFormacion = document.getElementById('btnGuardarFormacion');
let editIndex = null;
let indexSeleccionado = null;
let modoDireccion = false;
let indexAtletaDireccion = null;
const rutina = await fetch(`/api/rutinas/${rutinaId}`).then(res => res.json());
const modalidad = rutina.modalidad;
const audioPlayer = document.getElementById('audioPlayer');
if (rutina.musicUrl) {
audioPlayer.src = rutina.musicUrl;
}
tituloRutina.textContent = rutina.title || rutina.nombreCompetencia;
tipoRutina.textContent = rutina.tipoCompetencia;
modalidadRutina.textContent = modalidad;
const atletas = await fetch('/api/users/athletes').then(res => res.json());
atletas.forEach(a => {
const opt = document.createElement('option');
opt.value = JSON.stringify({ id: a._id, nombre: a.name, idPers: a.idPersonalizado });
opt.textContent = `${a.name} (${a.idPersonalizado || 'sin ID'})`;
select.appendChild(opt);
});
let figuraActual = null; // 🔁 Guardar la figura seleccionada
select.addEventListener('change', () => {
const datos = JSON.parse(select.value || '{}');
select.dataset.id = datos.id;
const idInput = document.getElementById('idPersonalizado');
if (datos.idPers) {
idInput.value = datos.idPers;
idInput.disabled = true;
} else {
idInput.value = '';
idInput.disabled = false;
}
});
let figurasFINA = [];
try {
const res = await fetch('/catalog/figurasFINA.json');
figurasFINA = await res.json();
const sugerenciasBox = document.getElementById('sugerenciasFigura');
inputFigura.addEventListener('input', () => {
const val = inputFigura.value.trim().toLowerCase();
sugerenciasBox.innerHTML = '';
if (val.length < 1) return;
const matches = figurasFINA.filter(f => f.nombre.toLowerCase().includes(val));
matches.forEach(figura => {
const item = document.createElement('button');
item.type = 'button';
item.className = 'list-group-item list-group-item-action';
item.textContent = figura.nombre;
item.onclick = () => {
inputFigura.value = figura.nombre;
inputFigura.title = `${figura.descripcion} (${figura.categoria})`;
sugerenciasBox.innerHTML = '';
figuraActual = figura; // guardamos figura activa
mostrarPreview(figura);
const codigoInput = document.getElementById("codigoElemento");
if (codigoInput && figura.codigoElemento) {
codigoInput.value = figura.codigoElemento;
}
};
sugerenciasBox.appendChild(item);
});
});
inputFigura.addEventListener('blur', () => {
setTimeout(() => sugerenciasBox.innerHTML = '', 200);
});
function mostrarPreview(figura) {
const nombreTrad = window.figurasTraducidas?.[figura.nombre]?.[window.tLang] || figura.nombre;
const descripcionTrad = window.descripcionesTraducidas?.[figura.descripcion]?.[window.tLang] || figura.descripcion;
// Traducción visual adicional debajo del input
const nombreTraducidoVisual = document.getElementById("nombreFiguraTraducido");
if (nombreTraducidoVisual) {
nombreTraducidoVisual.textContent = nombreTrad;
}
document.getElementById('previewFigura').innerHTML = `
${nombreTrad}
${descripcionTrad} ${figura.categoria}
`;
const codigoInput = document.getElementById("codigoElemento");
if (codigoInput && figura.codigoElemento) {
codigoInput.value = figura.codigoElemento;
}
}
// Esto es clave: vuelve a mostrar la figura al cambiar idioma
document.getElementById('langSelector').addEventListener('change', () => {
window.tLang = sessionStorage.getItem('lang') || user.language || 'es';
if (figuraActual) {
mostrarPreview(figuraActual); // 🔁 refresca con idioma nuevo
}
});
} catch (err) {
console.warn('❌ No se pudo cargar el catálogo FINA:', err);
}
const tipoPiscinaSelect = document.getElementById('tipoPiscina');
const medidasPiscina = {
olimpica: { width: 1000, height: 500 },
semiolimpica: { width: 750, height: 375 },
fosa: { width: 600, height: 600 }
};
let tipoSeleccionado = rutina.tipoPiscina || 'olimpica';
tipoPiscinaSelect.value = tipoSeleccionado;
let piscinaWidth = medidasPiscina[tipoSeleccionado].width;
let piscinaHeight = medidasPiscina[tipoSeleccionado].height;
tipoPiscinaSelect.addEventListener('change', async () => {
tipoSeleccionado = tipoPiscinaSelect.value;
piscinaWidth = medidasPiscina[tipoSeleccionado].width;
piscinaHeight = medidasPiscina[tipoSeleccionado].height;
// Actualiza dimensiones visuales
stage.width(piscinaWidth);
stage.height(piscinaHeight);
document.getElementById('piscina').style.width = `${piscinaWidth}px`;
document.getElementById('piscina').style.height = `${piscinaHeight}px`;
document.getElementById('piscinaContainer').style.width = `${piscinaWidth + 20}px`;
// Redibujar cuadrícula
layer.destroyChildren();
dibujarCuadricula(layer, piscinaWidth, piscinaHeight);
formacionActual.forEach(a => dibujarAtleta(a));
// Guardar en BD
try {
await fetch(`/api/rutinas/${rutinaId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ tipoPiscina: tipoSeleccionado })
});
} catch (err) {
console.error('Error al actualizar tipoPiscina:', err);
}
});
// Escalas de conversión a metros
const escalaX = 25 / piscinaWidth;
const escalaY = 20 / piscinaHeight;
function convertirAMetros(pxX, pxY) {
return {
metrosX: (pxX * escalaX).toFixed(2),
metrosY: (pxY * escalaY).toFixed(2)
};
}
const stage = new Konva.Stage({
container: 'piscina',
width: piscinaWidth,
height: piscinaHeight
});
const layer = new Konva.Layer();
stage.add(layer);
const divPiscina = document.getElementById('piscina');
divPiscina.style.width = `${piscinaWidth}px`;
divPiscina.style.height = `${piscinaHeight}px`;
document.getElementById('piscinaContainer').style.width = `${piscinaWidth + 20}px`;
dibujarCuadricula(layer, piscinaWidth, piscinaHeight);
function dibujarCuadricula(layer, ancho, alto, tamano = 45) {
for (let x = 0; x <= ancho; x += tamano) {
layer.add(new Konva.Line({
points: [x, 0, x, alto],
stroke: '#cceeff',
strokeWidth: 1
}));
}
for (let y = 0; y <= alto; y += tamano) {
layer.add(new Konva.Line({
points: [0, y, ancho, y],
stroke: '#cceeff',
strokeWidth: 1
}));
}
}
let formacionActual = [];
let atletasKonva = {};
let currentAtleta = null;
const maxAtletas = modalidad === 'solo' ? 1 : modalidad === 'duo' ? 2 : 8;
document.getElementById('btnAgregarAtleta').addEventListener('click', () => {
if (formacionActual.length >= maxAtletas) {
alert(`Modalidad "${modalidad}" permite un máximo de ${maxAtletas} atletas.`);
return;
}
const idAtleta = select.dataset.id;
const idPersonalizado = document.getElementById('idPersonalizado').value.trim();
// 🚫 Validación para evitar duplicados
const yaExiste = formacionActual.some(a => a.atletaId === idAtleta || a.idPersonalizado === idPersonalizado);
if (yaExiste) {
Swal.fire({
icon: 'warning',
title: 'Atleta ya asignado',
text: 'Este atleta ya fue agregado a esta formación.',
confirmButtonText: 'Entendido'
});
return;
}
const rol = document.getElementById('rolAtleta').value.trim().toLowerCase();
const figura = inputFigura?.value.trim();
const tipoElemento = document.getElementById('tipoElemento').value;
const codigoElemento = document.getElementById('codigoElemento').value.trim();
if (!idAtleta || !rol || !idPersonalizado) {
alert('Faltan datos del atleta');
return;
}
currentAtleta = {
atletaId: idAtleta,
rol,
idPersonalizado,
figura,
tipoElemento,
codigoElemento
};
alert('Haz clic en la piscina para colocarlo');
});
stage.on('click', () => {
if (!currentAtleta || modoDireccion) return;
const pos = stage.getPointerPosition();
const metros = convertirAMetros(pos.x, pos.y);
console.log(`📏 Posición en metros: (${metros.metrosX}m, ${metros.metrosY}m)`);
const atletaObj = { ...currentAtleta, x: pos.x, y: pos.y, grupo: '', direccion: null };
formacionActual.push(atletaObj);
dibujarAtleta(atletaObj);
currentAtleta = null;
document.getElementById('rolAtleta').value = '';
document.getElementById('idPersonalizado').value = '';
inputFigura.value = '';
inputFigura.title = '';
document.getElementById('previewFigura').innerHTML = '';
});
function dibujarAtleta(atleta) {
const color = atleta.rol === 'volador' ? 'purple' : atleta.rol === 'pilar' ? 'blue' : 'red';
const metros = convertirAMetros(atleta.x, atleta.y);
const circle = new Konva.Circle({
x: atleta.x,
y: atleta.y,
radius: 15,
fill: color,
stroke: 'white',
strokeWidth: 2,
draggable: !modoDireccion
});
const text = new Konva.Text({
x: atleta.x,
y: atleta.y,
text: atleta.idPersonalizado,
fontSize: 12,
fill: 'white',
fontStyle: 'bold',
align: 'center'
});
text.offsetX(text.width() / 2);
text.offsetY(text.height() / 2);
const figuraText = new Konva.Text({
x: atleta.x - 25,
y: atleta.y + 18,
text: atleta.figura || '',
fontSize: 10,
fill: '#333',
fontStyle: 'italic'
});
figuraText.listening(false);
const coordText = new Konva.Text({
x: atleta.x - 35,
y: atleta.y + 30,
text: `${metros.metrosX}m, ${metros.metrosY}m`,
fontSize: 9,
fill: '#666'
});
coordText.listening(false);
let flecha = null;
if (atleta.direccion) {
flecha = new Konva.Arrow({
points: [atleta.direccion.x1, atleta.direccion.y1, atleta.direccion.x2, atleta.direccion.y2],
stroke: 'black',
fill: 'black',
strokeWidth: 2,
pointerLength: 10,
pointerWidth: 10,
dash: [4, 4]
});
layer.add(flecha);
}
circle.on('dblclick', () => {
const i = formacionActual.findIndex(a => a.idPersonalizado === atleta.idPersonalizado);
const html = `
${atleta.figura || 'Sin figura'}
`;
showPopover(circle.x(), circle.y(), html);
});
window.eliminarDireccion = function(index) {
const atleta = formacionActual[index];
if (!atleta) return;
atleta.direccion = null;
const visual = atletasKonva[atleta.idPersonalizado];
if (visual?.flecha) {
visual.flecha.destroy();
visual.flecha = null;
layer.draw();
}
document.getElementById('popoverAtleta')?.remove();
};
circle.on('dragend', () => {
const newX = circle.x();
const newY = circle.y();
const i = formacionActual.findIndex(a => a.idPersonalizado === atleta.idPersonalizado);
if (i !== -1) {
formacionActual[i].x = newX;
formacionActual[i].y = newY;
// Si hay dirección, recalcular puntos
if (formacionActual[i].direccion && atletasKonva[atleta.idPersonalizado].flecha) {
const dir = formacionActual[i].direccion;
const dx = dir.x2 - dir.x1;
const dy = dir.y2 - dir.y1;
// Actualizar punto de partida y final relativo a nueva posición
dir.x1 = newX;
dir.y1 = newY;
dir.x2 = newX + dx;
dir.y2 = newY + dy;
atletasKonva[atleta.idPersonalizado].flecha.points([
dir.x1, dir.y1, dir.x2, dir.y2
]);
}
}
// Actualiza visualmente los textos
const nuevosMetros = convertirAMetros(newX, newY);
coordText.text(`${nuevosMetros.metrosX}m, ${nuevosMetros.metrosY}m`);
coordText.x(newX - 35);
coordText.y(newY + 30);
text.x(newX - 10);
text.y(newY - 7);
figuraText.x(newX - 25);
figuraText.y(newY + 18);
layer.batchDraw();
});
layer.add(circle);
layer.add(text);
layer.add(figuraText);
layer.add(coordText);
atletasKonva[atleta.idPersonalizado] = {
circle,
text,
figuraText,
coordText,
flecha
};
layer.draw();
}
window.activarModoDireccion = function(index) {
modoDireccion = true;
indexAtletaDireccion = index;
document.getElementById('popoverAtleta')?.remove();
alert('Haz clic para trazar dirección.');
}
stage.on('mousedown', () => {
if (!modoDireccion || indexAtletaDireccion === null) return;
const start = stage.getPointerPosition();
const atleta = formacionActual[indexAtletaDireccion];
const linea = new Konva.Arrow({
points: [start.x, start.y, start.x, start.y],
stroke: 'black',
fill: 'black',
strokeWidth: 2,
pointerLength: 10,
pointerWidth: 10,
dash: [4, 4]
});
layer.add(linea);
stage.on('mousemove.direccion', () => {
const pos = stage.getPointerPosition();
linea.points([start.x, start.y, pos.x, pos.y]);
layer.batchDraw();
});
stage.on('mouseup.direccion', () => {
const end = stage.getPointerPosition();
atleta.direccion = {
x1: start.x,
y1: start.y,
x2: end.x,
y2: end.y
};
// Asignar la flecha al atleta visual
if (atletasKonva[atleta.idPersonalizado]) {
atletasKonva[atleta.idPersonalizado].flecha = linea;
}
modoDireccion = false;
indexAtletaDireccion = null;
stage.off('mousemove.direccion');
stage.off('mouseup.direccion');
});
});
function showPopover(x, y, contentHTML) {
document.getElementById('popoverAtleta')?.remove();
const popover = document.createElement('div');
popover.id = 'popoverAtleta';
popover.innerHTML = contentHTML;
popover.style.position = 'absolute';
popover.style.left = `${x + 50}px`;
popover.style.top = `${y + 100}px`;
popover.style.zIndex = '1000';
popover.style.background = '#fff';
popover.style.border = '1px solid #ccc';
popover.style.boxShadow = '0 2px 8px rgba(0,0,0,0.2)';
popover.style.padding = '10px';
popover.style.borderRadius = '6px';
document.body.appendChild(popover);
setTimeout(() => {
document.addEventListener('click', function handler(e) {
if (!popover.contains(e.target)) {
popover.remove();
document.removeEventListener('click', handler);
}
});
}, 100);
}
function animarTransicion(nuevaFormacion) {
// Limpiar capa y diccionario de atletas previos
layer.destroyChildren();
atletasKonva = {};
// Redibujar cuadrícula
dibujarCuadricula(layer, piscinaWidth, piscinaHeight);
// Dibujar cada atleta
nuevaFormacion.forEach(a => {
dibujarAtleta(a);
});
layer.draw();
}
btnGuardarFormacion.addEventListener('click', async () => {
const nombre = document.getElementById('nombreFormacion').value.trim();
const notas = document.getElementById('notasFormacion').value.trim();
const duracion = parseInt(document.getElementById('duracionFormacion').value);
if (!nombre || formacionActual.length === 0) {
alert('Agrega nombre de formación y al menos un atleta');
return;
}
formacionActual = formacionActual.map(a => {
const obj = atletasKonva[a.idPersonalizado];
if (!obj) return a;
const x = obj.circle.x();
const y = obj.circle.y();
// Actualizar posición
a.x = x;
a.y = y;
// Si hay flecha, actualiza dirección
if (a.direccion && obj.flecha) {
const points = obj.flecha.points();
a.direccion = {
x1: points[0],
y1: points[1],
x2: points[2],
y2: points[3]
};
}
return a;
});
const body = {
nombreColoquial: nombre,
notasTacticas: notas,
duracion: duracion || 0,
atletas: formacionActual.map(a => ({
atletaId: a.atletaId,
idPersonalizado: a.idPersonalizado,
x: a.x,
y: a.y,
rol: a.rol,
grupo: a.grupo,
direccion: a.direccion,
figura: a.figura,
tipoElemento: a.tipoElemento,
codigoElemento: a.codigoElemento,
tipoPiscina: tipoPiscinaSelect.value,
}))
};
// Validación extra: asegura que se esté usando bien el ID de rutina
if (!rutinaId) {
alert('No se puede guardar porque falta el ID de rutina.');
return;
}
const method = editIndex === null ? 'POST' : 'PUT';
const endpoint = editIndex === null
? `/api/rutinas/${rutinaId}/formations`
: `/api/rutinas/${rutinaId}/formations/${editIndex}`;
const res = await fetch(endpoint, {
method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
if (res.ok) {
alert(editIndex === null ? '✅ Formación guardada' : '✏️ Formación actualizada');
window.location.reload();
} else {
alert('❌ Error al guardar formación');
}
});
const timeline = document.getElementById('lineaTiempo');
new Sortable(timeline, {
animation: 150,
onEnd: async (evt) => {
const nuevaLista = [...timeline.children].map(btn => parseInt(btn.dataset.index));
const nuevasFormaciones = nuevaLista.map(i => formaciones[i]);
try {
const res = await fetch(`/api/rutinas/${rutinaId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ formaciones: nuevasFormaciones })
});
const json = await res.json();
if (res.ok) {
console.log('✅ Formaciones reordenadas');
} else {
console.warn('⚠️ Error al guardar nuevo orden:', json);
}
} catch (err) {
console.error('❌ Error de red al reordenar:', err);
}
}
});
const formaciones = await fetch(`/api/rutinas/${rutinaId}/formations`).then(res => res.json());
if (Array.isArray(formaciones)) {
formaciones.forEach((f, i) => {
const block = document.createElement('button');
block.className = 'btn btn-outline-secondary btn-sm me-2 step';
block.textContent = `${f.nombreColoquial || `Formación ${i + 1}`} (${f.duracion || '?'}s)`;
block.dataset.index = i;
block.title = f.notasTacticas || '';
timeline.appendChild(block);
});
}
timeline.addEventListener('click', (e) => {
if (!e.target.classList.contains('step')) return;
indexSeleccionado = parseInt(e.target.dataset.index);
const seleccionada = formaciones[indexSeleccionado];
if (!seleccionada) return;
document.getElementById('nombreFormacion').value = seleccionada.nombreColoquial || '';
document.getElementById('notasFormacion').value = seleccionada.notasTacticas || '';
formacionActual = seleccionada.atletas.map(a => ({ ...a }));
const nuevaFormacion = seleccionada.atletas.map(a => ({ ...a }));
animarTransicion(nuevaFormacion);
formacionActual = nuevaFormacion;
btnEditarFormacion.disabled = false;
btnEditarFormacion.className = 'btn btn-outline-secondary btn-sm';
btnEditarFormacion.innerHTML = '✏ Editar formación';
btnGuardarFormacion.textContent = '💾 Guardar Formación';
btnGuardarFormacion.classList.remove('btn-warning');
btnGuardarFormacion.classList.add('btn-primary');
editIndex = null;
});
const syncPuntos = [];
let tiempoAcumulado = 0;
formaciones.forEach((f, i) => {
syncPuntos.push({
index: i,
inicio: tiempoAcumulado,
fin: tiempoAcumulado + (f.duracion || 0)
});
tiempoAcumulado += (f.duracion || 0);
});
btnEditarFormacion.addEventListener('click', () => {
if (indexSeleccionado !== null) {
editIndex = indexSeleccionado;
const a = formacionActual[0] || {};
document.getElementById('rolAtleta').value = a.rol || '';
document.getElementById('idPersonalizado').value = a.idPersonalizado || '';
inputFigura.value = a.figura || '';
inputFigura.title = '';
btnEditarFormacion.className = 'btn btn-warning btn-sm d-inline-flex align-items-center gap-2';
btnEditarFormacion.innerHTML = t('editor.edicionActiva');
btnGuardarFormacion.textContent = t('editor.actualizar');
btnGuardarFormacion.classList.remove('btn-primary');
btnGuardarFormacion.classList.add('btn-warning');
} else {
alert('Selecciona una formación desde la línea de tiempo primero.');
}
});
const btnEliminarFormacion = document.getElementById('btnEliminarFormacion');
btnEliminarFormacion.addEventListener('click', async () => {
if (indexSeleccionado === null || !formaciones[indexSeleccionado]) {
return alert('Selecciona una formación primero');
}
const confirm = await Swal.fire({
title: '¿Eliminar formación?',
text: 'Esta acción no se puede deshacer',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Sí, eliminar',
cancelButtonText: 'Cancelar'
});
if (!confirm.isConfirmed) return;
try {
const res = await fetch(`/api/rutinas/${rutinaId}/formations/${indexSeleccionado}`, {
method: 'DELETE'
});
if (res.ok) {
Swal.fire('Eliminada', 'La formación ha sido eliminada.', 'success');
window.location.reload();
} else {
Swal.fire('Error', 'No se pudo eliminar la formación.', 'error');
}
} catch (err) {
console.error(err);
Swal.fire('Error', 'Ocurrió un error de red.', 'error');
}
});
// Observador de redimensionamiento para mantener la tarjeta ajustada
const piscinaCard = document.querySelector('#piscinaContainer').closest('.card');
const resizeObserver = new ResizeObserver(() => {
if (piscinaCard) {
piscinaCard.style.height = 'auto';
}
});
resizeObserver.observe(document.getElementById('piscina'));
// Crear WaveSurfer
const wave = WaveSurfer.create({
container: '#waveform',
waveColor: '#A8DBA8',
progressColor: '#3B8686',
height: 100,
responsive: true
});
if (rutina.musicUrl) {
wave.load(rutina.musicUrl);
}
const playPauseBtn = document.getElementById('playPauseBtn');
playPauseBtn.addEventListener('click', () => {
wave.playPause();
});
wave.on('play', () => {
playPauseBtn.textContent = '⏸︎ Pausar';
});
wave.on('pause', () => {
playPauseBtn.textContent = '▶ Reproducir';
});
wave.on('finish', () => {
playPauseBtn.textContent = '▶ Reproducir';
});
wave.on('audioprocess', (currentTime) => {
syncPuntos.forEach(punto => {
const btn = document.querySelector(`.step[data-index="${punto.index}"]`);
if (!btn) return;
if (currentTime >= punto.inicio && currentTime < punto.fin) {
btn.classList.add('active');
if (indexSeleccionado !== punto.index) {
indexSeleccionado = punto.index;
const seleccionada = formaciones[punto.index];
if (seleccionada) {
formacionActual = seleccionada.atletas.map(a => ({ ...a }));
const nuevaFormacion = seleccionada.atletas.map(a => ({ ...a }));
animarTransicion(nuevaFormacion);
formacionActual = nuevaFormacion;
}
}
} else {
btn.classList.remove('active');
}
});
});
});
document.getElementById('langSelector').addEventListener('change', async (e) => {
const selectedLang = e.target.value;
sessionStorage.setItem('lang', selectedLang);
window.tLang = selectedLang;
const userId = sessionStorage.getItem("userId");
if (userId) {
await fetch(`/api/users/${userId}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ language: selectedLang })
});
}
// 🟡 Recargar solo 1 vez
sessionStorage.setItem('langJustChanged', 'true');
window.location.reload();
});
function logout() {
sessionStorage.clear();
localStorage.removeItem('lang'); // ✅ Limpia persistencia de idioma
alert("Sesión cerrada");
window.location.href = "../index.html";
}
window.logout = logout;