Страницы входа и регистрации упрощены

This commit is contained in:
goodmice 2021-12-07 19:41:32 +05:00
parent f389097439
commit 91a9bf9c9f
3 changed files with 122 additions and 272 deletions

View File

@ -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>
) )
} }

View File

@ -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

View File

@ -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'
}] }]