Person page: one-click sex setter (no edit mode) #39

Merged
justin merged 1 commits from quick-set-sex into main 2026-06-08 22:03:32 -04:00
@@ -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() {
<h1 className="flex flex-wrap items-center gap-3 text-3xl font-semibold">
<span className="inline-flex items-center gap-2">
{person.primary_name ?? "Unnamed person"}
{person.gender === "male" && (
<span title="Male" aria-label="Male" style={{ color: "rgb(120, 159, 172)" }}>
</span>
)}
{person.gender === "female" && (
<span title="Female" aria-label="Female" style={{ color: "rgb(196, 138, 146)" }}>
</span>
)}
</span>
{/* One-click sex setter — no edit mode needed. Active = current; click it again to clear. */}
<span className="inline-flex items-center overflow-hidden rounded-md border border-[var(--border)] text-base font-normal">
<button
type="button"
onClick={() => setGender(person.gender === "male" ? null : "male")}
aria-pressed={person.gender === "male"}
title={person.gender === "male" ? "Male — click to clear" : "Set male"}
className={`px-3 py-1 leading-none transition-colors ${
person.gender === "male"
? "bg-[rgb(120,159,172)] text-white"
: "text-[var(--muted)] hover:bg-bronze/[0.07]"
}`}
>
</button>
<button
type="button"
onClick={() => setGender(person.gender === "female" ? null : "female")}
aria-pressed={person.gender === "female"}
title={person.gender === "female" ? "Female — click to clear" : "Set female"}
className={`border-l border-[var(--border)] px-3 py-1 leading-none transition-colors ${
person.gender === "female"
? "bg-[rgb(196,138,146)] text-white"
: "text-[var(--muted)] hover:bg-bronze/[0.07]"
}`}
>
</button>
</span>
{isSelf && (
<span className="rounded-full bg-bronze/15 px-2.5 py-1 text-xs font-medium text-bronze">