Files
andaquenosabesna/public/nuevo-invitado.html
T

211 lines
8.9 KiB
HTML

<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow, noarchive">
<title>Nuevo enlace de invitado · AQNSN</title>
<meta name="theme-color" content="#06080d">
<link rel="icon" href="img/avatar.jpg">
<link rel="stylesheet" href="styles.css">
<style>
.gen-form { display: grid; gap: 20px; max-width: 560px; }
.gen-form label { display: grid; gap: 6px; font-weight: 600; font-size: .95rem; }
.gen-form input[type=text], .gen-form input[type=password], .gen-form input[type=datetime-local] {
width: 100%; padding: 13px 15px; border-radius: 12px; border: 1px solid var(--line);
background: var(--card); color: var(--ink); font: inherit; font-weight: 400; transition: .2s;
}
.gen-form input:focus { outline: none; border-color: var(--neon); box-shadow: 0 0 0 3px rgba(46,230,255,.18); }
.dias-list { display: grid; gap: 10px; }
.dia-row { display: flex; gap: 10px; align-items: center; }
.dia-row input { flex: 1; }
.dia-row .del-dia { background: transparent; border: 1px solid var(--line); color: var(--muted);
padding: 8px 13px; border-radius: 8px; font: inherit; cursor: pointer; transition: .2s; flex: none; }
.dia-row .del-dia:hover { border-color: #ff8a8a; color: #ff8a8a; }
.add-dia { background: transparent; border: 1px dashed var(--line); color: var(--muted);
padding: 11px 18px; border-radius: 12px; font: inherit; cursor: pointer; width: 100%; transition: .2s; }
.add-dia:hover { border-color: var(--neon); color: var(--neon); }
.result-box { display: none; margin-top: 8px; padding: 16px 18px; border: 1px solid var(--line);
border-left: 3px solid var(--neon); border-radius: 12px; background: var(--card); }
.result-box .url { word-break: break-all; font-size: .92rem; color: var(--neon); margin: 0 0 12px; }
.copy-btn { padding: 9px 20px; border-radius: 999px; border: 1px solid var(--neon);
background: transparent; color: var(--neon); font: inherit; font-weight: 700; cursor: pointer; transition: .2s; }
.copy-btn:hover { background: var(--neon); color: #001a20; }
.lock { max-width: 340px; }
small { color: var(--muted); font-weight: 400; font-size: .88rem; }
#login-err { color: #ff8a8a; font-size: .92rem; min-height: 1.4em; }
</style>
</head>
<body>
<header class="top">
<a class="brand" href="/" aria-label="Anda Que No Sabes Ná, inicio"><img src="img/avatar.jpg" alt="" width="40" height="40"><span>Anda que no sabes ná</span></a>
</header>
<main class="legal contact">
<h1>Nuevo <em>enlace</em> de invitado</h1>
<div id="login-panel">
<p class="lead-c">Solo para el equipo del programa.</p>
<form id="login-form" class="gen-form lock" novalidate>
<label>Contraseña
<input id="pwd" type="password" autocomplete="current-password" required>
</label>
<p id="login-err"></p>
<button class="btn primary" type="submit">Entrar</button>
</form>
</div>
<div id="gen-panel" hidden>
<p class="lead-c">Rellena el nombre del invitado y los días propuestos. Se generará un enlace que podrás enviarle.</p>
<form id="gen-form" class="gen-form" novalidate autocomplete="off">
<label>Nombre del invitado <span class="req">*</span>
<input id="nombre" type="text" maxlength="60" placeholder="Ej: Ana García" required>
<small>Tal como quieres presentarle en el programa.</small>
</label>
<div>
<div style="font-weight:600;font-size:.95rem;margin-bottom:8px">Días propuestos <span class="req">*</span></div>
<small style="display:block;margin-bottom:12px">Añade entre 1 y 5 opciones. La invitada elegirá la que mejor le venga.</small>
<div id="dias-list" class="dias-list"></div>
<button type="button" id="add-dia" class="add-dia">+ Añadir otro día</button>
</div>
<div>
<div style="font-weight:600;font-size:.95rem;margin-bottom:8px">Modo de enlace</div>
<label class="check" style="margin-bottom:8px">
<input type="radio" name="modo" value="propuestos" checked>
<span>Días propuestos — la invitada elige</span>
</label>
<label class="check">
<input type="radio" name="modo" value="fijo">
<span>Fecha fija — ya está confirmada</span>
</label>
</div>
<p id="gen-err" class="status err" hidden></p>
<button class="btn primary" type="submit">Generar enlace</button>
</form>
<div id="result" class="result-box">
<p class="url" id="result-url"></p>
<button class="copy-btn" id="copy-btn">Copiar enlace</button>
</div>
</div>
</main>
<script>
(function () {
var HASH = '%%PASS_HASH%%';
async function sha256hex(str) {
var buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(str));
return Array.from(new Uint8Array(buf)).map(function (b) { return b.toString(16).padStart(2, '0'); }).join('');
}
var loginPanel = document.getElementById('login-panel');
var genPanel = document.getElementById('gen-panel');
var loginForm = document.getElementById('login-form');
var loginErr = document.getElementById('login-err');
var pwd = document.getElementById('pwd');
var SESSION_KEY = 'aqnsn-gen-auth';
try { if (sessionStorage.getItem(SESSION_KEY) === HASH) { loginPanel.hidden = true; genPanel.hidden = false; } } catch (e) {}
loginForm.addEventListener('submit', function (e) {
e.preventDefault();
sha256hex(pwd.value).then(function (h) {
if (h === HASH) {
try { sessionStorage.setItem(SESSION_KEY, h); } catch (e) {}
loginPanel.hidden = true; genPanel.hidden = false; loginErr.textContent = '';
} else {
loginErr.textContent = 'Contraseña incorrecta.';
pwd.value = ''; pwd.focus();
}
});
});
// --- Generador ---
var diasList = document.getElementById('dias-list');
var addDiaBtn = document.getElementById('add-dia');
var genForm = document.getElementById('gen-form');
var genErr = document.getElementById('gen-err');
var result = document.getElementById('result');
var resultUrl = document.getElementById('result-url');
var copyBtn = document.getElementById('copy-btn');
function addDia(value) {
var row = document.createElement('div');
row.className = 'dia-row';
var inp = document.createElement('input');
inp.type = 'datetime-local'; inp.className = 'dia-inp';
if (value) inp.value = value;
var del = document.createElement('button');
del.type = 'button'; del.className = 'del-dia'; del.textContent = '✕';
del.addEventListener('click', function () {
row.remove();
actualizarAddBtn();
});
row.appendChild(inp); row.appendChild(del);
diasList.appendChild(row);
actualizarAddBtn();
}
function actualizarAddBtn() {
addDiaBtn.style.display = diasList.children.length >= 5 ? 'none' : '';
}
addDia(); // una fila por defecto
addDiaBtn.addEventListener('click', function () { addDia(); });
genForm.addEventListener('submit', function (e) {
e.preventDefault();
genErr.hidden = true;
var nombre = document.getElementById('nombre').value.trim();
if (!nombre) { genErr.textContent = 'Escribe el nombre del invitado.'; genErr.hidden = false; return; }
var modo = genForm.querySelector('input[name="modo"]:checked').value;
var inps = Array.prototype.slice.call(diasList.querySelectorAll('input.dia-inp'));
var timestamps = [];
for (var i = 0; i < inps.length; i++) {
var v = inps[i].value;
if (!v) continue;
var ts = Math.round(new Date(v).getTime() / 1000);
if (isNaN(ts)) continue;
timestamps.push(ts);
}
if (timestamps.length === 0) { genErr.textContent = 'Añade al menos un día.'; genErr.hidden = false; return; }
var base = location.origin + '/invitados.html';
var url;
if (modo === 'fijo') {
if (timestamps.length > 1) { genErr.textContent = 'En modo fecha fija solo puedes indicar un día.'; genErr.hidden = false; return; }
url = base + '?n=' + encodeURIComponent(nombre) + '&f=' + timestamps[0];
} else {
url = base + '?n=' + encodeURIComponent(nombre) + '&d=' + timestamps.join(',');
}
resultUrl.textContent = url;
result.style.display = 'block';
result.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
});
copyBtn.addEventListener('click', function () {
var url = resultUrl.textContent;
if (navigator.clipboard) {
navigator.clipboard.writeText(url).then(function () {
copyBtn.textContent = '¡Copiado!';
setTimeout(function () { copyBtn.textContent = 'Copiar enlace'; }, 2000);
});
} else {
var ta = document.createElement('textarea');
ta.value = url; document.body.appendChild(ta); ta.select(); document.execCommand('copy');
document.body.removeChild(ta);
copyBtn.textContent = '¡Copiado!';
setTimeout(function () { copyBtn.textContent = 'Copiar enlace'; }, 2000);
}
});
})();
</script>
</body>
</html>