diff --git a/web/src/components/PasswordResetConfirm.js b/web/src/components/PasswordResetConfirm.js
index 222c8add..d7a1143e 100644
--- a/web/src/components/PasswordResetConfirm.js
+++ b/web/src/components/PasswordResetConfirm.js
@@ -1,9 +1,15 @@
import React, { useEffect, useState } from 'react';
-import { Button, Form, Grid, Header, Image, Segment } from 'semantic-ui-react';
-import { API, copy, showError, showNotice } from '../helpers';
-import { useSearchParams } from 'react-router-dom';
+import { API, copy, showError, showNotice, getLogo, getSystemName } from '../helpers';
+import { useSearchParams, Link } from 'react-router-dom';
+import { Button, Card, Form, Typography } from '@douyinfe/semi-ui';
+import { IconMail, IconLock } from '@douyinfe/semi-icons';
+import { useTranslation } from 'react-i18next';
+import Background from '../images/example.png';
+
+const { Text, Title } = Typography;
const PasswordResetConfirm = () => {
+ const { t } = useTranslation();
const [inputs, setInputs] = useState({
email: '',
token: '',
@@ -11,13 +17,15 @@ const PasswordResetConfirm = () => {
const { email, token } = inputs;
const [loading, setLoading] = useState(false);
-
const [disableButton, setDisableButton] = useState(false);
const [countdown, setCountdown] = useState(30);
-
const [newPassword, setNewPassword] = useState('');
const [searchParams, setSearchParams] = useSearchParams();
+
+ const logo = getLogo();
+ const systemName = getSystemName();
+
useEffect(() => {
let token = searchParams.get('token');
let email = searchParams.get('email');
@@ -41,8 +49,8 @@ const PasswordResetConfirm = () => {
}, [disableButton, countdown]);
async function handleSubmit(e) {
+ if (!email || !token) return;
setDisableButton(true);
- if (!email) return;
setLoading(true);
const res = await API.post(`/api/user/reset`, {
email,
@@ -53,7 +61,7 @@ const PasswordResetConfirm = () => {
let password = res.data.data;
setNewPassword(password);
await copy(password);
- showNotice(`新密码已复制到剪贴板:${password}`);
+ showNotice(`${t('密码已重置并已复制到剪贴板')}: ${password}`);
} else {
showError(message);
}
@@ -61,52 +69,86 @@ const PasswordResetConfirm = () => {
}
return (
-
-
-
-
-
-
+
+ {/* 背景图片容器 - 放大并保持居中 */}
+
+
+ {/* 半透明遮罩层 */}
+
+
+
+
+
+
+

+
{systemName}
+
+
+
+
+
{t('密码重置确认')}
+
+
+
}
+ />
+
+ {newPassword && (
+
}
+ onClick={(e) => {
+ e.target.select();
+ navigator.clipboard.writeText(newPassword);
+ showNotice(`${t('密码已复制到剪贴板')}: ${newPassword}`);
+ }}
+ />
+ )}
+
+
+
+
+
+
+
+ {t('返回登录')}
+
+
+
+
+
+
+
);
};
diff --git a/web/src/components/PasswordResetForm.js b/web/src/components/PasswordResetForm.js
index 631d83be..222b4ebe 100644
--- a/web/src/components/PasswordResetForm.js
+++ b/web/src/components/PasswordResetForm.js
@@ -1,9 +1,16 @@
import React, { useEffect, useState } from 'react';
-import { Button, Form, Grid, Header, Image, Segment } from 'semantic-ui-react';
-import { API, showError, showInfo, showSuccess } from '../helpers';
+import { API, getLogo, showError, showInfo, showSuccess, getSystemName } from '../helpers';
import Turnstile from 'react-turnstile';
+import { Button, Card, Form, Typography } from '@douyinfe/semi-ui';
+import { IconMail } from '@douyinfe/semi-icons';
+import { Link } from 'react-router-dom';
+import { useTranslation } from 'react-i18next';
+import Background from '../images/example.png';
+
+const { Text, Title } = Typography;
const PasswordResetForm = () => {
+ const { t } = useTranslation();
const [inputs, setInputs] = useState({
email: '',
});
@@ -16,6 +23,20 @@ const PasswordResetForm = () => {
const [disableButton, setDisableButton] = useState(false);
const [countdown, setCountdown] = useState(30);
+ const logo = getLogo();
+ const systemName = getSystemName();
+
+ useEffect(() => {
+ let status = localStorage.getItem('status');
+ if (status) {
+ status = JSON.parse(status);
+ if (status.turnstile_check) {
+ setTurnstileEnabled(true);
+ setTurnstileSiteKey(status.turnstile_site_key);
+ }
+ }
+ }, []);
+
useEffect(() => {
let countdownInterval = null;
if (disableButton && countdown > 0) {
@@ -29,25 +50,24 @@ const PasswordResetForm = () => {
return () => clearInterval(countdownInterval);
}, [disableButton, countdown]);
- function handleChange(e) {
- const { name, value } = e.target;
- setInputs((inputs) => ({ ...inputs, [name]: value }));
+ function handleChange(value) {
+ setInputs((inputs) => ({ ...inputs, email: value }));
}
async function handleSubmit(e) {
- setDisableButton(true);
if (!email) return;
if (turnstileEnabled && turnstileToken === '') {
- showInfo('请稍后几秒重试,Turnstile 正在检查用户环境!');
+ showInfo(t('请稍后几秒重试,Turnstile 正在检查用户环境!'));
return;
}
+ setDisableButton(true);
setLoading(true);
const res = await API.get(
`/api/reset_password?email=${email}&turnstile=${turnstileToken}`,
);
const { success, message } = res.data;
if (success) {
- showSuccess('重置邮件发送成功,请检查邮箱!');
+ showSuccess(t('重置邮件发送成功,请检查邮箱!'));
setInputs({ ...inputs, email: '' });
} else {
showError(message);
@@ -56,46 +76,80 @@ const PasswordResetForm = () => {
}
return (
-
-
-
-