fix: show login failure feedback
This commit is contained in:
+17
-4
@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';
|
|||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { adminApi, clientApi, type CaptchaResponse } from '@/api/adminApi';
|
import { adminApi, clientApi, type CaptchaResponse } from '@/api/adminApi';
|
||||||
import { writeSession, type Portal } from '@/api/session';
|
import { writeSession, type Portal } from '@/api/session';
|
||||||
import { Button, Input } from '@/components/ui';
|
import { Button, Input, Modal } from '@/components/ui';
|
||||||
|
|
||||||
type LoginPageProps = {
|
type LoginPageProps = {
|
||||||
portal: Portal;
|
portal: Portal;
|
||||||
@@ -28,11 +28,14 @@ export function LoginPage({ portal }: LoginPageProps) {
|
|||||||
const [captchaText, setCaptchaText] = useState('');
|
const [captchaText, setCaptchaText] = useState('');
|
||||||
const [captcha, setCaptcha] = useState<CaptchaResponse | null>(null);
|
const [captcha, setCaptcha] = useState<CaptchaResponse | null>(null);
|
||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
|
const [alertMessage, setAlertMessage] = useState('');
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const isAdmin = portal === 'admin';
|
const isAdmin = portal === 'admin';
|
||||||
|
|
||||||
async function refreshCaptcha() {
|
async function refreshCaptcha(options: { clearError?: boolean } = {}) {
|
||||||
|
if (options.clearError ?? true) {
|
||||||
setError('');
|
setError('');
|
||||||
|
}
|
||||||
setCaptchaText('');
|
setCaptchaText('');
|
||||||
setCaptcha(await (isAdmin ? adminApi.getCaptcha() : clientApi.getCaptcha()));
|
setCaptcha(await (isAdmin ? adminApi.getCaptcha() : clientApi.getCaptcha()));
|
||||||
}
|
}
|
||||||
@@ -55,8 +58,10 @@ export function LoginPage({ portal }: LoginPageProps) {
|
|||||||
writeSession(session);
|
writeSession(session);
|
||||||
navigate(isAdmin ? '/admin' : '/client', { replace: true });
|
navigate(isAdmin ? '/admin' : '/client', { replace: true });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(loginErrorMessage(err));
|
const message = loginErrorMessage(err);
|
||||||
await refreshCaptcha();
|
setError(message);
|
||||||
|
setAlertMessage(message);
|
||||||
|
await refreshCaptcha({ clearError: false });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -85,6 +90,14 @@ export function LoginPage({ portal }: LoginPageProps) {
|
|||||||
<Button disabled={loading} onClick={submit}>{loading ? '登录中...' : '登录'}</Button>
|
<Button disabled={loading} onClick={submit}>{loading ? '登录中...' : '登录'}</Button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<Modal
|
||||||
|
footer={<Button onClick={() => setAlertMessage('')}>知道了</Button>}
|
||||||
|
onClose={() => setAlertMessage('')}
|
||||||
|
open={Boolean(alertMessage)}
|
||||||
|
title="登录失败"
|
||||||
|
>
|
||||||
|
<p className="login-alert-message">{alertMessage}</p>
|
||||||
|
</Modal>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4142,6 +4142,12 @@ h3 {
|
|||||||
background: rgba(239, 68, 68, 0.1);
|
background: rgba(239, 68, 68, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-alert-message {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--color-text-strong);
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
.system-page {
|
.system-page {
|
||||||
gap: 28px;
|
gap: 28px;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user