diff --git a/web/usercenter/components/Settings.tsx b/web/usercenter/components/Settings.tsx
index a85934a..133faa9 100644
--- a/web/usercenter/components/Settings.tsx
+++ b/web/usercenter/components/Settings.tsx
@@ -5,7 +5,6 @@ import React, { useEffect, useState } from 'react';
import { Icon } from './icons';
import { card, input } from './shared';
import { ErrorLine } from './Login';
-import { useUI } from '../lib/theme';
import type { TFn, Lang } from '../lib/i18n';
import { getClient } from '../lib/api/client';
import { bilingual } from '../lib/api/errors';
@@ -15,7 +14,6 @@ export default function Settings({ t, lang, totpEnabled, onTotpChange }: { t: TF
return (
@@ -24,57 +22,6 @@ export default function Settings({ t, lang, totpEnabled, onTotpChange }: { t: TF
const sectionTitle: React.CSSProperties = { fontSize: 14.5, fontWeight: 700, color: 'var(--fg1)' };
-function Preferences({ t }: { t: TFn }) {
- const { lang, setLang, theme, setTheme } = useUI();
- return (
-
-
{t('prefTitle')}
-
- setLang(v as Lang)}
- />
-
-
- setTheme(v as 'light' | 'dark')}
- />
-
-
- );
-}
-
-function Row({ label, children }: { label: string; children: React.ReactNode }) {
- return (
-
- {label}
- {children}
-
- );
-}
-
-function Seg({ value, options, onPick, icons }: { value: string; options: [string, string][]; onPick: (v: string) => void; icons?: Record }) {
- return (
-
- {options.map(([v, l]) => (
-
- ))}
-
- );
-}
-
/* ───────── TOTP 2FA ───────── */
function TotpSection({ t, lang, enabled, onChange }: { t: TFn; lang: Lang; enabled: boolean; onChange: () => void }) {
const api = getClient();
diff --git a/web/usercenter/components/UserCenter.tsx b/web/usercenter/components/UserCenter.tsx
index de788c9..08714ed 100644
--- a/web/usercenter/components/UserCenter.tsx
+++ b/web/usercenter/components/UserCenter.tsx
@@ -120,8 +120,16 @@ export default function UserCenter() {
setView('overview');
}
- // 静态导出无服务端会话:首屏(!ready)与未登录一律直接渲染登录页,避免出现空白
- // 背景(慢网络下用户会看到"空的")。已登录用户(有 refresh)会话续期完成后再切面板。
+ // 已登录(本地有 refresh token)但会话续期尚未完成:显示加载态而非登录页,
+ // 避免"先闪登录页再跳面板"(从官网带登录态进来时的 bug)。续期成功→面板、失败→登录页。
+ if (!ready && hasRefresh()) {
+ return (
+
+ {t('loading')}
+
+ );
+ }
+ // 无 refresh token(未登录)或续期失败:渲染登录页。
if (!ready || !authed) {
return ;
}