370 lines
12 KiB
JavaScript
370 lines
12 KiB
JavaScript
import React from "react";
|
||
import Head from 'next/head';
|
||
import Image from 'next/image';
|
||
import { connect } from "react-redux";
|
||
import { withRouter } from 'next/router';
|
||
import { reduxWrapper } from '../store';
|
||
import pluralize from 'pluralize-ru';
|
||
import { SpinnerCircular } from 'spinners-react';
|
||
import jwt from 'jsonwebtoken';
|
||
import { Cookies } from 'react-cookie';
|
||
import moment from 'moment';
|
||
import cookie from 'cookie';
|
||
|
||
import Header from './components/Header';
|
||
import Footer from './components/Footer';
|
||
import MainHeader from "./components/MainHeader";
|
||
import FormRequest from "./components/FormRequest";
|
||
|
||
import { sendLoginFormEmail, sendLoginFormPhone, sendSmsCode } from '../actions';
|
||
|
||
class LoginPage extends React.Component
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
email: "",
|
||
password: "",
|
||
phone: "",
|
||
phone_code: "",
|
||
tab: "email",
|
||
company: {},
|
||
email_error: false,
|
||
phone_form_step: 1,
|
||
phone_number_error: false,
|
||
phone_number_format_error: false,
|
||
phone_code_error: false,
|
||
email_login_disabled: true,
|
||
phone_login_disabled: true,
|
||
phone_code_submit_disabled: true,
|
||
phone_code_resend_disabled: true,
|
||
phone_sms_code_error: false,
|
||
timer: 0,
|
||
email_auth_loading: false,
|
||
phone_check_loading: false,
|
||
code_check_loading: false,
|
||
};
|
||
|
||
this.timer_ref = null;
|
||
}
|
||
|
||
static getDerivedStateFromProps(nextProps, prevState)
|
||
{
|
||
return {
|
||
company: nextProps.company,
|
||
};
|
||
}
|
||
|
||
_handle_onEmailSubmit = (event) =>
|
||
{
|
||
event.preventDefault();
|
||
|
||
const { email, password, email_auth_loading } = this.state;
|
||
|
||
if(!email_auth_loading)
|
||
{
|
||
this.setState({ email_auth_loading: true }, () =>
|
||
{
|
||
sendLoginFormEmail({ email, password, dispatch: this.props.dispatch })
|
||
.then(() =>
|
||
{
|
||
//this.setState({ email_auth_loading: false, });
|
||
})
|
||
.catch(() =>
|
||
{
|
||
this.setState({ email_error: true, email_auth_loading: false });
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
_handle_onPhoneSubmit = (event) =>
|
||
{
|
||
event.preventDefault();
|
||
|
||
const { phone, phone_check_loading } = this.state;
|
||
|
||
if(!phone_check_loading)
|
||
{
|
||
this.setState({ phone_check_loading: true }, () =>
|
||
{
|
||
sendLoginFormPhone({ phone })
|
||
.then(() =>
|
||
{
|
||
this.setState({ phone_check_loading: false, phone_number_error: false, timer: 60, phone_form_step: 2, }, () =>
|
||
{
|
||
this.timer_ref = setInterval(() =>
|
||
{
|
||
const t = this.state.timer - 1;
|
||
this.setState({ timer: t, }, () =>
|
||
{
|
||
if(t === 0)
|
||
{
|
||
clearInterval(this.timer_ref);
|
||
}
|
||
});
|
||
}, 1000);
|
||
});
|
||
})
|
||
.catch(() =>
|
||
{
|
||
this.setState({ phone_number_error: true, phone_check_loading: false });
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
_handle_onCodeSubmit = (event) =>
|
||
{
|
||
event.preventDefault();
|
||
|
||
const { phone, phone_code, code_check_loading } = this.state;
|
||
|
||
if(!code_check_loading)
|
||
{
|
||
this.setState({ code_check_loading: true }, () =>
|
||
{
|
||
sendSmsCode({ dispatch: this.props.dispatch, phone, code: phone_code })
|
||
.then(() =>
|
||
{
|
||
this.setState({ phone_sms_code_error: false, code_check_loading: false });
|
||
})
|
||
.catch(() =>
|
||
{
|
||
this.setState({ phone_sms_code_error: true, code_check_loading: false });
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
_handle_onResendCode = (event) =>
|
||
{
|
||
this.setState({ phone_sms_code_error: false }, () =>
|
||
{
|
||
this._handle_onPhoneSubmit(event);
|
||
});
|
||
}
|
||
|
||
_handle_onChangeTab = (tab) =>
|
||
{
|
||
this.setState({ tab: tab });
|
||
}
|
||
|
||
_handle_onEmailChange = (value) =>
|
||
{
|
||
this.setState({ email: value, email_login_disabled: this._check_fields_disabled([ value, this.state.password ]), email_error: false });
|
||
}
|
||
|
||
_handle_onPasswordChange = (value) =>
|
||
{
|
||
this.setState({ password: value, email_login_disabled: this._check_fields_disabled([ value, this.state.email ]), email_error: false });
|
||
}
|
||
|
||
_handle_onPhoneChange = (value) =>
|
||
{
|
||
const phone_number_format_error = value.length > 1 && (value[0] !== "+" || value[1] !== "7") ? true : false;
|
||
this.setState({ phone: value, phone_login_disabled: this._check_fields_disabled([ value ]), phone_number_error: false, phone_number_format_error: phone_number_format_error });
|
||
}
|
||
|
||
_handle_onPhoneCodeChange = (value) =>
|
||
{
|
||
this.setState({ phone_code: value, phone_code_submit_disabled: this._check_fields_disabled([ value ]), phone_sms_code_error: false });
|
||
}
|
||
|
||
_handle_onRecover = (event) =>
|
||
{
|
||
event.preventDefault();
|
||
this.props.router.push("/recovery");
|
||
}
|
||
|
||
_handle_onEmailFormFieldKey = (event) =>
|
||
{
|
||
const { email_login_disabled } = this.state;
|
||
|
||
if(event.keyCode === 13)
|
||
{
|
||
event.preventDefault();
|
||
|
||
if(!email_login_disabled)
|
||
{
|
||
this._handle_onEmailSubmit(event);
|
||
}
|
||
}
|
||
}
|
||
|
||
_check_fields_disabled = (values) =>
|
||
{
|
||
for(let i in values)
|
||
{
|
||
if(values[i] === "")
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { email, password, phone, phone_code, tab, email_error, phone_number_error, phone_code_error,
|
||
email_login_disabled, phone_login_disabled, phone_form_step, phone_code_submit_disabled, phone_code_resend_disabled,
|
||
timer, phone_sms_code_error, email_auth_loading, phone_check_loading, code_check_loading, phone_number_format_error } = this.state;
|
||
|
||
return (
|
||
<React.Fragment>
|
||
<Head>
|
||
<title>ЛК Эволюция автолизинга</title>
|
||
<meta
|
||
name="description"
|
||
content="ЛК Эволюция автолизинга"
|
||
/>
|
||
</Head>
|
||
<MainHeader logo_url={ process.env.NEXT_PUBLIC_MAIN_SITE } />
|
||
<main>
|
||
<section>
|
||
<div className="clear"></div>
|
||
<div className="container">
|
||
<h1 className="section_title">Личный кабинет</h1>
|
||
<div className={`login ${ tab === "phone" ? "recovery" : "" }`}>
|
||
<div className="login_with">
|
||
<p>Войти с помощью</p>
|
||
<div className="tabs">
|
||
<div className={`tab ${ tab === "email" ? "active" : "" }`} onClick={ () => this._handle_onChangeTab("email") }>Электронной почты</div>
|
||
<div className={`tab ${ tab === "phone" ? "active" : "" }`} onClick={ () => this._handle_onChangeTab("phone") }>Номера телефона</div>
|
||
</div>
|
||
</div>
|
||
{ tab === "email" ? (
|
||
<form onSubmit={ this._handle_onEmailSubmit }>
|
||
<div className="form_field">
|
||
<input type="text" name="email" value={ email } placeholder="Введите адрес E-mail" onChange={ (event) => this._handle_onEmailChange(event.target.value) } onKeyDown={ this._handle_onEmailFormFieldKey } required={ true }/>
|
||
</div>
|
||
<div className="form_field">
|
||
<input type="password" name="password" value={ password } placeholder="Введите пароль" onChange={ (event) => this._handle_onPasswordChange(event.target.value) } onKeyDown={ this._handle_onEmailFormFieldKey } required={ true }/>
|
||
</div>
|
||
<div style={{ display: "flex", flexDirection: "row", justifyContent: "flex-end", alignItems: "flex-end" }}>
|
||
<div>
|
||
<button className="button button-blue transparent" style={{ width: "160px" }} onClick={ (event) => this._handle_onRecover(event) }>Забыли пароль?</button>
|
||
</div>
|
||
<div>
|
||
<button type="submit" className="button button-blue" disabled={ email_login_disabled }>
|
||
{ email_auth_loading ? (
|
||
<SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" style={{ marginTop: "4px" }}/>
|
||
) : "Войти" }
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<p>{ email_error ? 'Ошибка: Неверный логин или пароль' : `\u00A0` }</p>
|
||
</form>
|
||
) : (
|
||
<>
|
||
{ phone_form_step === 1 && (
|
||
<>
|
||
<form onSubmit={ this._handle_onPhoneSubmit }>
|
||
<div className="form_field">
|
||
<input type="text" name="phone" value={ phone } placeholder="Введите номер телефона, например +7 900 111 22 33" onChange={ (event) => this._handle_onPhoneChange(event.target.value) } required={ true }/>
|
||
</div>
|
||
<button type="submit" className="button button-blue" disabled={ phone_login_disabled }>
|
||
{ phone_check_loading ? (
|
||
<SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" style={{ marginTop: "4px" }}/>
|
||
) : "Получить код" }
|
||
</button>
|
||
</form>
|
||
<p>{ phone_number_error ? 'Ошибка: нет аккаунта с таким номером телефона' : `\u00A0` }</p>
|
||
<p>{ phone_number_format_error ? 'Ошибка: номер должен начинаться на +7' : `\u00A0` }</p>
|
||
</>
|
||
) }
|
||
{ phone_form_step === 2 && (
|
||
<>
|
||
<p className="message">На номер <strong>+{ phone.replace(/[^0-9.]/g, '') }</strong> отправлен код подтверждения.</p>
|
||
<form onSubmit={ this._handle_onCodeSubmit }>
|
||
<div className="form_field">
|
||
<input type="text" name="phone_code" value={ phone_code } placeholder="Введите код из СМС" onChange={ (event) => this._handle_onPhoneCodeChange(event.target.value) } />
|
||
</div>
|
||
<button type="submit" className="button button-blue" disabled={ phone_code_submit_disabled }>
|
||
{ code_check_loading ? (
|
||
<SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" style={{ marginTop: "4px" }}/>
|
||
) : "Отправить код" }
|
||
</button>
|
||
</form>
|
||
<div className="resend" style={{ justifyContent: "flex-start" }}>
|
||
{ timer !== 0 ? (
|
||
<p>Запросить код повторно можно через: { timer } { pluralize(timer, 'секунд', 'секунду', 'секунды', 'секунд') }</p>
|
||
) : (
|
||
<button className="button button-blue transparent" onClick={ (event) => this._handle_onResendCode(event) }>Запросить код повторно</button>
|
||
) }
|
||
{/* disabled={ phone_code_resend_disabled }*/}
|
||
</div>
|
||
<p>{ phone_sms_code_error ? 'Ошибка: Вы указали неверный код' : `\u00A0` }</p>
|
||
</>
|
||
) }
|
||
</>
|
||
) }
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<FormRequest/>
|
||
</main>
|
||
<Footer/>
|
||
</React.Fragment>
|
||
);
|
||
}
|
||
}
|
||
|
||
function mapStateToProps(state, ownProps)
|
||
{
|
||
return {
|
||
company: state.company,
|
||
}
|
||
}
|
||
|
||
export const getServerSideProps = reduxWrapper.getServerSideProps(store =>
|
||
async ({ req, res, query }) =>
|
||
{
|
||
console.log("JWT TOKEN WITH CRM KEY", jwt.sign({ "acc_number": "ACC759", }, process.env.JWT_SECRET_CRM, { noTimestamp: false }));
|
||
/*
|
||
if(query.token !== undefined && query.token !== null)
|
||
{
|
||
try
|
||
{
|
||
var client_jwt_decoded = jwt.verify(query.token, process.env.JWT_SECRET_CRM);
|
||
console.log("LoginPage", "token", "client_jwt_decoded", client_jwt_decoded);
|
||
|
||
const client_token = jwt.sign({ "acc_number": client_jwt_decoded.acc_number, }, process.env.JWT_SECRET_CLIENT, { noTimestamp: true });
|
||
|
||
res.setHeader('Set-Cookie', [
|
||
cookie.serialize(
|
||
'jwt', client_token, {
|
||
//httpOnly: true,
|
||
//secure: process.env.NODE_ENV !== 'development',
|
||
maxAge: new Date(moment().add(7, 'day').toDate()),
|
||
//sameSite: 'strict',
|
||
//path: '/'
|
||
}
|
||
),
|
||
cookie.serialize(
|
||
'observer', true, {
|
||
//httpOnly: true,
|
||
//secure: process.env.NODE_ENV !== 'development',
|
||
maxAge: new Date(moment().add(7, 'day').toDate()),
|
||
//sameSite: 'strict',
|
||
//path: '/'
|
||
}
|
||
)
|
||
]);
|
||
|
||
res.statusCode = 302;
|
||
res.setHeader('Location', `/`);
|
||
}
|
||
catch(error)
|
||
{
|
||
console.error(error);
|
||
}
|
||
}
|
||
*/
|
||
}
|
||
);
|
||
|
||
export default withRouter(connect(mapStateToProps)(LoginPage));
|