chore: update default theme style

This commit is contained in:
JustSong
2025-02-02 16:02:38 +08:00
parent 9b83d63896
commit c64b7c891f
7 changed files with 224 additions and 75 deletions

View File

@@ -12,12 +12,14 @@ import {
Card,
} from 'semantic-ui-react';
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { UserContext } from '../context/User';
import { API, getLogo, showError, showSuccess, showWarning } from '../helpers';
import { onGitHubOAuthClicked, onLarkOAuthClicked } from './utils';
import larkIcon from '../images/lark.svg';
const LoginForm = () => {
const { t } = useTranslation();
const [inputs, setInputs] = useState({
username: '',
password: '',
@@ -33,7 +35,7 @@ const LoginForm = () => {
useEffect(() => {
if (searchParams.get('expired')) {
showError('未登录或登录已过期,请重新登录!');
showError(t('messages.error.login_expired'));
}
let status = localStorage.getItem('status');
if (status) {
@@ -57,7 +59,7 @@ const LoginForm = () => {
userDispatch({ type: 'login', payload: data });
localStorage.setItem('user', JSON.stringify(data));
navigate('/');
showSuccess('登录成功!');
showSuccess(t('messages.success.login'));
setShowWeChatLoginModal(false);
} else {
showError(message);
@@ -82,11 +84,11 @@ const LoginForm = () => {
localStorage.setItem('user', JSON.stringify(data));
if (username === 'root' && password === '123456') {
navigate('/user/edit');
showSuccess('登录成功!');
showWarning('请立刻修改默认密码!');
showSuccess(t('messages.success.login'));
showWarning(t('messages.error.root_password'));
} else {
navigate('/token');
showSuccess('登录成功!');
showSuccess(t('messages.success.login'));
}
} else {
showError(message);
@@ -110,7 +112,7 @@ const LoginForm = () => {
style={{ marginBottom: '1.5em' }}
>
<Image src={logo} style={{ marginBottom: '10px' }} />
<Header.Content>用户登录</Header.Content>
<Header.Content>{t('auth.login.title')}</Header.Content>
</Header>
</Card.Header>
<Form size='large'>
@@ -118,7 +120,7 @@ const LoginForm = () => {
fluid
icon='user'
iconPosition='left'
placeholder='用户名 / 邮箱地址'
placeholder={t('auth.login.username')}
name='username'
value={username}
onChange={handleChange}
@@ -128,7 +130,7 @@ const LoginForm = () => {
fluid
icon='lock'
iconPosition='left'
placeholder='密码'
placeholder={t('auth.login.password')}
name='password'
type='password'
value={password}
@@ -145,7 +147,7 @@ const LoginForm = () => {
}}
onClick={handleSubmit}
>
登录
{t('auth.login.button')}
</Button>
</Form>
@@ -160,15 +162,15 @@ const LoginForm = () => {
}}
>
<div>
忘记密码
{t('auth.login.forgot_password')}
<Link to='/reset' style={{ color: '#2185d0' }}>
点击重置
{t('auth.login.reset_password')}
</Link>
</div>
<div>
没有账户
{t('auth.login.no_account')}
<Link to='/register' style={{ color: '#2185d0' }}>
点击注册
{t('auth.login.register')}
</Link>
</div>
</div>
@@ -182,7 +184,7 @@ const LoginForm = () => {
horizontal
style={{ color: '#666', fontSize: '0.9em' }}
>
使用其他方式登录
{t('auth.login.other_methods')}
</Divider>
<div
style={{
@@ -250,14 +252,12 @@ const LoginForm = () => {
<Modal.Description>
<Image src={status.wechat_qrcode} fluid />
<div style={{ textAlign: 'center' }}>
<p>
微信扫码关注公众号输入验证码获取验证码三分钟内有效
</p>
<p>{t('auth.login.wechat.scan_tip')}</p>
</div>
<Form size='large'>
<Form.Input
fluid
placeholder='验证码'
placeholder={t('auth.login.wechat.code_placeholder')}
name='wechat_verification_code'
value={inputs.wechat_verification_code}
onChange={handleChange}
@@ -266,13 +266,13 @@ const LoginForm = () => {
fluid
size='large'
style={{
background: '#2F73FF', // 使用更现代的蓝色
background: '#2F73FF',
color: 'white',
marginBottom: '1.5em',
}}
onClick={onSubmitWeChatVerificationCode}
>
登录
{t('auth.login.button')}
</Button>
</Form>
</Modal.Description>

View File

@@ -8,29 +8,23 @@ import {
Card,
Message,
} from 'semantic-ui-react';
import {
API,
copy,
showError,
showInfo,
showNotice,
showSuccess,
} from '../helpers';
import { useTranslation } from 'react-i18next';
import { API, copy, getLogo, showError, showNotice } from '../helpers';
import { useSearchParams } from 'react-router-dom';
const PasswordResetConfirm = () => {
const { t } = useTranslation();
const [inputs, setInputs] = useState({
email: '',
token: '',
});
const { email, token } = inputs;
const [loading, setLoading] = useState(false);
const [disableButton, setDisableButton] = useState(false);
const [countdown, setCountdown] = useState(30);
const [newPassword, setNewPassword] = useState('');
const logo = getLogo();
const [countdown, setCountdown] = useState(30);
const [searchParams, setSearchParams] = useSearchParams();
useEffect(() => {
@@ -68,7 +62,7 @@ const PasswordResetConfirm = () => {
let password = res.data.data;
setNewPassword(password);
await copy(password);
showNotice(`新密码已复制到剪贴板:${password}`);
showNotice(t('messages.notice.password_copied', { password }));
} else {
showError(message);
}
@@ -90,8 +84,8 @@ const PasswordResetConfirm = () => {
textAlign='center'
style={{ marginBottom: '1.5em' }}
>
<Image src='/logo.png' style={{ marginBottom: '10px' }} />
<Header.Content>密码重置确认</Header.Content>
<Image src={logo} style={{ marginBottom: '10px' }} />
<Header.Content>{t('auth.reset.confirm.title')}</Header.Content>
</Header>
</Card.Header>
<Form size='large'>
@@ -99,7 +93,7 @@ const PasswordResetConfirm = () => {
fluid
icon='mail'
iconPosition='left'
placeholder='邮箱地址'
placeholder={t('auth.reset.email')}
name='email'
value={email}
readOnly
@@ -110,7 +104,7 @@ const PasswordResetConfirm = () => {
fluid
icon='lock'
iconPosition='left'
placeholder='新密码'
placeholder={t('auth.reset.confirm.new_password')}
name='newPassword'
value={newPassword}
readOnly
@@ -122,30 +116,29 @@ const PasswordResetConfirm = () => {
onClick={(e) => {
e.target.select();
navigator.clipboard.writeText(newPassword);
showNotice(`密码已复制到剪贴板:${newPassword}`);
showNotice(t('auth.reset.confirm.notice'));
}}
/>
)}
<Button
color='blue'
fluid
size='large'
onClick={handleSubmit}
loading={loading}
disabled={disableButton}
style={{
background: '#2F73FF', // 使用更现代的蓝色
background: '#2F73FF',
color: 'white',
marginBottom: '1.5em',
}}
>
{disableButton ? '密码重置完成' : '提交'}
{disableButton ? t('auth.reset.confirm.button_disabled') : t('auth.reset.confirm.button')}
</Button>
</Form>
{newPassword && (
<Message style={{ background: 'transparent', boxShadow: 'none' }}>
<p style={{ fontSize: '0.9em', color: '#666' }}>
新密码已生成请点击密码框或上方按钮复制请及时登录并修改密码
{t('auth.reset.confirm.notice')}
</p>
</Message>
)}

View File

@@ -8,21 +8,23 @@ import {
Card,
Message,
} from 'semantic-ui-react';
import { API, showError, showInfo, showSuccess } from '../helpers';
import { useTranslation } from 'react-i18next';
import { API, getLogo, showError, showInfo, showSuccess } from '../helpers';
import Turnstile from 'react-turnstile';
const PasswordResetForm = () => {
const { t } = useTranslation();
const [inputs, setInputs] = useState({
email: '',
});
const { email } = inputs;
const [loading, setLoading] = useState(false);
const [turnstileEnabled, setTurnstileEnabled] = useState(false);
const [turnstileSiteKey, setTurnstileSiteKey] = useState('');
const [turnstileToken, setTurnstileToken] = useState('');
const [disableButton, setDisableButton] = useState(false);
const [countdown, setCountdown] = useState(30);
const logo = getLogo();
useEffect(() => {
let status = localStorage.getItem('status');
@@ -66,10 +68,12 @@ const PasswordResetForm = () => {
);
const { success, message } = res.data;
if (success) {
showSuccess('重置邮件发送成功,请检查邮箱!');
showSuccess(t('auth.reset.notice'));
setInputs({ ...inputs, email: '' });
} else {
showError(message);
setDisableButton(false);
setCountdown(30);
}
setLoading(false);
}
@@ -89,8 +93,8 @@ const PasswordResetForm = () => {
textAlign='center'
style={{ marginBottom: '1.5em' }}
>
<Image src='/logo.png' style={{ marginBottom: '10px' }} />
<Header.Content>密码重置</Header.Content>
<Image src={logo} style={{ marginBottom: '10px' }} />
<Header.Content>{t('auth.reset.title')}</Header.Content>
</Header>
</Card.Header>
<Form size='large'>
@@ -98,7 +102,7 @@ const PasswordResetForm = () => {
fluid
icon='mail'
iconPosition='left'
placeholder='邮箱地址'
placeholder={t('auth.reset.email')}
name='email'
value={email}
onChange={handleChange}
@@ -133,12 +137,12 @@ const PasswordResetForm = () => {
marginBottom: '1.5em',
}}
>
{disableButton ? `重试 (${countdown})` : '提交'}
{disableButton ? t('auth.register.get_code_retry', { countdown }) : t('auth.reset.button')}
</Button>
</Form>
<Message style={{ background: 'transparent', boxShadow: 'none' }}>
<p style={{ fontSize: '0.9em', color: '#666' }}>
系统将向您的邮箱发送一封包含重置链接的邮件请注意查收
{t('auth.reset.notice')}
</p>
</Message>
</Card.Content>

View File

@@ -6,15 +6,16 @@ import {
Header,
Image,
Message,
Segment,
Card,
Divider,
} from 'semantic-ui-react';
import { Link, useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { API, getLogo, showError, showInfo, showSuccess } from '../helpers';
import Turnstile from 'react-turnstile';
const RegisterForm = () => {
const { t } = useTranslation();
const [inputs, setInputs] = useState({
username: '',
password: '',
@@ -28,6 +29,8 @@ const RegisterForm = () => {
const [turnstileSiteKey, setTurnstileSiteKey] = useState('');
const [turnstileToken, setTurnstileToken] = useState('');
const [loading, setLoading] = useState(false);
const [disableButton, setDisableButton] = useState(false);
const [countdown, setCountdown] = useState(30);
const logo = getLogo();
let affCode = new URLSearchParams(window.location.search).get('aff');
if (affCode) {
@@ -46,6 +49,19 @@ const RegisterForm = () => {
}
});
useEffect(() => {
let countdownInterval = null;
if (disableButton && countdown > 0) {
countdownInterval = setInterval(() => {
setCountdown(countdown - 1);
}, 1000);
} else if (countdown === 0) {
setDisableButton(false);
setCountdown(30);
}
return () => clearInterval(countdownInterval);
}, [disableButton, countdown]);
let navigate = useNavigate();
function handleChange(e) {
@@ -56,16 +72,16 @@ const RegisterForm = () => {
async function handleSubmit(e) {
if (password.length < 8) {
showInfo('密码长度不得小于 8 位!');
showInfo(t('messages.error.password_length'));
return;
}
if (password !== password2) {
showInfo('两次输入的密码不一致');
showInfo(t('messages.error.password_mismatch'));
return;
}
if (username && password) {
if (turnstileEnabled && turnstileToken === '') {
showInfo('请稍后几秒重试Turnstile 正在检查用户环境!');
showInfo(t('messages.error.turnstile_wait'));
return;
}
setLoading(true);
@@ -80,7 +96,7 @@ const RegisterForm = () => {
const { success, message } = res.data;
if (success) {
navigate('/login');
showSuccess('注册成功!');
showSuccess(t('messages.success.register'));
} else {
showError(message);
}
@@ -91,18 +107,21 @@ const RegisterForm = () => {
const sendVerificationCode = async () => {
if (inputs.email === '') return;
if (turnstileEnabled && turnstileToken === '') {
showInfo('请稍后几秒重试Turnstile 正在检查用户环境!');
showInfo(t('messages.error.turnstile_wait'));
return;
}
setDisableButton(true);
setLoading(true);
const res = await API.get(
`/api/verification?email=${inputs.email}&turnstile=${turnstileToken}`
);
const { success, message } = res.data;
if (success) {
showSuccess('验证码发送成功,请检查你的邮箱!');
showSuccess(t('messages.success.verification_code'));
} else {
showError(message);
setDisableButton(false);
setCountdown(30);
}
setLoading(false);
};
@@ -123,7 +142,7 @@ const RegisterForm = () => {
style={{ marginBottom: '1.5em' }}
>
<Image src={logo} style={{ marginBottom: '10px' }} />
<Header.Content>新用户注册</Header.Content>
<Header.Content>{t('auth.register.title')}</Header.Content>
</Header>
</Card.Header>
<Form size='large'>
@@ -131,7 +150,7 @@ const RegisterForm = () => {
fluid
icon='user'
iconPosition='left'
placeholder='输入用户名,最长 12 位'
placeholder={t('auth.register.username')}
onChange={handleChange}
name='username'
style={{ marginBottom: '1em' }}
@@ -140,7 +159,7 @@ const RegisterForm = () => {
fluid
icon='lock'
iconPosition='left'
placeholder='输入密码,最短 8 位,最长 20 位'
placeholder={t('auth.register.password')}
onChange={handleChange}
name='password'
type='password'
@@ -150,7 +169,7 @@ const RegisterForm = () => {
fluid
icon='lock'
iconPosition='left'
placeholder='再次输入密码'
placeholder={t('auth.register.confirm_password')}
onChange={handleChange}
name='password2'
type='password'
@@ -163,7 +182,7 @@ const RegisterForm = () => {
fluid
icon='mail'
iconPosition='left'
placeholder='输入邮箱地址'
placeholder={t('auth.register.email')}
onChange={handleChange}
name='email'
type='email'
@@ -171,9 +190,10 @@ const RegisterForm = () => {
<Button
onClick={sendVerificationCode}
disabled={loading}
// style={{ backgroundColor: '#2F73FF', color: 'white' }}
>
获取验证码
{disableButton
? t('auth.register.get_code_retry', { countdown })
: t('auth.register.get_code')}
</Button>
}
style={{ marginBottom: '1em' }}
@@ -182,7 +202,7 @@ const RegisterForm = () => {
fluid
icon='lock'
iconPosition='left'
placeholder='输入验证码'
placeholder={t('auth.register.verification_code')}
onChange={handleChange}
name='verification_code'
style={{ marginBottom: '1em' }}
@@ -218,7 +238,7 @@ const RegisterForm = () => {
}}
loading={loading}
>
注册
{t('auth.register.button')}
</Button>
</Form>
@@ -231,9 +251,9 @@ const RegisterForm = () => {
color: '#666',
}}
>
已有账户
{t('auth.register.has_account')}
<Link to='/login' style={{ color: '#2185d0' }}>
点击登录
{t('auth.register.login')}
</Link>
</div>
</Message>