diff --git a/prisma/migrations/20260714120000_person_name/migration.sql b/prisma/migrations/20260714120000_person_name/migration.sql new file mode 100644 index 0000000..1a0f750 --- /dev/null +++ b/prisma/migrations/20260714120000_person_name/migration.sql @@ -0,0 +1,2 @@ +-- Optionaler Anzeigename je Person (Fallback im UI: "Person A" / "Person B"). +ALTER TABLE "Person" ADD COLUMN "name" TEXT; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index c69e746..64aab8e 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -60,6 +60,7 @@ model Person { planId String plan Plan @relation(fields: [planId], references: [id], onDelete: Cascade) role PersonRole + name String? age Int retirementAge Int diff --git a/src/app/api/plans/[planId]/scenario/route.ts b/src/app/api/plans/[planId]/scenario/route.ts index f11722f..fc08c3c 100644 --- a/src/app/api/plans/[planId]/scenario/route.ts +++ b/src/app/api/plans/[planId]/scenario/route.ts @@ -42,7 +42,7 @@ export async function POST( inflationRateDefault: source.inflationRateDefault, parentPlanId: source.id, persons: { - create: source.persons.map((p) => ({ role: p.role, age: p.age, retirementAge: p.retirementAge })), + create: source.persons.map((p) => ({ role: p.role, name: p.name, age: p.age, retirementAge: p.retirementAge })), }, }, }); diff --git a/src/app/api/plans/route.ts b/src/app/api/plans/route.ts index 43da198..3cc9c8e 100644 --- a/src/app/api/plans/route.ts +++ b/src/app/api/plans/route.ts @@ -5,6 +5,7 @@ import { getCurrentUserId } from "@/lib/session"; const personSchema = z.object({ role: z.enum(["PERSON_A", "PERSON_B"]), + name: z.string().max(60).nullish(), age: z.number().int().min(0).max(120), retirementAge: z.number().int().min(30).max(100), }); diff --git a/src/components/PlanProfileFields.tsx b/src/components/PlanProfileFields.tsx index f803860..fa56e4c 100644 --- a/src/components/PlanProfileFields.tsx +++ b/src/components/PlanProfileFields.tsx @@ -1,19 +1,19 @@ "use client"; -import { NumberField, SelectField } from "@/components/FormField"; +import { NumberField, SelectField, TextField } from "@/components/FormField"; import type { HouseholdType, PersonRole } from "@/lib/types"; export interface ProfileDraft { householdType: HouseholdType; inflationRateDefault: number; - persons: { role: PersonRole; age: number; retirementAge: number }[]; + persons: { role: PersonRole; name: string; age: number; retirementAge: number }[]; } export function emptyProfileDraft(): ProfileDraft { return { householdType: "SINGLE", inflationRateDefault: 1.5, - persons: [{ role: "PERSON_A", age: 35, retirementAge: 65 }], + persons: [{ role: "PERSON_A", name: "", age: 35, retirementAge: 65 }], }; } @@ -32,7 +32,7 @@ export function PlanProfileFields({ } else { const persons = draft.persons.length < 2 - ? [...draft.persons, { role: "PERSON_B" as PersonRole, age: 35, retirementAge: 65 }] + ? [...draft.persons, { role: "PERSON_B" as PersonRole, name: "", age: 35, retirementAge: 65 }] : draft.persons; onChange({ ...draft, householdType: type, persons }); } @@ -63,6 +63,14 @@ export function PlanProfileFields({
{draft.householdType === "COUPLE" ? (person.role === "PERSON_A" ? "Person A" : "Person B") : "Ihre Angaben"}
+
+ updatePerson(index, { name: v })} + /> +
x.role === role); + if (p?.name && p.name.trim()) return p.name.trim(); + return role === "PERSON_A" ? "Person A" : "Person B"; + } + const personAxes = plan.persons.map((p) => ({ role: p.role, - label: p.role === "PERSON_A" ? "Person A" : "Person B", + label: personLabel(p.role), currentAge: p.age, retirementAge: p.retirementAge, color: p.role === "PERSON_A" ? "var(--person-a)" : "var(--person-b)", @@ -242,7 +249,7 @@ export function PlanView({ Grundprofil (Plan) {plan.persons.map((p) => ( - {plan.householdType === "COUPLE" ? (p.role === "PERSON_A" ? "Person A" : "Person B") : "Person"}: {p.age} J., Pension {p.retirementAge} + {personLabel(p.role)}: {p.age} J., Pension {p.retirementAge} ))} Inflation {plan.inflationRateDefault}% @@ -347,9 +354,7 @@ export function PlanView({
{el.name}
{el.ownerRole && el.ownerRole !== "HOUSEHOLD" && ( -
- {el.ownerRole === "PERSON_A" ? "Person A" : "Person B"} -
+
{personLabel(el.ownerRole)}
)} {columns.map((col) => { @@ -675,23 +680,27 @@ function AddElementDialog({ const needsPerson = PERSON_ONLY_CATEGORIES.includes(category); const isCouple = plan.householdType === "COUPLE"; + const pLabel = (role: string) => { + const p = plan.persons.find((x) => x.role === role); + return p?.name && p.name.trim() ? p.name.trim() : role === "PERSON_A" ? "Person A" : "Person B"; + }; const ownerOptions = needsPerson ? isCouple ? [ - { value: "PERSON_A", label: "Person A" }, - { value: "PERSON_B", label: "Person B" }, + { value: "PERSON_A", label: pLabel("PERSON_A") }, + { value: "PERSON_B", label: pLabel("PERSON_B") }, ] - : [{ value: "PERSON_A", label: "Person A" }] + : [{ value: "PERSON_A", label: pLabel("PERSON_A") }] : isCouple ? [ { value: "HOUSEHOLD", label: "Gemeinsam" }, - { value: "PERSON_A", label: "Person A" }, - { value: "PERSON_B", label: "Person B" }, + { value: "PERSON_A", label: pLabel("PERSON_A") }, + { value: "PERSON_B", label: pLabel("PERSON_B") }, ] : [ { value: "HOUSEHOLD", label: "Gemeinsam" }, - { value: "PERSON_A", label: "Person A" }, + { value: "PERSON_A", label: pLabel("PERSON_A") }, ]; // Kontext fuer die Phase-1-Felder des neuen Elements. @@ -864,7 +873,7 @@ function PlanSettingsDialog({ plan, onClose, onSaved }: { plan: PlanInput; onClo const [draft, setDraft] = useState({ householdType: plan.householdType, inflationRateDefault: plan.inflationRateDefault, - persons: plan.persons.map((p) => ({ role: p.role, age: p.age, retirementAge: p.retirementAge })), + persons: plan.persons.map((p) => ({ role: p.role, name: p.name ?? "", age: p.age, retirementAge: p.retirementAge })), }); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); diff --git a/src/lib/queries.ts b/src/lib/queries.ts index 80d4cd8..20361e7 100644 --- a/src/lib/queries.ts +++ b/src/lib/queries.ts @@ -34,6 +34,7 @@ export function toPlanInput(plan: PlanWithRelations): PlanInput { persons: plan.persons.map((p) => ({ id: p.id, role: p.role, + name: p.name, age: p.age, retirementAge: p.retirementAge, })), diff --git a/src/lib/types.ts b/src/lib/types.ts index 30afd6a..d113670 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -11,6 +11,7 @@ export type PersonRole = "PERSON_A" | "PERSON_B"; export interface PersonInput { id: string; role: PersonRole; + name: string | null; age: number; retirementAge: number; }