feat(portal): dynamic volunteer registration fields and conditional steps

Render registration_fields from the API grouped by section, submit
field_values and festival_section_id-based section_preferences.
Respect event toggles for section preferences and availability; polish
layout (header, welcome v-html, section cards, navigation).

Made-with: Cursor
This commit is contained in:
2026-04-12 23:59:16 +02:00
parent 73c8e6c466
commit e986e4c7eb
4 changed files with 880 additions and 462 deletions

View File

@@ -1,6 +1,7 @@
import { z } from 'zod'
export const step1Schema = z.object({
/** Fixed fields for step "Over jou" (portal volunteer registration). */
export const personalStepSchema = z.object({
first_name: z.string().min(1, 'Voornaam is verplicht').max(255),
last_name: z.string().min(1, 'Achternaam is verplicht').max(255),
email: z.string().min(1, 'E-mailadres is verplicht').email('Ongeldig e-mailadres').max(255),
@@ -8,18 +9,4 @@ export const step1Schema = z.object({
phone: z.string().max(50).optional().or(z.literal('')),
})
export const step2Schema = z.object({
tshirt_size: z.enum(['XS', 'S', 'M', 'L', 'XL', 'XXL', 'XXXL']).optional().or(z.literal('')),
first_aid: z.boolean().default(false),
allergies: z.string().max(500).optional().or(z.literal('')),
driving_licence: z.boolean().default(false),
})
export const step3Schema = z.object({
motivation: z.string().max(1000).optional().or(z.literal('')),
motivation_other: z.string().max(500).optional().or(z.literal('')),
})
export const fullRegistrationSchema = step1Schema
.merge(step2Schema)
.merge(step3Schema)
export const fullRegistrationSchema = personalStepSchema