diff --git a/api/app/Http/Requests/Api/V1/VolunteerRegistrationRequest.php b/api/app/Http/Requests/Api/V1/VolunteerRegistrationRequest.php index d31384d1..73c20d2f 100644 --- a/api/app/Http/Requests/Api/V1/VolunteerRegistrationRequest.php +++ b/api/app/Http/Requests/Api/V1/VolunteerRegistrationRequest.php @@ -40,7 +40,6 @@ final class VolunteerRegistrationRequest extends FormRequest 'tshirt_size' => ['nullable', 'string', 'in:XS,S,M,L,XL,XXL,XXXL'], 'first_aid' => ['nullable', 'boolean'], 'allergies' => ['nullable', 'string', 'max:500'], - 'access_requirements' => ['nullable', 'string', 'max:500'], 'driving_licence' => ['nullable', 'boolean'], 'motivation' => ['nullable', 'string', 'max:1000'], diff --git a/api/app/Services/VolunteerRegistrationService.php b/api/app/Services/VolunteerRegistrationService.php index 7f50a865..5262426d 100644 --- a/api/app/Services/VolunteerRegistrationService.php +++ b/api/app/Services/VolunteerRegistrationService.php @@ -59,7 +59,6 @@ final class VolunteerRegistrationService 'tshirt_size' => $validated['tshirt_size'] ?? null, 'first_aid' => $validated['first_aid'] ?? false, 'allergies' => $validated['allergies'] ?? null, - 'access_requirements' => $validated['access_requirements'] ?? null, 'driving_licence' => $validated['driving_licence'] ?? false, 'motivation' => $validated['motivation'] ?? null, 'motivation_other' => $validated['motivation_other'] ?? null, diff --git a/apps/portal/src/pages/register/[eventSlug].vue b/apps/portal/src/pages/register/[eventSlug].vue index 394492d4..2cfd463f 100644 --- a/apps/portal/src/pages/register/[eventSlug].vue +++ b/apps/portal/src/pages/register/[eventSlug].vue @@ -45,7 +45,6 @@ const { errors, defineField, validateField, setFieldValue } = useForm({ tshirt_size: '', first_aid: false, allergies: '', - access_requirements: '', driving_licence: false, motivation: '', motivation_other: '', @@ -60,7 +59,6 @@ const [phone] = defineField('phone') const [tshirtSize] = defineField('tshirt_size') const [firstAid] = defineField('first_aid') const [allergies] = defineField('allergies') -const [accessRequirements] = defineField('access_requirements') const [drivingLicence] = defineField('driving_licence') const [motivation] = defineField('motivation') const [motivationOther] = defineField('motivation_other') @@ -159,11 +157,11 @@ const formattedDates = computed(() => { }) // Step field mapping for validation (0-based) -type FormField = 'first_name' | 'last_name' | 'date_of_birth' | 'email' | 'phone' | 'tshirt_size' | 'first_aid' | 'allergies' | 'access_requirements' | 'driving_licence' | 'motivation' | 'motivation_other' +type FormField = 'first_name' | 'last_name' | 'date_of_birth' | 'email' | 'phone' | 'tshirt_size' | 'first_aid' | 'allergies' | 'driving_licence' | 'motivation' | 'motivation_other' const stepFields: Record = { 0: ['first_name', 'last_name', 'date_of_birth', 'email', 'phone'], - 1: ['tshirt_size', 'first_aid', 'allergies', 'access_requirements', 'driving_licence'], + 1: ['tshirt_size', 'first_aid', 'allergies', 'driving_licence'], 2: ['motivation', 'motivation_other'], } @@ -278,7 +276,6 @@ async function onSubmit() { tshirt_size: tshirtSize.value ?? '', first_aid: firstAid.value ?? false, allergies: allergies.value ?? '', - access_requirements: accessRequirements.value ?? '', driving_licence: drivingLicence.value ?? false, motivation: motivation.value ?? '', motivation_other: motivationOther.value ?? '', @@ -623,20 +620,28 @@ async function onSubmit() {

- +
+ @@ -644,13 +649,21 @@ async function onSubmit() { cols="12" md="6" > + @@ -658,40 +671,80 @@ async function onSubmit() { cols="12" md="6" > + - - - - - - - - + + + + + +
+ +
+ Contactgegevens +
+

+ Vul deze gegevens zorgvuldig in: we gebruiken ze om alle informatie over het evenement naar je te versturen. + Je e-mailadres is ook je gebruikersnaam voor Crewli, het systeem waar je straks alle informatie terugvindt. +

+ + + + + + + + + + @@ -704,21 +757,30 @@ async function onSubmit() { cols="12" md="6" > + -
+
+ - - -
@@ -770,14 +828,22 @@ async function onSubmit() { cols="12" md="6" > + @@ -786,15 +852,23 @@ async function onSubmit() { v-if="motivation" cols="12" > + @@ -1018,4 +1092,19 @@ async function onSubmit() { z-index: 1; 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; +} + +.volunteer-reg-dob-field :deep(input.v-field__input[type="date"]) { + flex: 1 1 auto; + max-inline-size: 100%; + min-inline-size: 0; +} diff --git a/apps/portal/src/schemas/registrationSchema.ts b/apps/portal/src/schemas/registrationSchema.ts index a5ac5b70..34f30601 100644 --- a/apps/portal/src/schemas/registrationSchema.ts +++ b/apps/portal/src/schemas/registrationSchema.ts @@ -12,7 +12,6 @@ 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('')), - access_requirements: z.string().max(500).optional().or(z.literal('')), driving_licence: z.boolean().default(false), }) diff --git a/apps/portal/src/types/registration.ts b/apps/portal/src/types/registration.ts index 204fc88a..9a7b1a14 100644 --- a/apps/portal/src/types/registration.ts +++ b/apps/portal/src/types/registration.ts @@ -51,7 +51,6 @@ export interface VolunteerRegistrationForm { tshirt_size: string first_aid: boolean allergies: string - access_requirements: string driving_licence: boolean // Step 3 motivation: string diff --git a/dev-docs/SCHEMA.md b/dev-docs/SCHEMA.md index bfd9484e..a1bb361f 100644 --- a/dev-docs/SCHEMA.md +++ b/dev-docs/SCHEMA.md @@ -558,7 +558,6 @@ $effectiveDate = $shift->end_date ?? $shift->timeSlot->date; | `first_aid` | bool | | | `driving_licence` | bool | | | `allergies` | text nullable | | -| `access_requirements` | text nullable | | | `emergency_contact_name` | string nullable | | | `emergency_contact_phone` | string nullable | | | `reliability_score` | decimal(3,2) | 0.00–5.00, computed via scheduled job | diff --git a/dev-docs/design-document.md b/dev-docs/design-document.md index fab9f0de..e1529942 100644 --- a/dev-docs/design-document.md +++ b/dev-docs/design-document.md @@ -359,7 +359,7 @@ Drielaags Crescat-model. Kritieke verbetering: time_slot_id gedenormaliseerd naa | **Tabel** | **Belangrijkste kolommen** | **Relaties, constraints & opmerkingen** | |----|----|----| -| **volunteer_profiles** | id (ULID), user_id (FK unique), bio, photo_url, tshirt_size, first_aid (bool), driving_licence (bool), allergies, access_requirements, emergency_contact_name, emergency_contact_phone, reliability_score (decimal 3,2), is_ambassador | Platform-breed, 1-op-1 met users. reliability_score 0.00-5.00, berekend via scheduled job. UNIQUE(user_id). | +| **volunteer_profiles** | id (ULID), user_id (FK unique), bio, photo_url, tshirt_size, first_aid (bool), driving_licence (bool), allergies, emergency_contact_name, emergency_contact_phone, reliability_score (decimal 3,2), is_ambassador | Platform-breed, 1-op-1 met users. reliability_score 0.00-5.00, berekend via scheduled job. UNIQUE(user_id). | | **volunteer_festival_history** | id (ULID), user_id, event_id, organisation_id, hours_planned, hours_completed, no_show_count, coordinator_rating (tinyint 1-5), coordinator_notes, would_reinvite (bool) | Per gebruiker per festival. Nooit zichtbaar voor vrijwilliger zelf. INDEX: (user_id, event_id), UNIQUE(user_id, event_id). | | **post_festival_evaluations** | id (ULID), event_id, person_id, shift_id (nullable), overall_rating (tinyint 1-5), shift_rating (tinyint 1-5), would_return (bool), feedback_text, improvement_suggestion, submitted_at, is_anonymous | Vrijwilliger evalueert na afloop. INDEX: (event_id, is_anonymous), (person_id). | | **festival_retrospectives** | id (ULID), event_id (unique), generated_at, volunteers_planned (int), volunteers_completed (int), no_show_count (int), no_show_pct (decimal 5,2), avg_overall_satisfaction (decimal 3,2), avg_shift_satisfaction (decimal 3,2), would_return_pct (decimal 5,2), sections_understaffed (int), sections_overstaffed (int), top_feedback (JSON: array of strings), notes (text) | Oplossing probleem 8: alle KPIs als concrete kolommen ipv JSON blob. Trendanalyse over meerdere jaren mogelijk. JSON alleen voor vrije-tekst feedback array. | @@ -604,7 +604,7 @@ Vrijwilligers zijn de kern van elke festival-organisatie. Dit module ontlast de - **Deel 1 — Over jou: Naam, e-mail, telefoon (met landcode).** -- **Deel 2 — Meer over jou: Shirtmaat, EHBO, allergieën, toegangsbehoeften, rijbewijs. Geconfigureerd via de formulierbouwer.** +- **Deel 2 — Meer over jou: Shirtmaat, EHBO, allergieën, rijbewijs. Geconfigureerd via de formulierbouwer.** - **Deel 3 — Motivatie: Waarom wil je vrijwilliger zijn? Dropdown + vrije tekst.**