diff --git a/frontend/src/routes/persons/[id]/edit/+page.server.ts b/frontend/src/routes/persons/[id]/edit/+page.server.ts new file mode 100644 index 00000000..6b5f9ebc --- /dev/null +++ b/frontend/src/routes/persons/[id]/edit/+page.server.ts @@ -0,0 +1,87 @@ +import { error, fail, redirect } from '@sveltejs/kit'; +import { createApiClient } from '$lib/api.server'; +import { getErrorMessage } from '$lib/errors'; + +export async function load({ params, fetch, locals }) { + const canWrite = + (locals.user as { groups?: { permissions: string[] }[] } | undefined)?.groups?.some((g) => + g.permissions.includes('WRITE_ALL') + ) ?? false; + + if (!canWrite) throw error(403, 'Forbidden'); + + const { id } = params; + const api = createApiClient(fetch); + const result = await api.GET('/api/persons/{id}', { params: { path: { id } } }); + + if (!result.response.ok) { + const code = (result.error as unknown as { code?: string })?.code; + throw error(result.response.status, getErrorMessage(code)); + } + + return { person: result.data! }; +} + +export const actions = { + update: async ({ request, params, fetch }) => { + const formData = await request.formData(); + const firstName = formData.get('firstName')?.toString().trim(); + 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; + + if (!firstName || !lastName) { + return fail(400, { updateError: 'Vor- und Nachname sind Pflichtfelder.' }); + } + + const api = createApiClient(fetch); + const result = await api.PUT('/api/persons/{id}', { + params: { path: { id: params.id } }, + body: { + firstName, + lastName, + ...(alias ? { alias } : {}), + ...(notes ? { notes } : {}), + ...(birthYear ? { birthYear } : {}), + ...(deathYear ? { deathYear } : {}) + } + }); + + if (!result.response.ok) { + const code = (result.error as unknown as { code?: string })?.code; + return fail(result.response.status, { updateError: getErrorMessage(code) }); + } + + throw redirect(303, `/persons/${params.id}`); + }, + + discard: async ({ params }) => { + throw redirect(303, `/persons/${params.id}`); + }, + + merge: async ({ request, params, fetch }) => { + const formData = await request.formData(); + const targetPersonId = formData.get('targetPersonId')?.toString(); + + if (!targetPersonId) { + return fail(400, { mergeError: 'Bitte eine Zielperson auswählen.' }); + } + + const api = createApiClient(fetch); + const result = await api.POST('/api/persons/{id}/merge', { + params: { path: { id: params.id } }, + body: { targetPersonId } + }); + + if (!result.response.ok) { + const code = (result.error as unknown as { code?: string })?.code; + return fail(result.response.status, { mergeError: getErrorMessage(code) }); + } + + throw redirect(303, `/persons/${targetPersonId}`); + } +}; diff --git a/frontend/src/routes/persons/[id]/edit/+page.svelte b/frontend/src/routes/persons/[id]/edit/+page.svelte new file mode 100644 index 00000000..a3483e4b --- /dev/null +++ b/frontend/src/routes/persons/[id]/edit/+page.svelte @@ -0,0 +1,56 @@ + + +
+ +
+ + + + + {person.firstName} + {person.lastName} + +

{m.person_edit_heading()}

+
+ + {#if form?.updateError} +
+ {form.updateError} +
+ {/if} + +
+
+

+ {m.persons_section_details()} +

+ +
+ + + + + +
diff --git a/frontend/src/routes/persons/[id]/edit/PersonDangerZone.svelte b/frontend/src/routes/persons/[id]/edit/PersonDangerZone.svelte new file mode 100644 index 00000000..b5fe3025 --- /dev/null +++ b/frontend/src/routes/persons/[id]/edit/PersonDangerZone.svelte @@ -0,0 +1,44 @@ + + +
+ + + {#if open} +
+ {#key person.id} + + {/key} +
+ {/if} +
diff --git a/frontend/src/routes/persons/[id]/edit/PersonEditForm.svelte b/frontend/src/routes/persons/[id]/edit/PersonEditForm.svelte new file mode 100644 index 00000000..de77c3e7 --- /dev/null +++ b/frontend/src/routes/persons/[id]/edit/PersonEditForm.svelte @@ -0,0 +1,100 @@ + + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
diff --git a/frontend/src/routes/persons/[id]/edit/PersonEditSaveBar.svelte b/frontend/src/routes/persons/[id]/edit/PersonEditSaveBar.svelte new file mode 100644 index 00000000..ff6c3042 --- /dev/null +++ b/frontend/src/routes/persons/[id]/edit/PersonEditSaveBar.svelte @@ -0,0 +1,21 @@ + + + +
+ + {m.person_discard_changes()} + + +