fix(settings): gender is set only in the people archive; drop the 个人资料 duplicate (BUG-1119)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3177ffe61d
commit
3e29b697db
@@ -319,7 +319,6 @@ export default function Home() {
|
||||
openAccountDialog,
|
||||
closeAccountDialog,
|
||||
persistAvatar,
|
||||
persistGender,
|
||||
saveOnboardingName,
|
||||
saveOnboardingBirth,
|
||||
saveOnboardingPlace,
|
||||
@@ -1129,7 +1128,7 @@ export default function Home() {
|
||||
overlayRef: accountDialog,
|
||||
closeButtonRef: closeButton,
|
||||
renderProfile: () => (
|
||||
<ProfilePanel account={account} profile={profile} avatarSaving={avatarSaving} avatarNotice={avatarNotice} accountError={accountError} persistAvatar={persistAvatar} persistGender={persistGender} />
|
||||
<ProfilePanel account={account} profile={profile} avatarSaving={avatarSaving} avatarNotice={avatarNotice} accountError={accountError} persistAvatar={persistAvatar} />
|
||||
),
|
||||
renderChartLibrary() {
|
||||
return null;
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
|
||||
import { ProfileGenderField } from "@/components/profile-gender-field";
|
||||
import { UserAvatar } from "@/components/user-avatar";
|
||||
import { beamAvatarPalettes, type BeamAvatarPatch } from "@/lib/beam-avatar";
|
||||
import type { Account, Profile } from "@/lib/home-types";
|
||||
import type { ProfileGender } from "@/lib/profile-gender";
|
||||
|
||||
export type ProfilePanelProps = {
|
||||
readonly account: Account;
|
||||
@@ -15,8 +11,6 @@ export type ProfilePanelProps = {
|
||||
readonly avatarNotice: string;
|
||||
readonly accountError: string;
|
||||
readonly persistAvatar: (patch: BeamAvatarPatch) => void;
|
||||
/** Saves the owner's optional gender on its own (not part of any birth-data save). */
|
||||
readonly persistGender?: (gender: ProfileGender | null) => Promise<void>;
|
||||
};
|
||||
|
||||
export function ProfilePanel({
|
||||
@@ -26,7 +20,6 @@ export function ProfilePanel({
|
||||
avatarNotice,
|
||||
accountError,
|
||||
persistAvatar,
|
||||
persistGender,
|
||||
}: ProfilePanelProps) {
|
||||
return (
|
||||
<>
|
||||
@@ -77,40 +70,6 @@ export function ProfilePanel({
|
||||
<div><dt>登录邮箱</dt><dd>{account.user.email || "尚未读取邮箱"}</dd></div>
|
||||
</dl>
|
||||
</section>
|
||||
{persistGender ? <OwnerGenderSection value={profile.gender ?? null} persistGender={persistGender} /> : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
/** 本人的性别(选填): saved as soon as a choice is made, like the avatar palette. */
|
||||
function OwnerGenderSection({
|
||||
value,
|
||||
persistGender,
|
||||
}: {
|
||||
readonly value: ProfileGender | null;
|
||||
readonly persistGender: (gender: ProfileGender | null) => Promise<void>;
|
||||
}) {
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [notice, setNotice] = useState("");
|
||||
const [error, setError] = useState("");
|
||||
async function choose(gender: ProfileGender | null) {
|
||||
setSaving(true);
|
||||
setNotice("");
|
||||
setError("");
|
||||
try {
|
||||
await persistGender(gender);
|
||||
setNotice("已保存。");
|
||||
} catch (caught) {
|
||||
setError(caught instanceof Error && caught.message ? caught.message : "性别没保存上,再试一次。");
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<section className="sheet-section" aria-label="性别">
|
||||
<ProfileGenderField idPrefix="account-profile" value={value} disabled={saving} onChange={(gender) => void choose(gender)} />
|
||||
{notice ? <p className="form-success" role="status">{notice}</p> : null}
|
||||
{error ? <p className="form-error" role="alert">{error}</p> : null}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import {
|
||||
readProfile,
|
||||
selectedBirthPlace,
|
||||
} from "@/lib/home-profile";
|
||||
import { withSavedGender, type ProfileGender } from "@/lib/profile-gender";
|
||||
import { saveSelfProfile } from "@/lib/self-profile-save";
|
||||
import { createStartGreeting } from "@/lib/starter-greeting";
|
||||
import { clearHomeWarmSnapshot } from "@/lib/home-warm-snapshot";
|
||||
@@ -194,26 +193,6 @@ export function useProfileOnboarding(params: ProfileOnboardingParams) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The owner's optional gender (设置 → 个人资料). A PATCH of this one field:
|
||||
* birth-data saves never send it, so they can never clear it.
|
||||
*/
|
||||
async function persistGender(gender: ProfileGender | null): Promise<void> {
|
||||
if (!account) throw new Error("账户尚未加载完成");
|
||||
const response = await fetch("/api/account", {
|
||||
method: "PATCH",
|
||||
credentials: "same-origin",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: JSON.stringify({ gender }),
|
||||
});
|
||||
const payload = await response.json().catch(() => null) as { error?: string } | null;
|
||||
if (!response.ok) throw new Error(payload?.error || "性别没保存上,再试一次。");
|
||||
const apply = (current: Profile): Profile => ({ ...current, gender });
|
||||
setProfile(apply);
|
||||
setProfileDraft(apply);
|
||||
setAccount((current) => current ? { ...current, profile: withSavedGender(current.profile, gender) } : current);
|
||||
}
|
||||
|
||||
async function persistProfile(nextProfile: Profile): Promise<Profile> {
|
||||
if (!account) throw new Error("账户尚未加载完成");
|
||||
if (process.env.NODE_ENV === "development" && uiPreview.current) return nextProfile;
|
||||
@@ -384,7 +363,6 @@ export function useProfileOnboarding(params: ProfileOnboardingParams) {
|
||||
openAccountDialog,
|
||||
closeAccountDialog,
|
||||
persistAvatar,
|
||||
persistGender,
|
||||
persistProfile,
|
||||
assessSavedBirthTime,
|
||||
saveOnboardingName,
|
||||
|
||||
@@ -35,9 +35,3 @@ export function profileGenderLabel(value: unknown): string {
|
||||
const gender = parseProfileGender(value);
|
||||
return gender ? PROFILE_GENDER_LABELS[gender] : PROFILE_GENDER_EMPTY_LABEL;
|
||||
}
|
||||
|
||||
/** The account's raw profile object with the saved gender (null = not filled). */
|
||||
export function withSavedGender(profile: unknown, gender: ProfileGender | null): Record<string, unknown> {
|
||||
const base = profile && typeof profile === "object" && !Array.isArray(profile) ? profile as Record<string, unknown> : {};
|
||||
return { ...base, gender };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user