TDMS/web/src/components/user/LoginModal.tsx
Maksim Skobaro c2d19a7724 improved, more featured, fixed
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
2025-02-07 07:05:15 +03:00

142 lines
5.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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