parent
3a91571bbc
commit
5dd4f3981e
@ -1,13 +1,33 @@
|
||||
export const login = (isAuthenticated: boolean) => (dispatch: any) => {
|
||||
export const login = () => (dispatch: any) => {
|
||||
dispatch({
|
||||
type: 'LOGIN',
|
||||
payload: isAuthenticated,
|
||||
});
|
||||
}
|
||||
|
||||
export const logout = (isAuthenticated: boolean) => (dispatch: any) => {
|
||||
export const loginSuccess = () => (dispatch: any) => {
|
||||
dispatch({
|
||||
type: 'LOGOUT',
|
||||
payload: isAuthenticated,
|
||||
type: 'LOGIN_SUCCESS',
|
||||
});
|
||||
}
|
||||
|
||||
export const loginError = (error = {}) => (dispatch: any) => {
|
||||
dispatch({
|
||||
type: 'LOGIN_ERROR',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
|
||||
export const loginAsync = (username: string, password: string) => {
|
||||
return (dispatch: any) => {
|
||||
dispatch(login());
|
||||
|
||||
return (window as any).cvat.server.login(username, password).then(
|
||||
(authenticated: any) => {
|
||||
dispatch(loginSuccess());
|
||||
},
|
||||
(error: any) => {
|
||||
dispatch(loginError(error));
|
||||
},
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
.login-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
|
||||
&__title {
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Login from './login';
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<Login />, div);
|
||||
ReactDOM.unmountComponentAtNode(div);
|
||||
});
|
||||
@ -0,0 +1,76 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { loginAsync } from '../../actions/auth.actions';
|
||||
|
||||
import { Button, Icon, Input, Form, Col, Row } from 'antd';
|
||||
|
||||
import './login.scss';
|
||||
import Title from 'antd/lib/typography/Title';
|
||||
|
||||
|
||||
class LoginForm extends PureComponent<any, any> {
|
||||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
|
||||
return (
|
||||
<Row type="flex" justify="center" align="middle">
|
||||
<Col span={4}>
|
||||
<Form className="login-form" onSubmit={ this.onSubmit }>
|
||||
<Title className="login-form__title">Login</Title>
|
||||
|
||||
<Form.Item>
|
||||
{getFieldDecorator('username', {
|
||||
rules: [{ required: true, message: 'Please enter your username!' }],
|
||||
})(
|
||||
<Input
|
||||
prefix={ <Icon type="user" /> }
|
||||
type="text"
|
||||
name="username"
|
||||
placeholder="Username"
|
||||
/>,
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
{getFieldDecorator('password', {
|
||||
rules: [{ required: true, message: 'Please enter your password!' }],
|
||||
})(
|
||||
<Input
|
||||
prefix={ <Icon type="lock" /> }
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder="Password"
|
||||
/>,
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<Button type="primary" htmlType="submit" loading={ this.props.isFetching }>
|
||||
Log in
|
||||
</Button>
|
||||
</Form.Item>
|
||||
|
||||
Have not registered yet? <a href="/register">Register here.</a>
|
||||
</Form>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
|
||||
private onSubmit = (event: any) => {
|
||||
event.preventDefault();
|
||||
|
||||
this.props.form.validateFields((error: any, values: any) => {
|
||||
if (!error) {
|
||||
this.props.dispatch(loginAsync(values.username, values.password))
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: any) => {
|
||||
return state.authContext;
|
||||
};
|
||||
|
||||
export default Form.create()(connect(mapStateToProps)(LoginForm));
|
||||
Loading…
Reference in New Issue