Exceptions and Errors are better Files structure is better New ComponentContext.ts New DataTable.tsx tables.ts Massive components refactoring New Group.java New LoggingRequestFilter.java LoggingSessionListener.java New NotificationStore.ts SysInfoStore.ts New reactiveValue.ts ReactiveControls.tsx New dependencies And much more
142 lines
5.7 KiB
TypeScript
142 lines
5.7 KiB
TypeScript
import {ChangeEvent} from "react";
|
||
import {Button, FormControl, FormGroup, FormLabel, FormText, Modal} from "react-bootstrap";
|
||
import {ModalState} from "../../utils/modalState";
|
||
import {observer} from "mobx-react";
|
||
import {action, computed, makeObservable, observable, reaction} from "mobx";
|
||
import {post} from "../../utils/request";
|
||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||
import {ComponentContext} from "../../utils/ComponentContext";
|
||
|
||
interface LoginModalProps {
|
||
modalState: ModalState;
|
||
}
|
||
|
||
@observer
|
||
export class LoginModal extends ComponentContext<LoginModalProps> {
|
||
@observable login = '';
|
||
@observable loginError = '';
|
||
@observable password = '';
|
||
@observable passwordError = '';
|
||
|
||
constructor(props: LoginModalProps) {
|
||
super(props);
|
||
makeObservable(this);
|
||
reaction(() => this.login, this.validateLogin);
|
||
reaction(() => this.password, this.validatePassword);
|
||
}
|
||
|
||
@action.bound
|
||
validateLogin() {
|
||
if (!this.login) {
|
||
this.loginError = 'Имя пользователя не может быть пустым';
|
||
} else if (this.login.length < 5) {
|
||
this.loginError = 'Имя пользователя должно быть не менее 5 символов';
|
||
} else if (this.login.length > 50) {
|
||
this.loginError = 'Имя пользователя должно быть не более 50 символов';
|
||
} else if (!/^[a-zA-Z0-9_]+$/.test(this.login)) {
|
||
this.loginError = 'Имя пользователя должно содержать только латинские буквы, цифры и знак подчеркивания';
|
||
} else {
|
||
this.loginError = '';
|
||
}
|
||
}
|
||
|
||
@action.bound
|
||
validatePassword() {
|
||
if (!this.password) {
|
||
this.passwordError = 'Пароль не может быть пустым';
|
||
} else if (this.password.length < 5) {
|
||
this.passwordError = 'Пароль должен быть не менее 5 символов';
|
||
} else if (this.password.length > 32) {
|
||
this.passwordError = 'Пароль должен быть не более 32 символов';
|
||
} else if (!/^[a-zA-Z0-9!@#$%^&*()_+]+$/.test(this.password)) {
|
||
this.passwordError = 'Пароль должен содержать только латинские буквы, цифры и специальные символы';
|
||
} else {
|
||
this.passwordError = '';
|
||
}
|
||
}
|
||
|
||
@computed
|
||
get loginButtonDisabled() {
|
||
return !this.login || !this.password || !!this.loginError || !!this.passwordError;
|
||
}
|
||
|
||
@action.bound
|
||
onLoginInput(event: ChangeEvent<HTMLInputElement>) {
|
||
this.login = event.target.value;
|
||
}
|
||
|
||
@action.bound
|
||
onPasswordInput(event: ChangeEvent<HTMLInputElement>) {
|
||
this.password = event.target.value;
|
||
}
|
||
|
||
@action.bound
|
||
tryLogin() {
|
||
if (this.loginButtonDisabled)
|
||
return;
|
||
|
||
this.thinkStore.think('loginModal');
|
||
post('user/login', {
|
||
username: this.login,
|
||
password: this.password
|
||
}).then(() => {
|
||
this.userStore.updateCurrentUser((user) => {
|
||
if (user.authenticated) {
|
||
this.routerStore.goTo('profile').then();
|
||
this.notificationStore.success('Вы успешно вошли в систему, ' + user.fullName, 'Успешный вход');
|
||
} else {
|
||
this.routerStore.goTo('root').then();
|
||
this.notificationStore.error('Произошла ошибка при попытке входа в систему', 'Ошибка входа');
|
||
}
|
||
});
|
||
}).finally(() => {
|
||
this.props.modalState.close();
|
||
this.thinkStore.completeAll('loginModal');
|
||
});
|
||
}
|
||
|
||
render() {
|
||
const open = this.props.modalState.isOpen;
|
||
const thinking = this.thinkStore.isThinking('loginModal');
|
||
|
||
return <Modal show={open} centered>
|
||
<Modal.Header>
|
||
<Modal.Title>Вход</Modal.Title>
|
||
</Modal.Header>
|
||
{
|
||
thinking &&
|
||
<Modal.Body>
|
||
<FontAwesomeIcon icon={'gear'} spin/>
|
||
</Modal.Body>
|
||
}
|
||
{
|
||
!thinking &&
|
||
<>
|
||
<Modal.Body>
|
||
<FormGroup className={'mb-3'}>
|
||
<FormLabel>Имя пользователя</FormLabel>
|
||
<FormControl type="text" onChange={this.onLoginInput}/>
|
||
{
|
||
this.loginError &&
|
||
<FormText className={'text-danger'}>{this.loginError}</FormText>
|
||
}
|
||
</FormGroup>
|
||
<FormGroup className={'mb-3'}>
|
||
<FormLabel>Пароль</FormLabel>
|
||
<FormControl type="password" onChange={this.onPasswordInput}/>
|
||
{
|
||
this.passwordError &&
|
||
<FormText className={'text-danger'}>{this.passwordError}</FormText>
|
||
}
|
||
</FormGroup>
|
||
</Modal.Body>
|
||
<Modal.Footer>
|
||
<Button variant={'primary'} onClick={this.tryLogin}
|
||
disabled={this.loginButtonDisabled}>Войти</Button>
|
||
<Button variant={'secondary'} onClick={this.props.modalState.close}>Закрыть</Button>
|
||
</Modal.Footer>
|
||
</>
|
||
}
|
||
</Modal>
|
||
}
|
||
} |