feat(web): 优化设置页面交互与语言同步

- 二级页面返回按钮导航到设置页而非路由栈上一页
- 通用设置开关等待后端响应后再更新 UI,失败时显示 toast
- 删除用户名/邮箱的硬编码默认值,使用 auth token 邮箱作为 fallback
- AppShell 侧边栏显示真实头像和用户名
- 页面加载时检查 URL 语言与用户偏好是否一致,不一致则重定向
This commit is contained in:
ZL-Q
2026-05-09 21:32:51 +08:00
parent 1d5efb46e7
commit a1b4418d55
5 changed files with 60 additions and 25 deletions
+7 -6
View File
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react';
import { logout } from '../lib/auth';
import { logout, getAuth } from '../lib/auth';
import { getUserProfile, getPointsBalance, type UserProfile, type PointsBalance } from '../lib/api';
interface Props {
@@ -37,8 +37,9 @@ export default function SettingsPage({ locale, settings: s }: Props) {
}
};
const displayName = profile?.display_name || profile?.email?.split('@')[0] || 'User';
const email = profile?.email || 'user@example.com';
const authEmail = getAuth()?.user?.email;
const displayName = loading ? '' : (profile?.display_name || profile?.email?.split('@')[0] || authEmail?.split('@')[0] || '');
const email = loading ? '' : (profile?.email || authEmail || '');
const bio = profile?.bio || '';
return (
@@ -71,13 +72,13 @@ export default function SettingsPage({ locale, settings: s }: Props) {
<img src={profile.avatar_url} alt={displayName} className="w-14 h-14 rounded-[28px] object-cover" />
) : (
<div className="w-14 h-14 rounded-[28px] bg-violet-50 flex items-center justify-center">
<span className="text-violet-600 text-xl font-bold">{displayName[0].toUpperCase()}</span>
<span className="text-violet-600 text-xl font-bold">{displayName ? displayName[0].toUpperCase() : '?'}</span>
</div>
)}
{/* Name & Email */}
<div className="flex-1 min-w-0">
<p className="text-slate-900 text-lg font-bold truncate">{displayName}</p>
<p className="text-slate-500 text-xs truncate">{email}</p>
<p className="text-slate-900 text-lg font-bold truncate">{loading ? '...' : (displayName || '-')}</p>
<p className="text-slate-500 text-xs truncate">{loading ? '...' : (email || '-')}</p>
</div>
{/* Edit Profile Button */}
<a