// ================================ // UTILIDADES DE AUTENTICACIÓN // ================================ /** Devuelve el token JWT o null si no hay sesión. */ function getToken() { return localStorage.getItem("token"); } /** Devuelve el objeto usuario guardado en sesión, o null. */ function getUsuario() { const u = localStorage.getItem("usuario"); return u ? JSON.parse(u) : null; } /** * Verifica que el usuario esté autenticado. * Si no lo está, redirige a login.html y devuelve null. */ function verificarAuth() { if (!getToken()) { window.location.href = "login.html"; return null; } return getUsuario(); } /** Cierra la sesión y recarga la página actual (o va a index si es protegida). */ function cerrarSesion() { localStorage.removeItem("token"); localStorage.removeItem("usuario"); const paginasProtegidas = ["intenciones.html", "diario-oracion.html"]; const actual = location.pathname.split("/").pop(); if (paginasProtegidas.includes(actual)) { window.location.href = "index.html"; } else { location.reload(); } } /** * Muestra el nombre del usuario y el botón de cerrar sesión en el header. * Sin sesión: muestra botones que abren el modal de auth. */ function mostrarSesionEnHeader() { const usuario = getUsuario(); const contenedor = document.getElementById("header-sesion"); if (!contenedor) return; if (usuario) { contenedor.innerHTML = ` 👤 ${usuario.nombre} `; } else { contenedor.innerHTML = ` `; } } // ================================ // MODAL DE AUTENTICACIÓN // ================================ /** Resuelve la base de la API aunque api-config.js no esté cargado en la página. */ function _apiBase() { if (typeof API_BASE !== "undefined") return API_BASE; return (location.hostname === "localhost" || location.hostname === "127.0.0.1" || location.hostname === "") ? "http://localhost:8080" : "https://recursos-catolicos.es:8080"; } /** Crea e inserta el modal en el DOM la primera vez que se abre. */ function _inyectarModalAuth() { if (document.getElementById("modal-auth")) return; const el = document.createElement("div"); el.id = "modal-auth"; el.className = "modal-auth-overlay"; el.setAttribute("role", "dialog"); el.setAttribute("aria-modal", "true"); el.setAttribute("aria-label", "Iniciar sesión o registrarse"); el.innerHTML = ` `; document.body.appendChild(el); // — Cerrar — document.getElementById("modal-auth-cerrar").addEventListener("click", cerrarModalAuth); el.addEventListener("click", e => { if (e.target === el) cerrarModalAuth(); }); document.addEventListener("keydown", _modalKeyHandler); // — Pestañas — el.querySelectorAll(".modal-auth-tab").forEach(tab => { tab.addEventListener("click", () => { el.querySelectorAll(".modal-auth-tab").forEach(t => t.classList.remove("activa")); tab.classList.add("activa"); document.getElementById("modal-panel-login").style.display = tab.dataset.tab === "login" ? "block" : "none"; document.getElementById("modal-panel-registro").style.display = tab.dataset.tab === "registro" ? "block" : "none"; _focoModal(tab.dataset.tab); }); }); // — Enter para enviar — ["modal-email", "modal-password"].forEach(id => document.getElementById(id).addEventListener("keydown", e => { if (e.key === "Enter") _loginModal(); }) ); ["modal-nombre", "modal-email-reg", "modal-password-reg"].forEach(id => document.getElementById(id).addEventListener("keydown", e => { if (e.key === "Enter") _registroModal(); }) ); document.getElementById("modal-btn-login").addEventListener("click", _loginModal); document.getElementById("modal-btn-registro").addEventListener("click", _registroModal); } function _modalKeyHandler(e) { if (e.key === "Escape") cerrarModalAuth(); } function _focoModal(tab) { setTimeout(() => { const id = tab === "login" ? "modal-email" : "modal-nombre"; document.getElementById(id)?.focus(); }, 80); } /** Abre el modal en la pestaña indicada ('login' | 'registro'). */ function abrirModalAuth(tab = "login") { _inyectarModalAuth(); const modal = document.getElementById("modal-auth"); // Limpiar mensajes y campos al abrir ["modal-login-msg", "modal-registro-msg"].forEach(id => { const el = document.getElementById(id); if (el) { el.textContent = ""; el.className = "modal-auth-msg"; } }); modal.querySelectorAll(".modal-auth-tab").forEach(t => t.classList.remove("activa")); modal.querySelector(`[data-tab="${tab}"]`).classList.add("activa"); document.getElementById("modal-panel-login").style.display = tab === "login" ? "block" : "none"; document.getElementById("modal-panel-registro").style.display = tab === "registro" ? "block" : "none"; modal.classList.add("activo"); document.body.classList.add("modal-abierto"); _focoModal(tab); } /** Cierra el modal. */ function cerrarModalAuth() { const modal = document.getElementById("modal-auth"); if (!modal) return; modal.classList.remove("activo"); document.body.classList.remove("modal-abierto"); } /** Lógica de inicio de sesión desde el modal. */ async function _loginModal() { const email = document.getElementById("modal-email").value.trim(); const password = document.getElementById("modal-password").value.trim(); const msg = document.getElementById("modal-login-msg"); const btn = document.getElementById("modal-btn-login"); msg.textContent = ""; msg.className = "modal-auth-msg"; if (!email || !password) { msg.textContent = "Completa todos los campos."; msg.classList.add("error"); return; } btn.disabled = true; btn.textContent = "Entrando…"; try { const res = await fetch(`${_apiBase()}/auth/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }) }); if (res.ok) { const data = await res.json(); localStorage.setItem("token", data.token); localStorage.setItem("usuario", JSON.stringify(data.usuario)); msg.textContent = `¡Bienvenido, ${data.usuario.nombre}! ✝`; msg.classList.add("success"); setTimeout(() => location.reload(), 900); } else { msg.textContent = "Email o contraseña incorrectos."; msg.classList.add("error"); btn.disabled = false; btn.textContent = "Entrar"; } } catch (e) { msg.textContent = "No se pudo conectar con el servidor."; msg.classList.add("error"); btn.disabled = false; btn.textContent = "Entrar"; } } /** Lógica de registro desde el modal (individual; registro completo en register.html). */ async function _registroModal() { const nombre = document.getElementById("modal-nombre").value.trim(); const email = document.getElementById("modal-email-reg").value.trim(); const password = document.getElementById("modal-password-reg").value.trim(); const msg = document.getElementById("modal-registro-msg"); const btn = document.getElementById("modal-btn-registro"); msg.textContent = ""; msg.className = "modal-auth-msg"; if (!nombre || !email || !password) { msg.textContent = "Completa todos los campos."; msg.classList.add("error"); return; } if (password.length < 8) { msg.textContent = "La contraseña debe tener al menos 8 caracteres."; msg.classList.add("error"); return; } btn.disabled = true; btn.textContent = "Registrando…"; try { const res = await fetch(`${_apiBase()}/auth/register`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ nombre, email, password, tipoUsuario: "individual" }) }); if (res.ok) { msg.textContent = "¡Cuenta creada! Iniciando sesión…"; msg.classList.add("success"); // Auto-login tras el registro const loginRes = await fetch(`${_apiBase()}/auth/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }) }); if (loginRes.ok) { const data = await loginRes.json(); localStorage.setItem("token", data.token); localStorage.setItem("usuario", JSON.stringify(data.usuario)); } setTimeout(() => location.reload(), 900); } else { const error = await res.text(); msg.textContent = error || "No se pudo crear la cuenta."; msg.classList.add("error"); btn.disabled = false; btn.textContent = "Registrarme"; } } catch (e) { msg.textContent = "No se pudo conectar con el servidor."; msg.classList.add("error"); btn.disabled = false; btn.textContent = "Registrarme"; } }