import { useMutation } from "@tanstack/react-query"; import { useEffect, useState } from "react"; import { toast } from "sonner"; import { authClient } from "@/lib/auth-client"; import { inputCls, validateBirthdate, validateEmail, validatePhone, validatePostcode, validateTextField, } from "@/lib/registration"; import { orpc } from "@/utils/orpc"; import { GiftSelector } from "./GiftSelector"; interface PerformerErrors { firstName?: string; lastName?: string; email?: string; phone?: string; birthdate?: string; postcode?: string; artForm?: string; isOver16?: string; } interface Props { onBack: () => void; onSuccess: (token: string, email: string, name: string) => void; } export function PerformerForm({ onBack, onSuccess }: Props) { const { data: session } = authClient.useSession(); const sessionEmail = session?.user?.email ?? ""; const [data, setData] = useState({ firstName: "", lastName: "", email: "", phone: "", birthdateDay: "", birthdateMonth: "", birthdateYear: "", postcode: "", artForm: "", experience: "", isOver16: false, extraQuestions: "", }); const [giftAmount, setGiftAmount] = useState(0); const [errors, setErrors] = useState({}); const [touched, setTouched] = useState>({}); useEffect(() => { if (sessionEmail) { setData((prev) => ({ ...prev, email: sessionEmail })); } }, [sessionEmail]); const submitMutation = useMutation({ ...orpc.submitRegistration.mutationOptions(), onSuccess: (result) => { if (result.managementToken) onSuccess( result.managementToken, data.email.trim(), `${data.firstName.trim()} ${data.lastName.trim()}`.trim(), ); }, onError: (error) => { toast.error(`Er is iets misgegaan: ${error.message}`); }, }); function getBirthdate(): string { const { birthdateYear, birthdateMonth, birthdateDay } = data; if (!birthdateYear || !birthdateMonth || !birthdateDay) return ""; return `${birthdateYear}-${birthdateMonth.padStart(2, "0")}-${birthdateDay.padStart(2, "0")}`; } function validate(): boolean { const birthdate = getBirthdate(); const errs: PerformerErrors = { firstName: validateTextField(data.firstName, true, "Voornaam"), lastName: validateTextField(data.lastName, true, "Achternaam"), email: validateEmail(data.email), phone: validatePhone(data.phone), birthdate: validateBirthdate(birthdate), postcode: validatePostcode(data.postcode), artForm: !data.artForm.trim() ? "Kunstvorm is verplicht" : undefined, isOver16: !data.isOver16 ? "Je moet 16 jaar of ouder zijn om op te treden" : undefined, }; setErrors(errs); setTouched({ firstName: true, lastName: true, email: true, phone: true, birthdate: true, postcode: true, artForm: true, isOver16: true, }); return !Object.values(errs).some(Boolean); } function handleChange( e: React.ChangeEvent, ) { const { name, value, type } = e.target; const newValue = type === "checkbox" ? (e.target as HTMLInputElement).checked : value; setData((prev) => ({ ...prev, [name]: newValue })); if (type !== "checkbox" && touched[name]) { const fieldError: Record = { firstName: validateTextField( name === "firstName" ? value : data.firstName, true, "Voornaam", ), lastName: validateTextField( name === "lastName" ? value : data.lastName, true, "Achternaam", ), email: validateEmail(name === "email" ? value : data.email), phone: validatePhone(name === "phone" ? value : data.phone), artForm: name === "artForm" && !value.trim() ? "Kunstvorm is verplicht" : undefined, }; setErrors((prev) => ({ ...prev, [name]: fieldError[name] })); } } function handleBlur( e: React.FocusEvent, ) { const { name, value } = e.target; setTouched((prev) => ({ ...prev, [name]: true })); const errMap: Record = { firstName: validateTextField(value, true, "Voornaam"), lastName: validateTextField(value, true, "Achternaam"), email: validateEmail(value), phone: validatePhone(value), artForm: !value.trim() ? "Kunstvorm is verplicht" : undefined, }; setErrors((prev) => ({ ...prev, [name]: errMap[name] })); } function handleSubmit(e: React.FormEvent) { e.preventDefault(); if (!validate()) { toast.error("Controleer je invoer"); return; } submitMutation.mutate({ firstName: data.firstName.trim(), lastName: data.lastName.trim(), email: data.email.trim(), phone: data.phone.trim() || undefined, birthdate: getBirthdate(), postcode: data.postcode.trim(), registrationType: "performer", artForm: data.artForm.trim() || undefined, experience: data.experience.trim() || undefined, isOver16: data.isOver16, extraQuestions: data.extraQuestions.trim() || undefined, giftAmount, }); } return (
{/* Back + type header */}
Ik wil optreden
{/* Name row */}
{touched.firstName && errors.firstName && ( {errors.firstName} )}
{touched.lastName && errors.lastName && ( {errors.lastName} )}
{/* Contact row */}
{touched.email && errors.email && ( {errors.email} )}
{touched.phone && errors.phone && ( {errors.phone} )}
{/* Birthdate + Postcode row */}

Geboortedatum *

Geboortedatum
{touched.birthdate && errors.birthdate && ( {errors.birthdate} )}
{touched.postcode && errors.postcode && ( {errors.postcode} )}
{/* Performer-specific fields */}

Optreden details

{touched.artForm && errors.artForm && ( {errors.artForm} )}
{/* Age confirmation */}
{/* Extra questions */}