feat(frontend): 控制台 next-intl 中英双语

接入无 URL 前缀的 zh-CN/en,顶栏与外观设置可切换语言;选择写入 cookie 后刷新生效。
This commit is contained in:
ryan
2026-08-16 16:49:16 +08:00
parent 64fbaa7ef1
commit 5a8722ff07
219 changed files with 21437 additions and 5212 deletions
+14 -12
View File
@@ -12,6 +12,7 @@ import { Check } from 'lucide-react';
import { AuthService } from '@/lib/services/auth';
import { useAuth } from '@/components/providers/auth-provider';
import { safeRedirectTarget } from '@/lib/utils';
import { useTranslations } from 'next-intl';
/**
* 登录页面组件
@@ -27,6 +28,7 @@ export function LoginPage() {
const router = useRouter();
const searchParams = useSearchParams();
const { user, loading, setUser } = useAuth();
const t = useTranslations('auth.login');
const [showOTP, setShowOTP] = useState(false);
/* 处理OAuth回调 */
@@ -87,9 +89,7 @@ export function LoginPage() {
try {
const result = await AuthService.handleCallback({ state, code });
if (result.status === 'need_bind') {
toast.info(
'您的第三方账号未绑定本地账号,系统已关闭注册。请登录已有本地账号进行绑定。',
);
toast.info(t('needBind'));
setIsProcessingCallback(false);
router.replace('/login');
return;
@@ -98,7 +98,9 @@ export function LoginPage() {
setUser(result.user);
}
setLoginSuccess(true);
toast.success(result.status === 'bound' ? '绑定成功' : '登录成功');
toast.success(
result.status === 'bound' ? t('bindSuccess') : t('success'),
);
setTimeout(() => {
if (!redirectedRef.current) {
@@ -109,7 +111,7 @@ export function LoginPage() {
} catch (error) {
console.error('OAuth callback error:', error);
toast.error(
error instanceof Error ? error.message : '登录失败,请重试',
error instanceof Error ? error.message : t('failed'),
);
setIsProcessingCallback(false);
router.replace('/login');
@@ -117,7 +119,7 @@ export function LoginPage() {
}
};
handleOAuthCallback();
}, [router, searchParams, setUser]);
}, [router, searchParams, setUser, t]);
return (
<AuthShell wide={showOTP}>
@@ -138,10 +140,10 @@ export function LoginPage() {
</div>
<div className='flex flex-col gap-2 text-center'>
<h3 className='font-semibold tracking-tight text-foreground'>
正在检查登录状态
{t('checkingSession')}
</h3>
<p className='text-xs text-muted-foreground'>
请稍候,我们正在确认当前会话...
{t('checkingSessionDesc')}
</p>
</div>
</div>
@@ -157,10 +159,10 @@ export function LoginPage() {
</motion.div>
<div className='flex flex-col gap-2 text-center'>
<h3 className='font-semibold tracking-tight text-foreground'>
登录成功
{t('success')}
</h3>
<p className='text-xs text-muted-foreground'>
正在跳转至控制台...
{t('redirecting')}
</p>
</div>
</div>
@@ -171,10 +173,10 @@ export function LoginPage() {
</div>
<div className='flex flex-col gap-2 text-center'>
<h3 className='font-semibold tracking-tight text-foreground'>
正在验证凭据
{t('verifyingCredentials')}
</h3>
<p className='text-xs text-muted-foreground'>
请稍候,我们正在为您建立安全会话...
{t('establishingSession')}
</p>
</div>
</div>