From 93c22b4bcf35574d36c11e04e50b5365f5f6e5d5 Mon Sep 17 00:00:00 2001 From: Justin Paul Date: Mon, 8 Jun 2026 21:42:59 -0400 Subject: [PATCH] Person page: one-click sex setter (no edit mode) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting a person's sex meant clicking Edit, opening a dropdown, and saving. Replace the read-only ♂/♀ symbol next to the name with an always-visible two-button segmented control that PATCHes immediately on click (gender-only; backend PATCH is exclude_unset so the name/other fields are untouched). Clicking the active sex clears it. The full edit form still offers gender for completeness. Co-Authored-By: Claude Opus 4.8 (1M context) Signed-off-by: Justin Paul --- .../trees/[id]/persons/[personId]/page.tsx | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/frontend/app/trees/[id]/persons/[personId]/page.tsx b/frontend/app/trees/[id]/persons/[personId]/page.tsx index 8c0bad2..211796f 100644 --- a/frontend/app/trees/[id]/persons/[personId]/page.tsx +++ b/frontend/app/trees/[id]/persons/[personId]/page.tsx @@ -535,6 +535,16 @@ export default function PersonDetailPage() { setEditingPerson(true); } + // Quick one-click sex setter — no need to open the full edit form. PATCH is + // exclude_unset on the backend, so sending only `gender` leaves the rest. + async function setGender(value: "male" | "female" | null) { + await api.PATCH("/api/v1/trees/{tree_id}/persons/{person_id}", { + params: { path: { tree_id: treeId, person_id: personId } }, + body: { gender: value }, + }); + load(); + } + async function savePerson() { const { error } = await api.PATCH("/api/v1/trees/{tree_id}/persons/{person_id}", { params: { path: { tree_id: treeId, person_id: personId } }, @@ -711,16 +721,35 @@ export default function PersonDetailPage() {

{person.primary_name ?? "Unnamed person"} - {person.gender === "male" && ( - - ♂ - - )} - {person.gender === "female" && ( - - ♀ - - )} + + {/* One-click sex setter — no edit mode needed. Active = current; click it again to clear. */} + + + {isSelf && ( -- 2.52.0