diff --git a/frontend/messages/de.json b/frontend/messages/de.json index d6c9a0ce..054a9cd8 100644 --- a/frontend/messages/de.json +++ b/frontend/messages/de.json @@ -174,12 +174,18 @@ "person_merge_warning": "Achtung: Diese Aktion ist nicht rückgängig zu machen.", "person_label_notes": "Notizen", "person_placeholder_notes": "Biographische Hinweise, Besonderheiten…", - "person_label_birth_year": "Geburtsjahr", - "person_label_death_year": "Todesjahr", + "person_label_birth_date": "Geburtsdatum", + "person_label_death_date": "Sterbedatum", + "person_label_birth_date_precision": "Genauigkeit", + "person_label_death_date_precision": "Genauigkeit", + "person_precision_hint": "Wie genau ist dieses Datum bekannt?", + "person_precision_day": "Genaues Datum (Tag)", + "person_precision_month": "Monat bekannt", + "person_precision_year": "Nur Jahreszahl", + "person_date_placeholder_hint": "Leer lassen, wenn unbekannt", "person_label_generation": "Generation", "person_option_generation_unset": "(keine)", "person_hint_generation": "Generation in der Familie (G 0 = älteste Generation)", - "person_placeholder_year": "z.B. 1923", "person_year_error": "Bitte eine vierstellige Jahreszahl eingeben", "person_years_error_order": "Geburtsjahr muss vor dem Todesjahr liegen", "person_docs_heading": "Gesendete Dokumente", diff --git a/frontend/messages/en.json b/frontend/messages/en.json index c330c78d..3711a251 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -174,12 +174,18 @@ "person_merge_warning": "Warning: This action cannot be undone.", "person_label_notes": "Notes", "person_placeholder_notes": "Biographical notes, remarks…", - "person_label_birth_year": "Birth year", - "person_label_death_year": "Death year", + "person_label_birth_date": "Date of birth", + "person_label_death_date": "Date of death", + "person_label_birth_date_precision": "Precision", + "person_label_death_date_precision": "Precision", + "person_precision_hint": "How precisely is this date known?", + "person_precision_day": "Exact date (day)", + "person_precision_month": "Month known", + "person_precision_year": "Year only", + "person_date_placeholder_hint": "Leave empty if unknown", "person_label_generation": "Generation", "person_option_generation_unset": "(none)", "person_hint_generation": "Generation within the family (G 0 = oldest generation)", - "person_placeholder_year": "e.g. 1923", "person_year_error": "Please enter a four-digit year", "person_years_error_order": "Birth year must be before death year", "person_docs_heading": "Sent documents", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index e6837b83..8fdec571 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -174,12 +174,18 @@ "person_merge_warning": "Atención: Esta acción no se puede deshacer.", "person_label_notes": "Notas", "person_placeholder_notes": "Notas biográficas, observaciones…", - "person_label_birth_year": "Año de nacimiento", - "person_label_death_year": "Año de fallecimiento", + "person_label_birth_date": "Fecha de nacimiento", + "person_label_death_date": "Fecha de defunción", + "person_label_birth_date_precision": "Precisión", + "person_label_death_date_precision": "Precisión", + "person_precision_hint": "¿Con qué precisión se conoce esta fecha?", + "person_precision_day": "Fecha exacta (día)", + "person_precision_month": "Mes conocido", + "person_precision_year": "Solo año", + "person_date_placeholder_hint": "Dejar vacío si es desconocido", "person_label_generation": "Generación", "person_option_generation_unset": "(ninguna)", "person_hint_generation": "Generación dentro de la familia (G 0 = generación más antigua)", - "person_placeholder_year": "p.ej. 1923", "person_year_error": "Introduzca un año de cuatro dígitos", "person_years_error_order": "El año de nacimiento debe ser anterior al año de fallecimiento", "person_docs_heading": "Documentos enviados", diff --git a/frontend/src/lib/person/PersonLifeDateField.svelte b/frontend/src/lib/person/PersonLifeDateField.svelte new file mode 100644 index 00000000..53a8e04f --- /dev/null +++ b/frontend/src/lib/person/PersonLifeDateField.svelte @@ -0,0 +1,96 @@ + + +
+ + {legend} + +
+
+ + +
+
+ +
+
+

+ {m.person_precision_hint()} · {m.person_date_placeholder_hint()} +

+
diff --git a/frontend/src/lib/person/person-validation.ts b/frontend/src/lib/person/person-validation.ts index 38823859..00bcfdf8 100644 --- a/frontend/src/lib/person/person-validation.ts +++ b/frontend/src/lib/person/person-validation.ts @@ -9,8 +9,10 @@ export type PersonFormData = { firstName?: string | null; lastName: string; alias?: string | null; - birthYear?: number | null; - deathYear?: number | null; + birthDate?: string | null; + birthDatePrecision?: string | null; + deathDate?: string | null; + deathDatePrecision?: string | null; generation?: number | null; notes?: string | null; }; diff --git a/frontend/src/routes/persons/[id]/edit/+page.server.ts b/frontend/src/routes/persons/[id]/edit/+page.server.ts index 91461f78..460d95f7 100644 --- a/frontend/src/routes/persons/[id]/edit/+page.server.ts +++ b/frontend/src/routes/persons/[id]/edit/+page.server.ts @@ -1,6 +1,7 @@ import { error, fail, redirect } from '@sveltejs/kit'; import { createApiClient, extractErrorCode } from '$lib/shared/api.server'; import { getErrorMessage } from '$lib/shared/errors'; +import type { DatePrecision } from '$lib/shared/utils/documentDate'; import { normalizePersonType, validatePersonFields, @@ -47,10 +48,17 @@ export const actions = { const lastName = formData.get('lastName')?.toString().trim(); const alias = formData.get('alias')?.toString().trim() || undefined; const notes = formData.get('notes')?.toString().trim() || undefined; - const birthYearStr = formData.get('birthYear')?.toString().trim(); - const deathYearStr = formData.get('deathYear')?.toString().trim(); - const birthYear = birthYearStr ? parseInt(birthYearStr, 10) : undefined; - const deathYear = deathYearStr ? parseInt(deathYearStr, 10) : undefined; + // Empty date input → omit date AND precision: the backend normalises the + // absent pair to null/UNKNOWN, and a lone precision would fail the + // coherence check (INVALID_DATE_PRECISION). + const birthDate = formData.get('birthDate')?.toString().trim() || undefined; + const birthDatePrecision = birthDate + ? (formData.get('birthDatePrecision')?.toString() as DatePrecision) + : undefined; + const deathDate = formData.get('deathDate')?.toString().trim() || undefined; + const deathDatePrecision = deathDate + ? (formData.get('deathDatePrecision')?.toString() as DatePrecision) + : undefined; // Must NOT use the conditional-spread idiom for generation: G 0 is a // valid family-tree-root value. The key always travels in the body so // an explicit clear (empty option) reaches the backend as null. @@ -73,8 +81,8 @@ export const actions = { lastName, ...(alias ? { alias } : {}), ...(notes ? { notes } : {}), - ...(birthYear ? { birthYear } : {}), - ...(deathYear ? { deathYear } : {}), + ...(birthDate ? { birthDate, birthDatePrecision } : {}), + ...(deathDate ? { deathDate, deathDatePrecision } : {}), generation } }); diff --git a/frontend/src/routes/persons/[id]/edit/PersonEditForm.svelte b/frontend/src/routes/persons/[id]/edit/PersonEditForm.svelte index 3a746550..c4b473c5 100644 --- a/frontend/src/routes/persons/[id]/edit/PersonEditForm.svelte +++ b/frontend/src/routes/persons/[id]/edit/PersonEditForm.svelte @@ -1,6 +1,7 @@