feat: add date_of_birth field to persons across all layers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-11 09:06:29 +02:00
parent d2f282eb4c
commit 6dccf87234
18 changed files with 161 additions and 17 deletions

View File

@@ -23,6 +23,7 @@ const form = ref({
crowd_type_id: '',
first_name: '',
last_name: '',
date_of_birth: '',
email: '',
phone: '',
company_id: '',
@@ -72,6 +73,7 @@ function resetForm() {
crowd_type_id: '',
first_name: '',
last_name: '',
date_of_birth: '',
email: '',
phone: '',
company_id: '',
@@ -91,6 +93,7 @@ function onSubmit() {
crowd_type_id: form.value.crowd_type_id,
first_name: form.value.first_name,
last_name: form.value.last_name,
...(form.value.date_of_birth ? { date_of_birth: form.value.date_of_birth } : {}),
email: form.value.email,
...(form.value.phone ? { phone: form.value.phone } : {}),
...(form.value.company_id ? { company_id: form.value.company_id } : {}),
@@ -164,6 +167,17 @@ function onSubmit() {
:error-messages="errors.last_name"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="form.date_of_birth"
label="Geboortedatum"
type="date"
:error-messages="errors.date_of_birth"
/>
</VCol>
<VCol cols="12">
<AppTextField
v-model="form.email"

View File

@@ -25,6 +25,7 @@ const form = ref({
crowd_type_id: '',
first_name: '',
last_name: '',
date_of_birth: '',
email: '',
phone: '',
company_id: '',
@@ -42,6 +43,7 @@ watch(() => props.person, (p) => {
crowd_type_id: p.crowd_type?.id ?? '',
first_name: p.first_name,
last_name: p.last_name,
date_of_birth: p.date_of_birth ?? '',
email: p.email,
phone: p.phone ?? '',
company_id: p.company?.id ?? '',
@@ -96,6 +98,7 @@ function onSubmit() {
crowd_type_id: form.value.crowd_type_id,
first_name: form.value.first_name,
last_name: form.value.last_name,
date_of_birth: form.value.date_of_birth || undefined,
email: form.value.email,
phone: form.value.phone || undefined,
company_id: form.value.company_id || undefined,
@@ -167,6 +170,17 @@ function onSubmit() {
:error-messages="errors.last_name"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<AppTextField
v-model="form.date_of_birth"
label="Geboortedatum"
type="date"
:error-messages="errors.date_of_birth"
/>
</VCol>
<VCol cols="12">
<AppTextField
v-model="form.email"

View File

@@ -37,10 +37,20 @@ const dateFormatter = new Intl.DateTimeFormat('nl-NL', {
year: 'numeric',
})
const dobFormatter = new Intl.DateTimeFormat('nl-NL', {
day: 'numeric',
month: 'long',
year: 'numeric',
})
function formatDate(iso: string) {
return dateFormatter.format(new Date(iso))
}
function formatDateOfBirth(dateStr: string) {
return dobFormatter.format(new Date(`${dateStr}T00:00:00`))
}
function getInitials(name: string) {
return name
.split(' ')
@@ -175,6 +185,17 @@ function onBlacklistToggle(val: boolean | null) {
<!-- Tab: Informatie -->
<VTabsWindowItem value="info">
<VList class="pa-0">
<VListItem>
<template #prepend>
<VIcon
icon="tabler-cake"
class="me-3"
/>
</template>
<VListItemTitle>Geboortedatum</VListItemTitle>
<VListItemSubtitle>{{ person.date_of_birth ? formatDateOfBirth(person.date_of_birth) : 'Niet opgegeven' }}</VListItemSubtitle>
</VListItem>
<VListItem>
<template #prepend>
<VIcon

View File

@@ -47,6 +47,7 @@ export interface Person {
id: string
first_name: string
last_name: string
date_of_birth: string | null
full_name: string
email: string
phone: string | null
@@ -67,6 +68,7 @@ export interface CreatePersonPayload {
crowd_type_id: string
first_name: string
last_name: string
date_of_birth?: string
email: string
phone?: string
company_id?: string

View File

@@ -40,6 +40,7 @@ const { errors, defineField, validateField, setFieldValue } = useForm({
first_name: '',
last_name: '',
email: '',
date_of_birth: '',
phone: '',
tshirt_size: '',
first_aid: false,
@@ -53,6 +54,7 @@ const { errors, defineField, validateField, setFieldValue } = useForm({
const [firstName] = defineField('first_name')
const [lastName] = defineField('last_name')
const [dateOfBirth] = defineField('date_of_birth')
const [email] = defineField('email')
const [phone] = defineField('phone')
const [tshirtSize] = defineField('tshirt_size')
@@ -157,10 +159,10 @@ const formattedDates = computed(() => {
})
// Step field mapping for validation (0-based)
type FormField = 'first_name' | 'last_name' | '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' | 'access_requirements' | 'driving_licence' | 'motivation' | 'motivation_other'
const stepFields: Record<number, FormField[]> = {
0: ['first_name', 'last_name', 'email', 'phone'],
0: ['first_name', 'last_name', 'date_of_birth', 'email', 'phone'],
1: ['tshirt_size', 'first_aid', 'allergies', 'access_requirements', 'driving_licence'],
2: ['motivation', 'motivation_other'],
}
@@ -270,6 +272,7 @@ async function onSubmit() {
const payload: VolunteerRegistrationForm = {
first_name: firstName.value ?? '',
last_name: lastName.value ?? '',
date_of_birth: dateOfBirth.value ?? '',
email: email.value ?? '',
phone: phone.value ?? '',
tshirt_size: tshirtSize.value ?? '',
@@ -678,6 +681,19 @@ async function onSubmit() {
density="comfortable"
/>
</VCol>
<VCol
cols="12"
md="6"
>
<VTextField
v-model="dateOfBirth"
label="Geboortedatum"
type="date"
:error-messages="errors.date_of_birth"
density="comfortable"
/>
</VCol>
</VRow>
</div>

View File

@@ -4,6 +4,7 @@ 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),
date_of_birth: z.string().optional().or(z.literal('')),
phone: z.string().max(50).optional().or(z.literal('')),
})

View File

@@ -44,6 +44,7 @@ export interface VolunteerRegistrationForm {
// Step 1
first_name: string
last_name: string
date_of_birth: string
email: string
phone: string
// Step 2