import { useState } from 'react'; import { useQuery, useMutation } from '@tanstack/react-query'; import { useParams, Link } from '@tanstack/react-router'; import { CalendarClock, CheckCircle2, Clock, GraduationCap, Loader2, Moon, Sun, Users, } from 'lucide-react'; import { Badge, Button, Input, Label } from '../components/ui'; import { Logo } from '../components/brand'; import { useTheme } from '../context/ThemeProvider'; import { getInviteInfo, joinViaInvite, ApiError } from '../lib/api'; import { BILLING_LABELS, formatPrice, formatSchedule } from '../lib/format'; export function JoinGroupView() { const { token } = useParams({ strict: false }) as { token: string }; const { theme, setTheme, isDark } = useTheme(); const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); const [phone, setPhone] = useState(''); const [email, setEmail] = useState(''); const [errorMessage, setErrorMessage] = useState(null); // Success state const [registeredAttendee, setRegisteredAttendee] = useState<{ fullName: string; phone: string | null; } | null>(null); // Waitlist state (group is full) const [waitlistInfo, setWaitlistInfo] = useState<{ message: string } | null>(null); const inviteQuery = useQuery({ queryKey: ['public-invite', token], queryFn: () => getInviteInfo(token), enabled: Boolean(token), retry: 1, }); const joinMutation = useMutation({ mutationFn: () => joinViaInvite(token, { firstName: firstName.trim(), lastName: lastName.trim(), phone: phone.trim(), email: email.trim() || undefined, }), onSuccess: (data) => { setErrorMessage(null); if (data.status === 'waitlisted') { setRegisteredAttendee(null); setWaitlistInfo({ message: data.message }); return; } setWaitlistInfo(null); setRegisteredAttendee({ fullName: data.attendee!.fullName, phone: data.attendee!.phone, }); }, onError: (error: unknown) => { if (error instanceof ApiError) { if (error.problem?.code === 'attendee_already_registered') { setErrorMessage( 'Ya te encuentras registrado en este grupo con ese número de teléfono. El profesor ya tiene tus datos.', ); return; } setErrorMessage(error.message || 'Error al procesar la inscripción.'); } else if (error instanceof Error) { setErrorMessage(error.message); } else { setErrorMessage('Ocurrió un error inesperado. Por favor, intenta de nuevo.'); } }, }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); setErrorMessage(null); if (!firstName.trim() || !lastName.trim() || !phone.trim()) { setErrorMessage('Por favor completa los campos requeridos (Nombre, Apellido y Teléfono).'); return; } joinMutation.mutate(); }; const group = inviteQuery.data; return (
{/* Public Header */}
{/* Main Content */}
{inviteQuery.isPending ? (

Cargando información del grupo...

) : null} {inviteQuery.isError || !group ? (

Enlace no válido o expirado

No pudimos encontrar este grupo. Por favor consulta con tu profesor para solicitar un nuevo enlace de invitación.

) : null} {/* Registration Success Confirmation */} {registeredAttendee && group ? (
Registro Confirmado

¡Inscripción Exitosa!

Tus datos han sido registrados con éxito en el grupo{' '} {group.name}.

Profesor: {group.teacherName}
Alumno: {registeredAttendee.fullName}
{registeredAttendee.phone ? (
Teléfono registrado: {registeredAttendee.phone}
) : null}

El profesor se pondrá en contacto contigo a la brevedad por WhatsApp para darte la bienvenida y coordinar los detalles de la clase.

) : null} {/* Waitlist Confirmation (group full) */} {waitlistInfo && group ? (
Lista de Espera

Cupo completo

{waitlistInfo.message}

El profesor se pondrá en contacto contigo cuando haya un lugar disponible en{' '} {group.name}.

) : null} {/* Inscription Form */} {!registeredAttendee && !waitlistInfo && group ? (
{/* Group Info Header */}
Invitación Oficial

{group.name}

Profesor: {group.teacherName}

{group.description ? (

{group.description}

) : null} {/* Schedule & Price Details */}
{(group.days?.length ?? 0) > 0 ? (
{formatSchedule(group.days ?? [], group.time)}
) : null} {group.price != null ? (
{formatPrice(group.price)} {group.billingType ? · {BILLING_LABELS[group.billingType]} : ''}
) : null} {group.capacity ? (
Cupo {group.capacity}
) : null}
{/* Form Header */}

Completa tus datos

Ingresa tus datos para registrarte en la lista de alumnos de este grupo.

{/* Error banner */} {errorMessage ? (
{errorMessage}
) : null} {/* Form */}
setFirstName(e.target.value)} required />
setLastName(e.target.value)} required />
setPhone(e.target.value)} required />

El profesor se comunicará contigo por WhatsApp a este número.

setEmail(e.target.value)} />
) : null}
{/* Footer */}
); }