From 5b117800749bbf81ad8901934c3bcfb0cd552cd8 Mon Sep 17 00:00:00 2001 From: Gulum Date: Sat, 6 Jun 2026 09:08:46 +0200 Subject: [PATCH] FEAT-14b: trait vocabulary (de.character), Gerbil/sale-ad types, Charakterbogen component --- gerbil-manager-web/src/api/saleAd.ts | 3 + gerbil-manager-web/src/api/types.ts | 8 +++ .../src/components/Charakterbogen.tsx | 62 +++++++++++++++++++ .../src/components/charakterbogen.css | 41 ++++++++++++ gerbil-manager-web/src/format/traits.ts | 15 +++++ gerbil-manager-web/src/strings/de.ts | 28 +++++++++ 6 files changed, 157 insertions(+) create mode 100644 gerbil-manager-web/src/components/Charakterbogen.tsx create mode 100644 gerbil-manager-web/src/components/charakterbogen.css create mode 100644 gerbil-manager-web/src/format/traits.ts diff --git a/gerbil-manager-web/src/api/saleAd.ts b/gerbil-manager-web/src/api/saleAd.ts index 766cf34..11027a4 100644 --- a/gerbil-manager-web/src/api/saleAd.ts +++ b/gerbil-manager-web/src/api/saleAd.ts @@ -20,6 +20,9 @@ export interface SaleAdAnimal { farbschlag: string | null dateOfBirth: string | null notes: string | null + /** FEAT-14: German trait LABELS (human-readable for the prompt), not keys. */ + traits?: string[] + characterNote?: string | null } export interface SaleAdRequest { diff --git a/gerbil-manager-web/src/api/types.ts b/gerbil-manager-web/src/api/types.ts index a59aa3e..ebdedff 100644 --- a/gerbil-manager-web/src/api/types.ts +++ b/gerbil-manager-web/src/api/types.ts @@ -34,6 +34,12 @@ export interface Gerbil { /** Compact GEN-1 genotype string, e.g. "Aa CC Dd EE GG Pp Spsp rere" (or "?"-wildcards). */ genotype: string | null notes: string | null + /** + * FEAT-14: Charakterbogen. Selected trait KEYS (see de.character.traits). + * Optional until FEAT-14a backend exposes the fields; treat absent as []. + */ + characterTraits?: string[] | null + characterNote?: string | null } /** Payload for POST /gerbils. */ @@ -52,6 +58,8 @@ export interface CreateGerbil { receiverContactId?: string | null genotype?: string | null notes?: string | null + characterTraits?: string[] | null + characterNote?: string | null } /** Payload for PUT /gerbils/{id} (all optional / partial update). */ diff --git a/gerbil-manager-web/src/components/Charakterbogen.tsx b/gerbil-manager-web/src/components/Charakterbogen.tsx new file mode 100644 index 0000000..f8a7ad1 --- /dev/null +++ b/gerbil-manager-web/src/components/Charakterbogen.tsx @@ -0,0 +1,62 @@ +import { de } from '../strings/de' +import { ALL_TRAITS } from '../format/traits' +import './charakterbogen.css' + +export interface CharakterbogenProps { + /** Selected trait keys. */ + traits: string[] + note: string + onTraitsChange: (traits: string[]) => void + onNoteChange: (note: string) => void +} + +/** + * FEAT-14: character sheet — a checkbox grid of traits + a free note. + * Controlled & reusable: rendered on the animal detail page (persisted) and in + * the Abgabe listing composer (feeds the AI sale-text). German labels from + * de.character.traits; the stored value is the trait KEY. + */ +export default function Charakterbogen({ + traits, + note, + onTraitsChange, + onNoteChange, +}: CharakterbogenProps) { + const t = de.character + const selected = new Set(traits) + + const toggle = (key: string) => { + const next = new Set(selected) + if (next.has(key)) next.delete(key) + else next.add(key) + // Preserve the vocabulary order for stable output. + onTraitsChange(ALL_TRAITS.filter((tr) => next.has(tr.key)).map((tr) => tr.key)) + } + + return ( +
+ +