forked from ddrilling/asb_cloud_front
Страницы входа и регистрации упрощены
This commit is contained in:
parent
f389097439
commit
91a9bf9c9f
@ -1,22 +1,18 @@
|
|||||||
import { Card, Form, Input, Button, notification } from 'antd';
|
import { Card, Form, Input, Button } from 'antd'
|
||||||
import { UserOutlined, LockOutlined } from '@ant-design/icons'
|
import { UserOutlined, LockOutlined } from '@ant-design/icons'
|
||||||
import logo from '../images/logo_32.png'
|
|
||||||
import Loader from '../components/Loader'
|
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import {Link, useHistory} from "react-router-dom";
|
import { Link, useHistory } from 'react-router-dom'
|
||||||
import { AuthService, OpenAPI } from '../services/api/'
|
import { AuthService, OpenAPI } from '../services/api/'
|
||||||
|
import LoaderPortal from '../components/LoaderPortal'
|
||||||
|
import { invokeWebApiWrapperAsync } from '../components/factory'
|
||||||
|
import { loginRules, passwordRules } from '../utils/validationRules'
|
||||||
|
|
||||||
import '../styles/index.css'
|
import '../styles/index.css'
|
||||||
|
import logo from '../images/logo_32.png'
|
||||||
|
|
||||||
const { login } = AuthService
|
const logoIcon = <img src={logo} alt={'АСБ'} className={'logo'} width={130}/>
|
||||||
|
|
||||||
const openNotificationError = (message, title) => {
|
const setUser = (user) => {
|
||||||
notification['error']({
|
|
||||||
message: title||'Ошибка',
|
|
||||||
description: message,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const setUser = (user) =>{
|
|
||||||
OpenAPI.TOKEN = user.token
|
OpenAPI.TOKEN = user.token
|
||||||
localStorage['userId'] = user.id
|
localStorage['userId'] = user.id
|
||||||
localStorage['token'] = user.token
|
localStorage['token'] = user.token
|
||||||
@ -24,100 +20,40 @@ const setUser = (user) =>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
const [loader, setLoader] = useState(false);
|
const history = useHistory()
|
||||||
const [isErrorVisible, setErrorVisible] = useState(false);
|
const [showLoader, setShowLoader] = useState(false)
|
||||||
const history = useHistory();
|
|
||||||
const [form] = Form.useForm();
|
|
||||||
|
|
||||||
const logoIcon = <img src={logo} alt="АСБ" className="logo"/>
|
const handleLogin = (formData) => invokeWebApiWrapperAsync(
|
||||||
|
async () => {
|
||||||
let handleLogin = async (formData) =>{
|
const user = await AuthService.login(formData)
|
||||||
setLoader(true)
|
if (!user) throw Error('Неправильный логин или пароль')
|
||||||
try{
|
|
||||||
let user = await login(formData)
|
|
||||||
setUser(user)
|
setUser(user)
|
||||||
setLoader(false)
|
|
||||||
history.push('well')
|
history.push('well')
|
||||||
}catch(e){
|
},
|
||||||
if(e.status === 400)
|
setShowLoader,
|
||||||
openNotificationError(e.body)
|
(ex) => ex?.message ?? 'Ошибка входа'
|
||||||
console.error(`Error ${e}`)
|
)
|
||||||
|
|
||||||
setErrorVisible(true)
|
|
||||||
form.validateFields()
|
|
||||||
setLoader(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const showError = (isErrorVisible, errorObj) => {
|
|
||||||
if (isErrorVisible)
|
|
||||||
return Promise.reject(errorObj)
|
|
||||||
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='login_page shadow'>
|
<LoaderPortal show={showLoader} className={'loader-container login_page shadow'}>
|
||||||
<Card title="Система мониторинга" className='shadow' bordered={true} style={{ width: 350 }} extra={logoIcon}>
|
<Card title={'Система мониторинга'} className={'shadow'} bordered={true} style={{ width: 350 }} extra={logoIcon}>
|
||||||
<Form form={form} onFinish={handleLogin}>
|
<Form onFinish={handleLogin}>
|
||||||
<Form.Item
|
<Form.Item name={'login'} rules={loginRules}>
|
||||||
name="login"
|
<Input placeholder={'Пользователь'} prefix={<UserOutlined />} />
|
||||||
validateStatus={isErrorVisible ? "error" : "validating"}
|
|
||||||
rules={[
|
|
||||||
{ required: true, message: 'Пожалуйста, введите имя пользователя' },
|
|
||||||
() => ({
|
|
||||||
validator() {
|
|
||||||
return showError(isErrorVisible, new Error('Неправильные логин или пароль!'))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Input
|
|
||||||
placeholder="Пользователь"
|
|
||||||
prefix={<UserOutlined />}
|
|
||||||
onChange={() => {
|
|
||||||
setErrorVisible(false)
|
|
||||||
form.validateFields()
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item name={'password'} rules={passwordRules}>
|
||||||
<Form.Item
|
<Input.Password placeholder={'Пароль'} prefix={<LockOutlined />} />
|
||||||
name="password"
|
|
||||||
rules={[
|
|
||||||
{ required: true, message: 'Пожалуйста, введите пароль' },
|
|
||||||
() => ({
|
|
||||||
validator() {
|
|
||||||
return showError(isErrorVisible)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Input.Password
|
|
||||||
placeholder='пароль'
|
|
||||||
prefix={<LockOutlined />}
|
|
||||||
onChange={() => {
|
|
||||||
setErrorVisible(false)
|
|
||||||
form.validateFields()
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<div className='login-button'>
|
<div className={'login-button'}>
|
||||||
<Button type="primary" htmlType="submit">
|
<Button type={'primary'} htmlType={'submit'}>Вход</Button>
|
||||||
Вход
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<div className={'text-align-center'}>
|
||||||
<div className='text-align-center'>
|
|
||||||
<Link to={`/register`}>Отправить заявку на регистрацию</Link>
|
<Link to={`/register`}>Отправить заявку на регистрацию</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</Form>
|
</Form>
|
||||||
</Card>
|
</Card>
|
||||||
{loader && <Loader/>}
|
</LoaderPortal>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -1,198 +1,101 @@
|
|||||||
import { Card, Form, Input, Select, Button, notification } from 'antd';
|
import { memo, useState } from 'react'
|
||||||
import { UserOutlined,
|
import { Link, useHistory } from 'react-router-dom'
|
||||||
|
import { Card, Form, Input, Select, Button } from 'antd'
|
||||||
|
import {
|
||||||
|
UserOutlined,
|
||||||
LockOutlined,
|
LockOutlined,
|
||||||
EyeInvisibleOutlined,
|
EyeInvisibleOutlined,
|
||||||
EyeTwoTone } from '@ant-design/icons'
|
EyeTwoTone
|
||||||
import logo from '../images/logo_32.png'
|
} from '@ant-design/icons'
|
||||||
import Loader from '../components/Loader'
|
|
||||||
import { useState } from 'react'
|
|
||||||
import { Link, useHistory } from "react-router-dom";
|
|
||||||
import { AuthService } from '../services/api/'
|
import { AuthService } from '../services/api/'
|
||||||
|
import LoaderPortal from '../components/LoaderPortal'
|
||||||
const openNotification = (message, type, title) => {
|
import { invokeWebApiWrapperAsync } from '../components/factory'
|
||||||
notification[type]({
|
import {
|
||||||
message: title||'Ошибка',
|
createLoginRules,
|
||||||
description: message,
|
createPasswordRules,
|
||||||
});
|
emailRules,
|
||||||
};
|
loginRules,
|
||||||
|
nameRules,
|
||||||
const { Option } = Select;
|
passwordRules,
|
||||||
|
phoneRules
|
||||||
|
} from '../utils/validationRules'
|
||||||
|
import logo from '../images/logo_32.png'
|
||||||
|
|
||||||
const companies = [
|
const companies = [
|
||||||
{ name: "ООО «Газпромнефть-Хантос» ", value: 1 },
|
{ label: 'ООО «Газпромнефть-Хантос» ', value: 1 },
|
||||||
{ name: "АО «НафтаГаз»", value: 2 },
|
{ label: 'АО «НафтаГаз»', value: 2 },
|
||||||
{ name: "ООО «Нафтагаз Бурение»", value: 3 },
|
{ label: 'ООО «Нафтагаз Бурение»', value: 3 },
|
||||||
{ name: "ООО «Газпромнефть-ННГ»", value: 4 }
|
{ label: 'ООО «Газпромнефть-ННГ»', value: 4 }
|
||||||
];
|
]
|
||||||
|
|
||||||
const showError = (isErrorVisible, errorObj) => {
|
|
||||||
if (isErrorVisible)
|
|
||||||
return Promise.reject(errorObj)
|
|
||||||
|
|
||||||
|
const surnameRules = [...nameRules, { required: true, message: 'Пожалуйста, введите фамилию!' }]
|
||||||
|
const regEmailRules = [{ required: true, message: 'Пожалуйста, введите email!' }, ...emailRules]
|
||||||
|
const confirmPasswordRules = [
|
||||||
|
...createPasswordRules,
|
||||||
|
{ required: true, message: 'Пожалуйста, введите пароль повторно!' },
|
||||||
|
({ getFieldValue }) => ({
|
||||||
|
validator(_, value) {
|
||||||
|
if (!value || getFieldValue('password') === value)
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
return Promise.reject(new Error('Пароли не совпадают!'))
|
||||||
|
|
||||||
const getValidationRules = (isRequired, message, isErrorVisible, errorObj) => {
|
|
||||||
return [
|
|
||||||
{ required: isRequired, message: message },
|
|
||||||
() => ({
|
|
||||||
validator() {
|
|
||||||
return showError(isErrorVisible, errorObj)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
}
|
|
||||||
|
|
||||||
|
const logoIcon = <img src={logo} alt={'АСБ'} className={'logo'} width={130}/>
|
||||||
|
const showPasswordIcon = visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)
|
||||||
|
|
||||||
export default function Register() {
|
const createInput = (name, placeholder, rules, isPassword, dependencies) => (
|
||||||
const [loader, setLoader] = useState(false);
|
<Form.Item name={name} rules={rules ?? []} dependencies={dependencies ?? []}>
|
||||||
const [isLengthErrorVisible, setIsLengthErrorVisible] = useState(false);
|
{isPassword ? (
|
||||||
const [isPasswordLengthErrorVisible, setIsPasswordLengthErrorVisible] = useState(false);
|
<Input.Password placeholder={placeholder} prefix={<LockOutlined />} iconRender={showPasswordIcon} />
|
||||||
const [isPasswordMismatchErrorVisible, setIsPasswordMismatchErrorVisible] = useState(false);
|
) : (
|
||||||
const [selectedCompanyId, setSelectedCompanyId] = useState(companies[0].value);
|
<Input placeholder={placeholder} prefix={<UserOutlined />} />
|
||||||
const history = useHistory();
|
)}
|
||||||
const [form] = Form.useForm();
|
</Form.Item>
|
||||||
|
)
|
||||||
|
|
||||||
const logoIcon = <img src={logo} alt="АСБ" className="logo"/>
|
export const Register = memo(() => {
|
||||||
|
const [showLoader, setShowLoader] = useState(false)
|
||||||
|
const history = useHistory()
|
||||||
|
|
||||||
const children = companies.map((line) => (
|
const handleRegister = (formData) => invokeWebApiWrapperAsync(
|
||||||
<Option key={line.value}>{line.name}</Option>
|
async () => {
|
||||||
));
|
|
||||||
|
|
||||||
const checkFormErrors = (formData) => {
|
|
||||||
if(formData.login.length < 4 || formData.login.length > 50){
|
|
||||||
setIsLengthErrorVisible(true)
|
|
||||||
form.validateFields()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if(formData.password.length < 4 || formData.password.length > 50) {
|
|
||||||
setIsPasswordLengthErrorVisible(true)
|
|
||||||
form.validateFields()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if(formData.password !== formData.confirmPassword) {
|
|
||||||
setIsPasswordMismatchErrorVisible(true)
|
|
||||||
form.validateFields()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
let handleRegister = async (formData) =>{
|
|
||||||
|
|
||||||
if(checkFormErrors(formData))
|
|
||||||
return
|
|
||||||
|
|
||||||
formData.idCompany = +selectedCompanyId
|
|
||||||
|
|
||||||
setLoader(true)
|
|
||||||
try{
|
|
||||||
await AuthService.register(formData)
|
await AuthService.register(formData)
|
||||||
setLoader(false)
|
history.push('/login')
|
||||||
openNotification("Заявка на регистрацию отправлена.", 'success')
|
},
|
||||||
history.push("/login");
|
setShowLoader,
|
||||||
}catch(e){
|
`Ошибка отправки заявки на регистрацию`
|
||||||
openNotification(e.body, 'error')
|
|
||||||
console.error(`Error ${e}`)
|
|
||||||
setLoader(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const createInput = (name, placeholder, isRequired, requiredValidationMessage, lengthValidationMessage) => {
|
|
||||||
|
|
||||||
const rules = getValidationRules(true, requiredValidationMessage,
|
|
||||||
isLengthErrorVisible, new Error(lengthValidationMessage))
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form.Item
|
|
||||||
name={name}
|
|
||||||
rules={isRequired ? rules : []}
|
|
||||||
>
|
|
||||||
<Input
|
|
||||||
placeholder={placeholder}
|
|
||||||
prefix={<UserOutlined />}
|
|
||||||
onChange={() => {
|
|
||||||
setIsLengthErrorVisible(false)
|
|
||||||
form.validateFields()
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
const createPasswordInput = (name, message, errorObj, isErrorVisible, setIsErrorVisible) => {
|
|
||||||
return (
|
|
||||||
<Form.Item
|
|
||||||
name={name}
|
|
||||||
rules={getValidationRules(true, message, isErrorVisible, errorObj)}
|
|
||||||
>
|
|
||||||
<Input.Password
|
|
||||||
placeholder='Подтверждение пароля'
|
|
||||||
iconRender={visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)}
|
|
||||||
prefix={<LockOutlined />}
|
|
||||||
onChange={() => {
|
|
||||||
setIsErrorVisible(false)
|
|
||||||
form.validateFields()
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='login_page shadow'>
|
<LoaderPortal show={showLoader} className={'loader-container login_page shadow'}>
|
||||||
<Card title="Система мониторинга" className='shadow' bordered={true} style={{ width: 350 }} extra={logoIcon}>
|
<Card title={'Система мониторинга'} className={'shadow'} bordered={true} style={{ width: 350 }} extra={logoIcon}>
|
||||||
<Form form={form} onFinish={handleRegister}>
|
<Form onFinish={handleRegister}>
|
||||||
{createInput('login', 'Пользователь', true,
|
{createInput('login', 'Пользователь', [...loginRules, ...createLoginRules])}
|
||||||
'Пожалуйста, введите имя!',
|
{createInput('password', 'Пароль', [...passwordRules, ...createPasswordRules], true, null)}
|
||||||
'Допустимая длина логина от 3 до 50 символов!')}
|
{createInput('confirmPassword', 'Подтверждение пароля', confirmPasswordRules, true, ['password'])}
|
||||||
{createPasswordInput('password', 'Пожалуйста, введите пароль!',
|
{createInput('name', 'Имя', nameRules)}
|
||||||
new Error('Допускаются пароли от 3х до 50ти символов'),
|
{createInput('surName', 'Фамилия', surnameRules)}
|
||||||
isPasswordLengthErrorVisible, setIsPasswordLengthErrorVisible)}
|
{createInput('patronymic', 'Отчество', nameRules)}
|
||||||
{createPasswordInput('confirmPassword', 'Пожалуйста, введите пароль повторно!',
|
{createInput('email', 'Email', regEmailRules)}
|
||||||
new Error('Пароли не совпадают!'), isPasswordMismatchErrorVisible,
|
{createInput('phone', 'Номер телефона', phoneRules)}
|
||||||
setIsPasswordMismatchErrorVisible)}
|
<Form.Item name={'idCompany'} initialValue={companies[0].value}>
|
||||||
{createInput('name', 'Имя', false)}
|
<Select placeholder={'Выберите компанию'} className={'m-0'} options={companies} />
|
||||||
{createInput('surName', 'Фамилия', false)}
|
|
||||||
{createInput('patronymic', 'Отчество',false)}
|
|
||||||
{createInput('email', 'Email',false)}
|
|
||||||
{createInput('phone', 'Номер телефона',false)}
|
|
||||||
<Form.Item
|
|
||||||
name="idCompany"
|
|
||||||
initialValue={companies[0].name}
|
|
||||||
>
|
|
||||||
<Select
|
|
||||||
placeholder="Выберите компанию"
|
|
||||||
className="m-0"
|
|
||||||
value={selectedCompanyId}
|
|
||||||
onChange={setSelectedCompanyId}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{createInput('position', 'Должность',false)}
|
{createInput('position', 'Должность')}
|
||||||
|
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<div className='register-button'>
|
<div className={'register-button'}>
|
||||||
<Button
|
<Button type={'primary'} htmlType={'submit'}>Зарегистрироваться</Button>
|
||||||
type="primary"
|
|
||||||
htmlType="submit"
|
|
||||||
>
|
|
||||||
Зарегистрироваться
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<div className={'text-align-center'}>
|
||||||
<div className='text-align-center'>
|
|
||||||
<Link to={`/login`}>Назад</Link>
|
<Link to={`/login`}>Назад</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</Form>
|
</Form>
|
||||||
</Card>
|
</Card>
|
||||||
{loader && <Loader/>}
|
</LoaderPortal>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
||||||
|
export default Register
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Rule } from 'rc-field-form/lib/interface'
|
import { Rule } from 'rc-field-form/lib/interface'
|
||||||
|
|
||||||
export const loginRules: Rule[] = [{
|
export const createLoginRules: Rule[] = [{
|
||||||
min: 3,
|
min: 3,
|
||||||
max: 255,
|
max: 255,
|
||||||
message: 'Допустимая длина 3-255 символов'
|
message: 'Допустимая длина 3-255 символов'
|
||||||
@ -10,6 +10,11 @@ export const loginRules: Rule[] = [{
|
|||||||
message: 'Логин должен начинаться с русской или латинской буквы, содержать только (А-яA-z0-9_-.)!'
|
message: 'Логин должен начинаться с русской или латинской буквы, содержать только (А-яA-z0-9_-.)!'
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
export const loginRules: Rule[] = [{
|
||||||
|
required: true,
|
||||||
|
message: 'Пожалуйста, введите имя пользователя'
|
||||||
|
}]
|
||||||
|
|
||||||
export const nameRules: Rule[] = [{
|
export const nameRules: Rule[] = [{
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 255,
|
max: 255,
|
||||||
@ -31,5 +36,11 @@ export const emailRules: Rule[] = [{
|
|||||||
|
|
||||||
export const passwordRules: Rule[] = [{
|
export const passwordRules: Rule[] = [{
|
||||||
required: true,
|
required: true,
|
||||||
message: 'Поле не может быть пустым!'
|
message: 'Пожалуйста, введите пароль!'
|
||||||
|
}]
|
||||||
|
|
||||||
|
export const createPasswordRules: Rule[] = [{
|
||||||
|
min: 8,
|
||||||
|
max: 255,
|
||||||
|
message: 'Допустимая длина пароля 8-255'
|
||||||
}]
|
}]
|
||||||
|
Loading…
Reference in New Issue
Block a user