fix: 个人中心布局整理(昵称/博客/签名/QQ 统一列布局+单个保存按钮,消除多按钮/空白碎片)
This commit is contained in:
@@ -34,10 +34,8 @@ export default function Profile() {
|
||||
const [rainidEnabled, setRainidEnabled] = useState(false);
|
||||
// QQ 号(rainweb 层字段,后端返回 qq 时显示编辑;用于 QQ 头像渲染优先级)
|
||||
const [qq, setQq] = useState('');
|
||||
const [qqBusy, setQqBusy] = useState(false);
|
||||
// 个性签名(公开主页 bio)
|
||||
const [bio, setBio] = useState('');
|
||||
const [bioBusy, setBioBusy] = useState(false);
|
||||
// 对外昵称 + 个人博客(全站作者名 / 个人主页展示)
|
||||
const [nickname, setNickname] = useState('');
|
||||
const [website, setWebsite] = useState('');
|
||||
@@ -122,38 +120,14 @@ export default function Profile() {
|
||||
navigate('/');
|
||||
};
|
||||
|
||||
// QQ 号保存(rainweb 层字段,后端返回 qq 字段时显示输入)
|
||||
const saveQq = async () => {
|
||||
setQqBusy(true);
|
||||
try {
|
||||
await profileApi.updateProfile({ qq: qq.trim() });
|
||||
showSnackbar('QQ 已更新');
|
||||
} catch (e) {
|
||||
showSnackbar(e.message);
|
||||
}
|
||||
setQqBusy(false);
|
||||
};
|
||||
|
||||
// 个性签名保存(公开主页展示)
|
||||
const saveBio = async () => {
|
||||
setBioBusy(true);
|
||||
try {
|
||||
await profileApi.updateProfile({ bio: bio.trim() });
|
||||
showSnackbar('个性签名已更新');
|
||||
} catch (e) {
|
||||
showSnackbar(e.message);
|
||||
}
|
||||
setBioBusy(false);
|
||||
};
|
||||
|
||||
// 对外昵称 + 个人博客保存(作者名/头衔之外的公开资料;后端白名单扩展后生效)
|
||||
const saveInfo = async () => {
|
||||
// 对外昵称 + 个人博客 + QQ 号 + 个性签名统一保存
|
||||
const saveAll = async () => {
|
||||
if (nickname.trim().length > 20) { showSnackbar('昵称最多 20 字'); return; }
|
||||
if (website.trim() && !/^https?:\/\//i.test(website.trim())) { showSnackbar('个人博客需以 http(s):// 开头'); return; }
|
||||
setInfoBusy(true);
|
||||
try {
|
||||
await profileApi.updateProfile({ nickname: nickname.trim(), website: website.trim() });
|
||||
showSnackbar('资料已更新');
|
||||
await profileApi.updateProfile({ nickname: nickname.trim(), website: website.trim(), qq: qq.trim(), bio: bio.trim() });
|
||||
showSnackbar('资料已保存');
|
||||
} catch (e) {
|
||||
showSnackbar(e.message);
|
||||
}
|
||||
@@ -239,46 +213,34 @@ export default function Profile() {
|
||||
</div>
|
||||
|
||||
{/* 对外昵称 + 个人博客:显示在帖子/评论/个人主页 */}
|
||||
<div className="form-group" style={{ display: 'flex', gap: 12, alignItems: 'flex-end', flexWrap: 'wrap' }}>
|
||||
<div style={{ flex: '1 1 220px', minWidth: 200 }}>
|
||||
<label htmlFor="profileNickname">对外昵称</label>
|
||||
<input
|
||||
id="profileNickname"
|
||||
type="text"
|
||||
value={nickname}
|
||||
onChange={(e) => setNickname(e.target.value)}
|
||||
placeholder="显示在帖子 / 评论 / 个人主页的作者名"
|
||||
maxLength={20}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 220px', minWidth: 200 }}>
|
||||
<label htmlFor="profileWebsite">个人博客</label>
|
||||
<input
|
||||
id="profileWebsite"
|
||||
type="url"
|
||||
value={website}
|
||||
onChange={(e) => setWebsite(e.target.value)}
|
||||
placeholder="https://example.com"
|
||||
/>
|
||||
</div>
|
||||
<button className="btn btn-tonal btn-sm" onClick={saveInfo} disabled={infoBusy}>
|
||||
{infoBusy ? '保存中…' : '保存资料'}
|
||||
</button>
|
||||
<div className="form-group">
|
||||
<label htmlFor="profileNickname">对外昵称</label>
|
||||
<input
|
||||
id="profileNickname"
|
||||
type="text"
|
||||
value={nickname}
|
||||
onChange={(e) => setNickname(e.target.value)}
|
||||
placeholder="显示在帖子 / 评论 / 个人主页的作者名"
|
||||
maxLength={20}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-muted" style={{ fontSize: 12, marginTop: 4 }}>
|
||||
昵称留空则显示用户名;博客会以「个人博客」链接展示在主页(外链跳确认页)
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="profileWebsite">个人博客</label>
|
||||
<input
|
||||
id="profileWebsite"
|
||||
type="url"
|
||||
value={website}
|
||||
onChange={(e) => setWebsite(e.target.value)}
|
||||
placeholder="https://example.com"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* QQ 号:rainweb 层字段(后端返回 qq 时显示;用于 QQ 头像渲染优先级) */}
|
||||
{typeof user.qq !== 'undefined' && (
|
||||
<div className="form-group" style={{ display: 'flex', gap: 8, alignItems: 'flex-end' }}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<label htmlFor="profileQq">QQ 号(用于 QQ 头像)</label>
|
||||
<input id="profileQq" type="text" value={qq} onChange={(e) => setQq(e.target.value)} placeholder="QQ 号码" />
|
||||
</div>
|
||||
<button className="btn btn-tonal btn-sm" onClick={saveQq} disabled={qqBusy}>
|
||||
{qqBusy ? '保存中…' : '保存'}
|
||||
</button>
|
||||
<div className="form-group">
|
||||
<label htmlFor="profileQq">QQ 号(用于 QQ 头像)</label>
|
||||
<input id="profileQq" type="text" value={qq} onChange={(e) => setQq(e.target.value)} placeholder="QQ 号码" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -298,8 +260,14 @@ export default function Profile() {
|
||||
<span>{bio.length}/200</span>
|
||||
</div>
|
||||
</div>
|
||||
<button className="btn btn-tonal btn-sm" onClick={saveBio} disabled={bioBusy}>
|
||||
{bioBusy ? '保存中…' : '保存签名'}
|
||||
|
||||
<p style={{ fontSize: 12, color: 'var(--md-ref-on-surface-variant)', margin: '4px 0 12px' }}>
|
||||
昵称留空则显示用户名;博客会以「个人博客」链接展示在主页(外链跳确认页)
|
||||
</p>
|
||||
|
||||
{/* 统一保存按钮 */}
|
||||
<button className="btn btn-tonal" onClick={saveAll} disabled={infoBusy}>
|
||||
{infoBusy ? '保存中…' : '保存全部'}
|
||||
</button>
|
||||
|
||||
{/* RainID 开启:改密/资料交 RainID,本地只保留头像与 QQ */}
|
||||
|
||||
Reference in New Issue
Block a user