/* Página de entrada (27-oct-2026).
- Si ya hay sesión, salta directo a donde ibas (nginx manda aquí con #/ruta/original).
- Entrar: POST /api/entrar → el servidor pone la cookie de sesión; el mensaje dice qué pasó.
- Avisos públicos del sitio (incidencias marcadas «publica») y reporte sin sesión (POST /api/incidencias/publica). */
(function () {
var $ = function (id) { return document.getElementById(id); };
function destino() {
// Solo rutas de ESTE sitio: se arma la URL completa y se exige el mismo origen (un «/\t/otro.com» o «/\\otro.com»
// se vuelve «//otro.com» en el navegador: comparar el origen lo cierra). Nunca regresa a la entrada.
var h = '';
try { h = decodeURIComponent((location.hash || '').slice(1)); } catch (e) { h = ''; }
if (!h || h.charAt(0) !== '/') return '/';
try {
var u = new URL(h, location.origin);
if (u.origin !== location.origin || /^\/entrar\.html/.test(u.pathname)) return '/';
return u.href; // absoluta y del mismo origen (un «/.//otro.com» relativo sería otro sitio)
} catch (e) { return '/'; }
}
function ir() { location.replace(destino()); }
function mensaje(el, html, bien) { el.className = 'en-msg ' + (bien ? 'ok' : 'err'); el.innerHTML = html; }
function esc(s) { var d = document.createElement('div'); d.textContent = s == null ? '' : String(s); return d.innerHTML; }
// ¿ya hay sesión?
fetch('/api/sesion', { cache: 'no-store', credentials: 'same-origin' })
.then(function (r) { return r.ok ? r.json() : null; })
.then(function (j) { if (j && j.sesion) ir(); })
.catch(function () {});
// usuario recordado (solo el nombre, nunca la contraseña)
try { var u0 = localStorage.getItem('hbox.usuario'); if (u0) { $('usuario').value = u0; } } catch (e) {}
($('usuario').value ? $('password') : $('usuario')).focus();
$('ver').addEventListener('click', function () {
var p = $('password'), mostrar = p.type === 'password';
p.type = mostrar ? 'text' : 'password';
this.textContent = mostrar ? 'Ocultar' : 'Ver';
this.setAttribute('aria-pressed', mostrar ? 'true' : 'false');
this.setAttribute('aria-label', mostrar ? 'Ocultar la contraseña' : 'Mostrar la contraseña');
});
function revisarMayus(ev) {
if (ev.getModifierState) $('mayus').hidden = !ev.getModifierState('CapsLock');
}
$('password').addEventListener('keydown', revisarMayus);
$('password').addEventListener('keyup', revisarMayus);
$('fEntrar').addEventListener('submit', function (ev) {
ev.preventDefault();
var b = $('bEntrar'), msg = $('msg');
var usuario = $('usuario').value.trim(), password = $('password').value;
if (!usuario || !password) { mensaje(msg, 'Escribe tu usuario y tu contraseña.', false); return; }
b.disabled = true; b.textContent = 'Entrando…';
fetch('/api/entrar', {
method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ usuario: usuario, password: password, recordar: $('recordar').checked })
}).then(function (r) {
return r.json().catch(function () { return { ok: false, error: 'El servidor no respondió bien (HTTP ' + r.status + ').' }; });
}).then(function (j) {
if (j && j.ok) {
try { localStorage.setItem('hbox.usuario', usuario); } catch (e) {}
mensaje(msg, 'Listo, ' + esc(j.user) + '. Abriendo el sitio…', true);
ir();
return;
}
var t = esc((j && j.error) || 'No se pudo entrar.');
if (j && j.codigo === 'contrasena') {
$('password').value = ''; $('password').focus();
} else if (j && j.codigo === 'usuario') {
$('usuario').focus();
}
if (j && (j.codigo === 'bloqueado' || j.codigo === 'contrasena')) {
t += ' Reportar el problema.';
}
mensaje(msg, t, false);
var a = $('abrirAyuda');
if (a) a.addEventListener('click', function (e) { e.preventDefault(); abrirAyuda(); });
}).catch(function () {
mensaje(msg, 'No pude contactar al servidor. Revisa tu conexión e intenta otra vez; si sigue, repórtalo abajo.', false);
}).then(function () { b.disabled = false; b.textContent = 'Entrar'; });
});
function abrirAyuda() {
var d = $('ayuda'); d.open = true;
if (!$('rNombre').value) $('rNombre').value = $('usuario').value.trim();
d.scrollIntoView({ behavior: 'smooth', block: 'start' });
setTimeout(function () { $('rDesc').focus(); }, 300);
}
$('ayuda').addEventListener('toggle', function () {
if (this.open && !$('rNombre').value) $('rNombre').value = $('usuario').value.trim();
});
$('fReporte').addEventListener('submit', function (ev) {
ev.preventDefault();
var b = $('bReporte'), msg = $('msgR');
var tipo = (document.querySelector('input[name="rTipo"]:checked') || {}).value || 'acceso';
var cuerpo = { nombre: $('rNombre').value.trim(), contacto: $('rContacto').value.trim(), descripcion: $('rDesc').value.trim(),
tipo: tipo, sitio_web: $('rTrampa').value, pantalla: screen.width + '×' + screen.height };
if (cuerpo.descripcion.length < 5) { mensaje(msg, 'Cuéntanos qué pasa (aunque sea una línea).', false); return; }
if (!cuerpo.nombre && !cuerpo.contacto) { mensaje(msg, 'Dinos quién eres o cómo contactarte.', false); return; }
b.disabled = true; b.textContent = 'Enviando…';
fetch('/api/incidencias/publica', {
method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(cuerpo)
}).then(function (r) { return r.json().catch(function () { return { ok: false, error: 'HTTP ' + r.status }; }); })
.then(function (j) {
if (j && j.ok) {
mensaje(msg, 'Recibido: ' + esc(j.id) + '. Se revisa todos los días; si dejaste cómo contactarte, te buscamos. '
+ 'Guarda el folio por si preguntas.', true);
$('rDesc').value = '';
} else {
mensaje(msg, esc((j && j.error) || 'No se pudo enviar.'), false);
}
})
.catch(function () { mensaje(msg, 'No pude contactar al servidor. Avísale a Leo o a Gibran por mensaje.', false); })
.then(function () { b.disabled = false; b.textContent = 'Enviar reporte'; });
});
// avisos públicos
fetch('/api/incidencias/publicas', { cache: 'no-store', credentials: 'same-origin' })
.then(function (r) { return r.ok ? r.json() : null; })
.then(function (j) {
if (!j || !j.ok || !j.avisos || !j.avisos.length) return;
var ul = $('avisosLista');
j.avisos.forEach(function (a) {
var li = document.createElement('li');
li.innerHTML = '' + (a.resuelta ? 'Resuelto' : 'En atención') + ''
+ '' + esc(a.titulo) + ' ' + esc(a.actualizado) + '';
ul.appendChild(li);
});
$('avisos').hidden = false;
})
.catch(function () {});
})();