Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
70 lines
2.7 KiB
TypeScript
70 lines
2.7 KiB
TypeScript
"use client";
|
|
|
|
import { UserAvatar } from "@/components/user-avatar";
|
|
import { beamAvatarPalettes, type BeamAvatarPatch } from "@/lib/beam-avatar";
|
|
import type { Account, Profile } from "@/lib/home-types";
|
|
|
|
export type ProfilePanelProps = {
|
|
readonly account: Account;
|
|
readonly profile: Profile;
|
|
readonly avatarSaving: boolean;
|
|
readonly persistAvatar: (patch: BeamAvatarPatch) => void;
|
|
};
|
|
|
|
export function ProfilePanel({
|
|
account,
|
|
profile,
|
|
avatarSaving,
|
|
persistAvatar,
|
|
}: ProfilePanelProps) {
|
|
return (
|
|
<>
|
|
{account.avatar && (
|
|
<section className="sheet-section avatar-section" aria-labelledby="avatar-section-title">
|
|
<div className="section-heading">
|
|
<b id="avatar-section-title">账户头像</b>
|
|
<small>Beam 形象会在刷新和换设备后保持一致</small>
|
|
</div>
|
|
<div className="avatar-editor">
|
|
<UserAvatar avatar={account.avatar} size={56} label="当前头像预览" />
|
|
<div className="avatar-editor-controls">
|
|
<div className="avatar-palette-list" role="radiogroup" aria-label="头像配色">
|
|
{beamAvatarPalettes.map((palette, index) => (
|
|
<button
|
|
key={palette.name}
|
|
className="avatar-palette"
|
|
type="button"
|
|
role="radio"
|
|
aria-checked={account.avatar?.palette === index}
|
|
aria-label={palette.name}
|
|
title={palette.name}
|
|
disabled={avatarSaving}
|
|
onClick={() => void persistAvatar({ action: "set_palette", palette: index })}
|
|
>
|
|
{palette.colors.map((color) => <span key={color} style={{ backgroundColor: color }} />)}
|
|
</button>
|
|
))}
|
|
</div>
|
|
<button
|
|
className="button-secondary avatar-randomize"
|
|
type="button"
|
|
disabled={avatarSaving}
|
|
onClick={() => void persistAvatar({ action: "randomize" })}
|
|
>
|
|
{avatarSaving ? "保存中" : "换一个形象"}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)}
|
|
<section className="sheet-section" aria-labelledby="account-info-title">
|
|
<div className="section-heading"><b id="account-info-title">账户信息</b><small>登录与账户识别信息</small></div>
|
|
<dl className="account-info-list">
|
|
<div><dt>昵称</dt><dd>{profile.name.trim() || "尚未设置"}<small>与“我的星盘”名称同步</small></dd></div>
|
|
<div><dt>登录邮箱</dt><dd>{account.user.email || "尚未读取邮箱"}</dd></div>
|
|
</dl>
|
|
</section>
|
|
</>
|
|
);
|
|
}
|