+
+
Powered by Crewli
@@ -1166,79 +1095,14 @@ async function onSubmit() {
.registration-container {
position: relative;
z-index: 1;
- max-inline-size: 1040px;
-}
-
-.registration-header-fallback {
- background: rgb(var(--v-theme-surface));
- border-color: rgba(var(--v-border-color), var(--v-border-opacity)) !important;
-}
-
-.registration-welcome-html :deep(p) {
- margin-block-end: 0.5rem;
-}
-
-.registration-welcome-html :deep(p:last-child) {
- margin-block-end: 0;
-}
-
-.step-indicator {
- inline-size: 48px;
- block-size: 48px;
- border-radius: 10px;
- font-size: 16px;
- font-weight: 700;
- transition: background-color 0.2s ease, color 0.2s ease;
-}
-
-.step-indicator--active {
- background-color: rgb(var(--v-theme-primary));
- color: rgb(var(--v-theme-on-primary));
-}
-
-.step-indicator--done {
- background-color: rgba(var(--v-theme-primary), 0.12);
- color: rgb(var(--v-theme-primary));
-}
-
-.step-indicator--todo {
- background-color: rgba(var(--v-theme-on-surface), 0.06);
- color: rgba(var(--v-theme-on-surface), 0.35);
-}
-
-.section-category-heading {
- padding-block-end: 8px;
- border-block-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
-}
-
-.registration-section-grid {
- align-items: stretch;
-}
-
-.section-pref-card {
- border-color: rgba(var(--v-border-color), var(--v-border-opacity)) !important;
- transition: border-color 0.15s ease, background-color 0.15s ease;
-}
-
-.section-pref-card--selected {
- border: 2px solid rgb(var(--v-theme-primary)) !important;
- background-color: rgba(var(--v-theme-primary), 0.06);
-}
-
-.priority-pill {
- position: absolute;
- inset-block-start: 10px;
- inset-inline-end: 10px;
- z-index: 1;
- font-size: 11px;
- font-weight: 600;
- padding-block: 4px;
- padding-inline: 10px;
- border-radius: 999px;
- background-color: rgba(var(--v-theme-on-surface), 0.75);
- color: rgb(var(--v-theme-surface));
+ max-inline-size: 1000px;
}
+/*
+ Native date inputs have a large intrinsic min-width; without min-width: 0 the
+ grid cell grows and the prepend-inner icon no longer sits inside the outline
+ next to the value (Vuetify v-field grid: prepend-inner | field).
+*/
.volunteer-reg-dob-field :deep(.v-field__field) {
min-inline-size: 0;
}
@@ -1249,6 +1113,10 @@ async function onSubmit() {
min-inline-size: 0;
}
+/*
+ Vuetify’s .v-list uses overflow: auto, which shows scrollbars on this step when
+ list rows are slightly wider than the card (e.g. checkbox + text + rating).
+*/
.registration-availability-list {
overflow: visible !important;
}
diff --git a/apps/portal/src/schemas/registrationSchema.ts b/apps/portal/src/schemas/registrationSchema.ts
index 3f228c49..34f30601 100644
--- a/apps/portal/src/schemas/registrationSchema.ts
+++ b/apps/portal/src/schemas/registrationSchema.ts
@@ -1,7 +1,6 @@
import { z } from 'zod'
-/** Fixed fields for step "Over jou" (portal volunteer registration). */
-export const personalStepSchema = z.object({
+export const step1Schema = 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),
@@ -9,4 +8,18 @@ export const personalStepSchema = z.object({
phone: z.string().max(50).optional().or(z.literal('')),
})
-export const fullRegistrationSchema = personalStepSchema
+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)
diff --git a/apps/portal/src/types/registration.ts b/apps/portal/src/types/registration.ts
index f4d52da9..9a7b1a14 100644
--- a/apps/portal/src/types/registration.ts
+++ b/apps/portal/src/types/registration.ts
@@ -1,33 +1,3 @@
-export type RegistrationFieldType =
- | 'text'
- | 'textarea'
- | 'select'
- | 'multiselect'
- | 'checkbox'
- | 'radio'
- | 'boolean'
- | 'number'
- | 'tag_picker'
-
-export interface RegistrationTagOption {
- id: string
- name: string
- category: string | null
-}
-
-export interface RegistrationField {
- id: string
- label: string
- slug: string
- field_type: RegistrationFieldType
- options: string[] | null
- tag_category: string | null
- is_required: boolean
- section: string | null
- help_text: string | null
- available_tags?: RegistrationTagOption[]
-}
-
export interface EventRegistrationData {
event: {
id: string
@@ -38,12 +8,9 @@ export interface EventRegistrationData {
registration_banner_url: string | null
registration_welcome_text: string | null
registration_logo_url: string | null
- registration_show_section_preferences: boolean
- registration_show_availability: boolean
}
sections: SectionOption[]
time_slots: TimeSlotOption[]
- registration_fields: RegistrationField[]
}
export interface SectionOption {
@@ -63,25 +30,33 @@ export interface TimeSlotOption {
duration_hours: number
}
-export interface SectionPreferencePayload {
- festival_section_id: string
+export interface SectionPreference {
+ section_name: string
priority: number
}
-export interface VolunteerAvailabilityPayload {
+export interface VolunteerAvailability {
time_slot_id: string
- preference_level?: number
+ preference_level: number
}
-export type FieldValuePayload = string | number | boolean | string[] | null
-
export interface VolunteerRegistrationForm {
+ // Step 1
first_name: string
last_name: string
- date_of_birth?: string
+ date_of_birth: string
email: string
- phone?: string
- field_values?: Record
- section_preferences?: SectionPreferencePayload[]
- availabilities?: VolunteerAvailabilityPayload[]
+ phone: string
+ // Step 2
+ tshirt_size: string
+ first_aid: boolean
+ allergies: string
+ driving_licence: boolean
+ // Step 3
+ motivation: string
+ motivation_other: string
+ // Step 4
+ section_preferences: SectionPreference[]
+ // Step 5
+ availabilities: VolunteerAvailability[]
}