<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Confirmación Cumpleaños Vickol</title>
<!-- Incluimos Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Incluimos
la fuente Inter -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap"
rel="stylesheet">
<!-- Firebase SDKs -->
<script type="module">
import { initializeApp } from
"https://www.gstatic.com/firebasejs/11.6.1/firebase-app.js";
import { getAuth, signInAnonymously, signInWithCustomToken,
onAuthStateChanged } from
"https://www.gstatic.com/firebasejs/11.6.1/firebase-auth.js";
import { getFirestore, collection, addDoc, setDoc, doc, getDoc,
onSnapshot, setLogLevel } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-firestore.js";
// ---
Configuración de Firebase ---
let db, auth;
let appId, userId;
const firebaseConfig = JSON.parse(typeof __firebase_config !== 'undefined' ?
__firebase_config : '{}');
appId = typeof __app_id !== 'undefined' ? __app_id : 'default-app-id';
try {
const app = initializeApp(firebaseConfig);
db = getFirestore(app);
auth = getAuth(app);
setLogLevel('Debug'); //
Habilitar logs para depuración
//
Autenticar al usuario (invitado) de forma anónima
onAuthStateChanged(auth, async (user) => {
if (user) {
console.log("Usuario autenticado anónimamente:", user.uid);
userId = user.uid;
} else {
try {
const token = typeof
__initial_auth_token !== 'undefined'
? __initial_auth_token : null;
if (token) {
await signInWithCustomToken(auth, token);
console.log("Autenticado con token custom.");
} else {
await signInAnonymously(auth);
console.log("Autenticado anónimamente.");
}
}
catch (error) {
console.error("Error en la autenticación
anónima:", error);
}
}
});
} catch (e) {
console.error("Error inicializando Firebase:",
e);
}
// --- Lógica
de la App ---
document.addEventListener('DOMContentLoaded',
() => {
const rsvpFormPage = document.getElementById('rsvp-form-page');
const thankYouPage = document.getElementById('thank-you-page');
const rsvpForm = document.getElementById('rsvp-form');
const submitButton = document.getElementById('submit-button');
const submitButtonText = document.getElementById('submit-button-text');
const submitButtonLoading = document.getElementById('submit-button-loading');
const partnerQuestion = document.getElementById('partner-question');
const attendanceRadios = document.querySelectorAll('input[name="asistencia"]');
const calendarButton = document.getElementById('calendar-button');
const errorMessage = document.getElementById('error-message');
// ---
Generar Link de Google Calendar ---
const generateCalendarLink = ()
=> {
const title = "Cumpleaños de
Vickol!";
//
Fecha/Hora en UTC (Argentina es UTC-3)
//
Inicio: 2025-11-23 20:00:00 -> 20251123T230000Z
//
Fin: 2025-11-24 01:00:00 -> 20251124T040000Z
const startTime =
"20251123T230000Z";
const endTime =
"20251124T040000Z";
const details = "Vamos a
festejar mis 39 con un asadito! La morfi la pongo yo,
el lugar lava los platos. Como cada lugar contratado, me piden que confirme la
cantidad de gente.\nMe encantaría que compartas
conmigo el festejo de mis ultimos treintis!";
const location = "BierhofBA - Nicaragua 4427 (Palermo)";
const params = new URLSearchParams({
action: 'TEMPLATE',
text: title,
dates: `${startTime}/${endTime}`,
details: details,
location: location,
trp: 'false'
});
return
`https://www.google.com/calendar/render?${params.toString()}`;
};
calendarButton.href = generateCalendarLink();
// ---
Lógica del Formulario ---
//
Mostrar/ocultar la pregunta de la pareja
attendanceRadios.forEach(radio => {
radio.addEventListener('change',
() => {
if (radio.value === 'si') {
partnerQuestion.classList.remove('hidden');
} else {
partnerQuestion.classList.add('hidden');
// Si dice que no, reseteamos la opción de pareja
document.querySelector('input[name="pareja"][value="no"]').checked
= true;
}
});
});
// Enviar
el formulario
rsvpForm.addEventListener('submit',
async (e) => {
e.preventDefault();
if (!db || !auth.currentUser)
{
errorMessage.textContent = "Error: No se pudo conectar
a la base de datos. Intenta de nuevo.";
errorMessage.classList.remove('hidden');
return;
}
//
Mostrar estado de carga
submitButton.disabled = true;
submitButtonText.classList.add('hidden');
submitButtonLoading.classList.remove('hidden');
errorMessage.classList.add('hidden');
try {
const formData = new FormData(rsvpForm);
const nombre = formData.get('nombre').trim();
const asiste = formData.get('asistencia');
//
Solo obtenemos el valor de 'pareja' si la pregunta estaba visible
let traePareja = 'no';
if (asiste === 'si') {
traePareja = formData.get('pareja');
}
if (!nombre || !asiste) {
throw new Error("Por favor completa todos
los campos requeridos.");
}
//
Preparamos los datos para Firestore
const rsvpData = {
nombre: nombre,
asiste: asiste,
traePareja: traePareja,
timestamp: new Date()
};
//
Guardamos en la colección pública de la app
const rsvpCollectionPath = `artifacts/${appId}/public/data/rsvps`;
const rsvpCollection = collection(db, rsvpCollectionPath);
await addDoc(rsvpCollection,
rsvpData);
console.log("Respuesta guardada en:", rsvpCollectionPath,
rsvpData);
//
Redireccionar a la página de agradecimiento
rsvpFormPage.classList.add('hidden');
thankYouPage.classList.remove('hidden');
}
catch (error) {
console.error("Error al guardar la respuesta:",
error);
errorMessage.textContent = `Error: ${error.message
|| "No se pudo enviar la respuesta."}`;
errorMessage.classList.remove('hidden');
} finally {
//
Restaurar botón
submitButton.disabled
= false;
submitButtonText.classList.remove('hidden');
submitButtonLoading.classList.add('hidden');
}
});
});
</script>
<style>
body {
font-family: 'Inter', sans-serif;
}
/* Estilos
para los radio buttons personalizados */
.custom-radio:checked + .radio-dot
{
transform: scale(1);
}
.custom-radio:checked + .radio-dot
+ .radio-label {
font-weight: 500;
}
</style>
</head>
<body class="bg-amber-50
text-gray-800 min-h-screen flex
items-center justify-center
p-4">
<div class="w-full max-w-lg">
<!-- Página
del Formulario de RSVP (Inicial) -->
<div id="rsvp-form-page" class="bg-white shadow-xl rounded-lg overflow-hidden">
<!--
Imagen de cabecera -->
<img
src="https://placehold.co/800x300/fde68a/a16207?text=Vickol's+39th!"
alt="Banner de fiesta de cumpleaños"
class="w-full h-48 object-cover">
<div class="p-6
md:p-8">
<!-- Detalles del Evento -->
<section class="mb-6">
<h1 class="text-3xl
font-bold text-amber-700 mb-3">¡Cumpleaños de
Vickol!</h1>
<p class="text-gray-600 mb-4">
Vamos a festejar mis 39 con un asadito! La morfi
la pongo yo, el lugar lava los platos. Como cada lugar contratado, me piden que
confirme la cantidad de gente.
</p>
<p class="text-lg
font-medium text-gray-700 mb-6">
¡Me encantaría que compartas conmigo el festejo de mis últimos treintis!
</p>
<div class="space-y-4
text-gray-700">
<div class="flex items-center">
<svg class="w-5
h-5 mr-3 text-amber-600 flex-shrink-0" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor">
<path stroke-linecap="round"
stroke-linejoin="round" d="M6.75
3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 0 1 2.25-2.25h13.5A2.25 2.25 0 0 1
21 7.5v11.25m-18 0A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75m-18
0v-7.5A2.25 2.25 0 0 1 5.25 9h13.5A2.25 2.25 0 0 1 21 11.25v7.5" />
</svg>
<span class="font-medium">Domingo 23 de Noviembre, 2025 (Preferiado)</span>
</div>
<div class="flex items-center">
<svg class="w-5
h-5 mr-3 text-amber-600 flex-shrink-0" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor">
<path stroke-linecap="round"
stroke-linejoin="round" d="M12 6v6h4.5m4.5
0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
<span class="font-medium">20:00 hs -
01:00 hs</span>
</div>
<div class="flex items-center">
<svg
class="w-5 h-5 mr-3 text-amber-600
flex-shrink-0" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor">
<path stroke-linecap="round"
stroke-linejoin="round" d="M15 10.5a3
3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
<path stroke-linecap="round"
stroke-linejoin="round" d="M19.5
10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1 1 15 0Z"
/>
</svg>
<span class="font-medium">BierhofBA -
Nicaragua 4427 (Palermo)</span>
</div>
</div>
</section>
<!-- Botón de Google Calendar -->
<a id="calendar-button"
href="#"
target="_blank"
rel="noopener noreferrer"
class="w-full flex items-center justify-center px-4
py-3 bg-white border
border-gray-300 rounded-lg shadow-sm
text-gray-700 font-medium hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2
focus:ring-amber-500 transition-colors duration-150
mb-6">
<img
src="https://upload.wikimedia.org/wikipedia/commons/a/a5/Google_Calendar_icon_%282020%29.svg"
alt="Google Calendar" class="w-5
h-5 mr-2.5">
Agendar en Google Calendar
</a>
<!-- Formulario de RSVP -->
<section>
<h2 class="text-2xl font-bold text-amber-700 mb-5">Confirmar
Asistencia</h2>
<form id="rsvp-form"
class="space-y-5">
<!-- Nombre -->
<div>
<label for="nombre"
class="block text-sm font-medium text-gray-700 mb-1">Nombre y
Apellido</label>
<input type="text"
name="nombre" id="nombre" required
class="w-full px-3 py-2 border
border-gray-300 rounded-lg shadow-sm
focus:outline-none focus:ring-2 focus:ring-amber-500
focus:border-amber-500">
</div>
<!-- Confirmación de Asistencia -->
<div>
<span class="block
text-sm font-medium
text-gray-700 mb-2">¿Vas a venir?</span>
<div class="flex space-x-6">
<label class="flex items-center
cursor-pointer">
<input type="radio" name="asistencia"
value="si" required
class="custom-radio hidden">
<span class="w-5 h-5 border-2
border-gray-300 rounded-full flex
items-center justify-center
transition-all">
<span class="radio-dot w-3 h-3 bg-amber-600 rounded-full
transform scale-0 transition-transform"></span>
</span>
<span
class="radio-label
ml-2 text-gray-700">¡Sí, obvio!</span>
</label>
<label class="flex items-center
cursor-pointer">
<input type="radio" name="asistencia"
value="no" class="custom-radio hidden">
<span class="w-5 h-5 border-2
border-gray-300 rounded-full flex
items-center justify-center
transition-all">
<span class="radio-dot w-3 h-3 bg-amber-600 rounded-full
transform scale-0 transition-transform"></span>
</span>
<span class="radio-label ml-2 text-gray-700">No puedo :(</span>
</label>
</div>
</div>
<!-- Confirmación de Pareja (oculto por defecto) -->
<div id="partner-question"
class="hidden transition-all duration-300">
<span class="block
text-sm font-medium
text-gray-700 mb-2">¿Venís con pareja?</span>
<div class="flex space-x-6">
<label
class="flex items-center cursor-pointer">
<input type="radio" name="pareja"
value="si" class="custom-radio hidden">
<span class="w-5 h-5 border-2
border-gray-300 rounded-full flex
items-center justify-center
transition-all">
<span class="radio-dot w-3 h-3 bg-amber-600 rounded-full
transform scale-0 transition-transform"></span>
</span>
<span
class="radio-label
ml-2 text-gray-700">Sí, somos dos</span>
</label>
<label class="flex items-center
cursor-pointer">
<input type="radio" name="pareja"
value="no" checked
class="custom-radio hidden">
<span class="w-5 h-5 border-2
border-gray-300 rounded-full flex
items-center justify-center
transition-all">
<span class="radio-dot w-3 h-3 bg-amber-600 rounded-full
transform scale-0 transition-transform"></span>
</span>
<span class="radio-label ml-2 text-gray-700">No, voy solo/a</span>
</label>
</div>
</div>
<!-- Mensaje de Error -->
<div id="error-message"
class="hidden
text-red-600 text-sm font-medium"></div>
<!-- Botón de Enviar -->
<div>
<button type="submit" id="submit-button"
class="w-full flex justify-center py-3 px-4 bg-amber-600 text-white
font-medium rounded-lg shadow-md hover:bg-amber-700 focus:outline-none
focus:ring-2 focus:ring-offset-2 focus:ring-amber-500 transition-colors
duration-150 disabled:opacity-50 disabled:cursor-not-allowed">
<span id="submit-button-text">Enviar
Respuesta</span>
<span id="submit-button-loading"
class="hidden">
<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25"
cx="12" cy="12"
r="10" stroke="currentColor"
stroke-width="4"></circle>
<path class="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014
12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</span>
</button>
</div>
</form>
</section>
</div>
</div>
<!-- Página
de Agradecimiento (Oculta) -->
<div id="thank-you-page" class="hidden bg-white shadow-xl rounded-lg overflow-hidden text-center p-8 md:p-12">
<svg class="w-16 h-16
text-green-500 mx-auto mb-5" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor">
<path stroke-linecap="round"
stroke-linejoin="round" d="M9 12.75
11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
<h1 class="text-3xl font-bold
text-gray-800 mb-3">¡Gracias por responder!</h1>
<p class="text-gray-600 text-lg
mb-6">Tu respuesta fue enviada correctamente.</p>
<p class="text-gray-600 text-lg">¡Espero
verte ahí!</p>
</div>
</div>
</body>
</html>