2022-08-08 07:05:49 +03:00

370 lines
12 KiB
JavaScript
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 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));