feat(registration): add birthdate & postcode
This commit is contained in:
@@ -4,8 +4,10 @@ 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";
|
||||
@@ -16,6 +18,8 @@ interface PerformerErrors {
|
||||
lastName?: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
birthdate?: string;
|
||||
postcode?: string;
|
||||
artForm?: string;
|
||||
isOver16?: string;
|
||||
}
|
||||
@@ -34,6 +38,10 @@ export function PerformerForm({ onBack, onSuccess }: Props) {
|
||||
lastName: "",
|
||||
email: "",
|
||||
phone: "",
|
||||
birthdateDay: "",
|
||||
birthdateMonth: "",
|
||||
birthdateYear: "",
|
||||
postcode: "",
|
||||
artForm: "",
|
||||
experience: "",
|
||||
isOver16: false,
|
||||
@@ -64,12 +72,21 @@ export function PerformerForm({ onBack, onSuccess }: Props) {
|
||||
},
|
||||
});
|
||||
|
||||
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"
|
||||
@@ -81,6 +98,8 @@ export function PerformerForm({ onBack, onSuccess }: Props) {
|
||||
lastName: true,
|
||||
email: true,
|
||||
phone: true,
|
||||
birthdate: true,
|
||||
postcode: true,
|
||||
artForm: true,
|
||||
isOver16: true,
|
||||
});
|
||||
@@ -144,6 +163,8 @@ export function PerformerForm({ onBack, onSuccess }: Props) {
|
||||
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,
|
||||
@@ -305,6 +326,149 @@ export function PerformerForm({ onBack, onSuccess }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Birthdate + Postcode row */}
|
||||
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||
<div className="flex flex-col gap-2">
|
||||
<p className="text-white text-xl">
|
||||
Geboortedatum <span className="text-red-300">*</span>
|
||||
</p>
|
||||
<fieldset className="m-0 flex gap-2 border-0 p-0">
|
||||
<legend className="sr-only">Geboortedatum</legend>
|
||||
<div className="flex flex-1 flex-col gap-1">
|
||||
<label htmlFor="p-birthdateDay" className="sr-only">
|
||||
Dag
|
||||
</label>
|
||||
<select
|
||||
id="p-birthdateDay"
|
||||
name="birthdateDay"
|
||||
value={data.birthdateDay}
|
||||
onChange={(e) =>
|
||||
setData((prev) => ({
|
||||
...prev,
|
||||
birthdateDay: e.target.value,
|
||||
}))
|
||||
}
|
||||
aria-label="Dag"
|
||||
className={`border-b bg-transparent pb-2 text-lg text-white transition-colors focus:outline-none ${touched.birthdate && errors.birthdate ? "border-red-400" : "border-white/30 focus:border-white"}`}
|
||||
>
|
||||
<option value="" className="bg-[#214e51]">
|
||||
DD
|
||||
</option>
|
||||
{Array.from({ length: 31 }, (_, i) => i + 1).map((d) => (
|
||||
<option key={d} value={String(d)} className="bg-[#214e51]">
|
||||
{String(d).padStart(2, "0")}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="flex flex-1 flex-col gap-1">
|
||||
<label htmlFor="p-birthdateMonth" className="sr-only">
|
||||
Maand
|
||||
</label>
|
||||
<select
|
||||
id="p-birthdateMonth"
|
||||
name="birthdateMonth"
|
||||
value={data.birthdateMonth}
|
||||
onChange={(e) =>
|
||||
setData((prev) => ({
|
||||
...prev,
|
||||
birthdateMonth: e.target.value,
|
||||
}))
|
||||
}
|
||||
aria-label="Maand"
|
||||
className={`border-b bg-transparent pb-2 text-lg text-white transition-colors focus:outline-none ${touched.birthdate && errors.birthdate ? "border-red-400" : "border-white/30 focus:border-white"}`}
|
||||
>
|
||||
<option value="" className="bg-[#214e51]">
|
||||
MM
|
||||
</option>
|
||||
{[
|
||||
"Jan",
|
||||
"Feb",
|
||||
"Mrt",
|
||||
"Apr",
|
||||
"Mei",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Okt",
|
||||
"Nov",
|
||||
"Dec",
|
||||
].map((m, i) => (
|
||||
<option
|
||||
key={m}
|
||||
value={String(i + 1)}
|
||||
className="bg-[#214e51]"
|
||||
>
|
||||
{m}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="flex flex-1 flex-col gap-1">
|
||||
<label htmlFor="p-birthdateYear" className="sr-only">
|
||||
Jaar
|
||||
</label>
|
||||
<select
|
||||
id="p-birthdateYear"
|
||||
name="birthdateYear"
|
||||
value={data.birthdateYear}
|
||||
onChange={(e) =>
|
||||
setData((prev) => ({
|
||||
...prev,
|
||||
birthdateYear: e.target.value,
|
||||
}))
|
||||
}
|
||||
aria-label="Jaar"
|
||||
className={`border-b bg-transparent pb-2 text-lg text-white transition-colors focus:outline-none ${touched.birthdate && errors.birthdate ? "border-red-400" : "border-white/30 focus:border-white"}`}
|
||||
>
|
||||
<option value="" className="bg-[#214e51]">
|
||||
JJJJ
|
||||
</option>
|
||||
{Array.from(
|
||||
{ length: 100 },
|
||||
(_, i) => new Date().getFullYear() - i,
|
||||
).map((y) => (
|
||||
<option key={y} value={String(y)} className="bg-[#214e51]">
|
||||
{y}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</fieldset>
|
||||
{touched.birthdate && errors.birthdate && (
|
||||
<span className="text-red-300 text-sm" role="alert">
|
||||
{errors.birthdate}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<label htmlFor="p-postcode" className="text-white text-xl">
|
||||
Postcode <span className="text-red-300">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="p-postcode"
|
||||
name="postcode"
|
||||
value={data.postcode}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
placeholder="bv. 9000"
|
||||
autoComplete="postal-code"
|
||||
inputMode="numeric"
|
||||
aria-required="true"
|
||||
aria-invalid={touched.postcode && !!errors.postcode}
|
||||
className={inputCls(!!touched.postcode && !!errors.postcode)}
|
||||
/>
|
||||
{touched.postcode && errors.postcode && (
|
||||
<span className="text-red-300 text-sm" role="alert">
|
||||
{errors.postcode}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Performer-specific fields */}
|
||||
<div className="border border-amber-400/20 bg-amber-400/5 p-6">
|
||||
<p className="mb-5 text-amber-300/80 text-sm uppercase tracking-wider">
|
||||
|
||||
Reference in New Issue
Block a user