Merge remote-tracking branch 'origin/dev/2025b' into dev/2025b
commit
6e8bc882c8
Binary file not shown.
Before Width: | Height: | Size: 34 KiB |
@ -1,112 +1,116 @@
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useEffect } from 'react'
|
||||
import { Button, Form, Input, Row, Radio, App, Typography } from 'antd'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import useAuthStore from '@/stores/Auth'
|
||||
import { appendRequestParams } from '@/utils/request'
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useEffect } from "react";
|
||||
import { Button, Form, Input, Row, Radio, App, Typography } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import useAuthStore from "@/stores/Auth";
|
||||
import { appendRequestParams } from "@/utils/request";
|
||||
|
||||
function Login() {
|
||||
const [authenticate, loginStatus, defaultRoute] =
|
||||
useAuthStore((state) => [state.authenticate, state.loginStatus, state.defaultRoute])
|
||||
const [authenticate, loginStatus, defaultRoute] = useAuthStore((state) => [
|
||||
state.authenticate,
|
||||
state.loginStatus,
|
||||
state.defaultRoute,
|
||||
]);
|
||||
|
||||
const { t, i18n } = useTranslation()
|
||||
const { notification } = App.useApp()
|
||||
const navigate = useNavigate()
|
||||
const [form] = Form.useForm()
|
||||
const { t, i18n } = useTranslation();
|
||||
const { notification } = App.useApp();
|
||||
const navigate = useNavigate();
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const handleLngChange = (lng) => {
|
||||
appendRequestParams('lgc', lng === 'zh' ? 2 : 1)
|
||||
i18n.changeLanguage(lng)
|
||||
}
|
||||
appendRequestParams("lgc", lng === "zh" ? 2 : 1);
|
||||
i18n.changeLanguage(lng);
|
||||
};
|
||||
|
||||
const defaultLng = i18n.language??'zh'
|
||||
appendRequestParams('lgc', defaultLng === 'zh' ? 2 : 1)
|
||||
const defaultLng = i18n.language ?? "zh";
|
||||
appendRequestParams("lgc", defaultLng === "zh" ? 2 : 1);
|
||||
|
||||
useEffect (() => {
|
||||
useEffect(() => {
|
||||
if (loginStatus === 302) {
|
||||
navigate(defaultRoute)
|
||||
navigate(defaultRoute);
|
||||
}
|
||||
}, [loginStatus])
|
||||
}, [loginStatus]);
|
||||
|
||||
const onFinish = (values) => {
|
||||
authenticate(values.username, values.password)
|
||||
.catch(ex => {
|
||||
console.error(ex)
|
||||
notification.error({
|
||||
message: t('Validation.Title'),
|
||||
description: t('Validation.LoginFailed'),
|
||||
placement: 'top',
|
||||
duration: 4,
|
||||
})
|
||||
})
|
||||
}
|
||||
authenticate(values.username, values.password).catch((ex) => {
|
||||
console.error(ex);
|
||||
notification.error({
|
||||
message: t("Validation.Title"),
|
||||
description: t("Validation.LoginFailed"),
|
||||
placement: "top",
|
||||
duration: 4,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const onFinishFailed = (errorInfo) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
}
|
||||
console.log("Failed:", errorInfo);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Typography.Title className="text-center" level={3}>Global Highlights Hub</Typography.Title>
|
||||
<Row justify='center' align='middle' className='min-h-96'>
|
||||
<Form
|
||||
name='login'
|
||||
layout='vertical'
|
||||
form={form}
|
||||
size='large'
|
||||
labelCol={{
|
||||
span: 8,
|
||||
}}
|
||||
wrapperCol={{
|
||||
span: 24,
|
||||
}}
|
||||
className='max-w-xl'
|
||||
initialValues={{
|
||||
language: defaultLng,
|
||||
}}
|
||||
onFinish={onFinish}
|
||||
onFinishFailed={onFinishFailed}
|
||||
autoComplete='off'
|
||||
>
|
||||
<Form.Item
|
||||
label={t('Username')}
|
||||
name='username'
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('Validation.UsernameIsEmpty'),
|
||||
},
|
||||
]}
|
||||
<Typography.Title className="text-center" level={3}>
|
||||
Highlights Hub
|
||||
</Typography.Title>
|
||||
<Row justify="center" align="middle" className="min-h-96">
|
||||
<Form
|
||||
name="login"
|
||||
layout="vertical"
|
||||
form={form}
|
||||
size="large"
|
||||
labelCol={{
|
||||
span: 8,
|
||||
}}
|
||||
wrapperCol={{
|
||||
span: 24,
|
||||
}}
|
||||
className="max-w-xl"
|
||||
initialValues={{
|
||||
language: defaultLng,
|
||||
}}
|
||||
onFinish={onFinish}
|
||||
onFinishFailed={onFinishFailed}
|
||||
autoComplete="off"
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t('Password')}
|
||||
name='password'
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('Validation.PasswordIsEmpty'),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input.Password />
|
||||
</Form.Item>
|
||||
<Form.Item name='language'>
|
||||
<Radio.Group onChange={e => handleLngChange(e.target.value)}>
|
||||
<Radio value='zh'>中文</Radio>
|
||||
<Radio value='en'>English</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button type='primary' htmlType='submit' className='w-full'>
|
||||
{t('Login')}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Row>
|
||||
<Form.Item
|
||||
label={t("Username")}
|
||||
name="username"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t("Validation.UsernameIsEmpty"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("Password")}
|
||||
name="password"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t("Validation.PasswordIsEmpty"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input.Password />
|
||||
</Form.Item>
|
||||
<Form.Item name="language">
|
||||
<Radio.Group onChange={(e) => handleLngChange(e.target.value)}>
|
||||
<Radio value="zh">中文</Radio>
|
||||
<Radio value="en">English</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button type="primary" htmlType="submit" className="w-full">
|
||||
{t("Login")}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Row>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default Login
|
||||
export default Login;
|
||||
|
Loading…
Reference in New Issue