diff --git a/backend/src/main/java/org/raddatz/familienarchiv/controller/PersonController.java b/backend/src/main/java/org/raddatz/familienarchiv/controller/PersonController.java index 32a0a59f..e7da0a5a 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/controller/PersonController.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/controller/PersonController.java @@ -44,6 +44,21 @@ public class PersonController { return documentRepository.findBySenderId(id); } + @PostMapping + public ResponseEntity createPerson(@RequestBody Map body) { + String firstName = body.get("firstName"); + String lastName = body.get("lastName"); + if (firstName == null || firstName.isBlank() || lastName == null || lastName.isBlank()) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Vor- und Nachname sind Pflichtfelder"); + } + Person person = Person.builder() + .firstName(firstName.trim()) + .lastName(lastName.trim()) + .alias(body.get("alias")) + .build(); + return ResponseEntity.ok(personRepository.save(person)); + } + @PutMapping("/{id}") public ResponseEntity updatePerson(@PathVariable UUID id, @RequestBody Map body) { String firstName = body.get("firstName"); diff --git a/frontend/src/lib/generated/api.ts b/frontend/src/lib/generated/api.ts index e0445130..9de906e7 100644 --- a/frontend/src/lib/generated/api.ts +++ b/frontend/src/lib/generated/api.ts @@ -68,6 +68,22 @@ export interface paths { patch?: never; trace?: never; }; + "/api/persons": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: operations["getPersons"]; + put?: never; + post: operations["createPerson"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/persons/{id}/merge": { parameters: { query?: never; @@ -180,22 +196,6 @@ export interface paths { patch?: never; trace?: never; }; - "/api/persons": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get: operations["getPersons"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; "/api/persons/{id}/documents": { parameters: { query?: never; @@ -581,6 +581,54 @@ export interface operations { }; }; }; + getPersons: { + parameters: { + query?: { + q?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "*/*": components["schemas"]["Person"][]; + }; + }; + }; + }; + createPerson: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": { + [key: string]: string; + }; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "*/*": components["schemas"]["Person"]; + }; + }; + }; + }; mergePerson: { parameters: { query?: never; @@ -783,28 +831,6 @@ export interface operations { }; }; }; - getPersons: { - parameters: { - query?: { - q?: string; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "*/*": components["schemas"]["Person"][]; - }; - }; - }; - }; getPersonDocuments: { parameters: { query?: never; diff --git a/frontend/src/routes/persons/+page.svelte b/frontend/src/routes/persons/+page.svelte index 019195e6..f1ac7f88 100644 --- a/frontend/src/routes/persons/+page.svelte +++ b/frontend/src/routes/persons/+page.svelte @@ -1,84 +1,128 @@ -
- -
-
-

Personenverzeichnis

-

- Durchsuchen Sie den Index aller erfassten Personen im Familienarchiv. -

-
+
+ +
+
+

Personenverzeichnis

+

+ Durchsuchen Sie den Index aller erfassten Personen im Familienarchiv. +

+ + + + + Neue Person + +
- -
- -
- -
- -
-
-
-
+ +
+ +
+ +
+ +
+
+
+
- {#if data.persons.length === 0} -
-
- -
-

Keine Personen gefunden.

-

Versuchen Sie einen anderen Suchbegriff.

-
- {:else} - + {/if}
diff --git a/frontend/src/routes/persons/new/+page.server.ts b/frontend/src/routes/persons/new/+page.server.ts new file mode 100644 index 00000000..d58d969c --- /dev/null +++ b/frontend/src/routes/persons/new/+page.server.ts @@ -0,0 +1,26 @@ +import { fail, redirect } from '@sveltejs/kit'; +import { createApiClient } from '$lib/api.server'; + +export const actions = { + default: async ({ request, 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; + + if (!firstName || !lastName) { + return fail(400, { error: 'Vor- und Nachname sind Pflichtfelder.' }); + } + + const api = createApiClient(fetch); + const result = await api.POST('/api/persons', { + body: { firstName, lastName, ...(alias ? { alias } : {}) } + }); + + if (!result.response.ok) { + return fail(result.response.status, { error: 'Person konnte nicht gespeichert werden.' }); + } + + throw redirect(303, `/persons/${result.data!.id}`); + } +}; diff --git a/frontend/src/routes/persons/new/+page.svelte b/frontend/src/routes/persons/new/+page.svelte new file mode 100644 index 00000000..afc6dd6f --- /dev/null +++ b/frontend/src/routes/persons/new/+page.svelte @@ -0,0 +1,100 @@ + + +
+ + + + {#if form?.error} +
{form.error}
+ {/if} + +
+
+

+ Angaben zur Person +

+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+
+
+ + +
+ + Abbrechen + + +
+
+