289 lines
9.2 KiB
JavaScript
289 lines
9.2 KiB
JavaScript
import React from "react";
|
||
import Head from 'next/head';
|
||
import Image from 'next/image';
|
||
import Link from "next/link";
|
||
import cookie from 'cookie';
|
||
import { connect } from "react-redux";
|
||
import numeral from "numeral";
|
||
import pluralize from 'pluralize-ru';
|
||
import { SpinnerCircular } from 'spinners-react';
|
||
|
||
import { withRouter } from 'next/router';
|
||
import { reduxWrapper } from '../../store';
|
||
|
||
import InnerMenu from "./components/InnerMenu";
|
||
import Header from '../components/Header';
|
||
import Footer from '../components/Footer';
|
||
import Pagination from '../components/Pagination';
|
||
import Company from "../components/Company";
|
||
|
||
import { sendPhoneChangeNumber, sendPhoneChangeNumberSmsCode, setUserPhone } from '../../actions';
|
||
|
||
class IndexPage extends React.Component
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
phone: "",
|
||
phone_code: "",
|
||
phone_form_step: 1,
|
||
phone_number_error: false,
|
||
phone_number_format_error: false,
|
||
phone_code_error: false,
|
||
phone_login_disabled: true,
|
||
phone_code_submit_disabled: true,
|
||
phone_code_resend_disabled: true,
|
||
phone_sms_code_error: false,
|
||
timer: 0,
|
||
phone_check_loading: false,
|
||
code_check_loading: false,
|
||
user: {},
|
||
};
|
||
}
|
||
|
||
static getDerivedStateFromProps(nextProps, prevState)
|
||
{
|
||
return {
|
||
user: nextProps.user,
|
||
};
|
||
}
|
||
|
||
componentDidMount()
|
||
{
|
||
}
|
||
|
||
_handle_onPhoneSubmit = (event) =>
|
||
{
|
||
event.preventDefault();
|
||
|
||
const { user, phone, phone_check_loading } = this.state;
|
||
|
||
if(!phone_check_loading)
|
||
{
|
||
this.setState({ phone_check_loading: true }, () =>
|
||
{
|
||
sendPhoneChangeNumber({ email: user.email, 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 }, () =>
|
||
{
|
||
sendPhoneChangeNumberSmsCode({ phone, code: phone_code })
|
||
.then(() =>
|
||
{
|
||
const new_user = { ...this.state.user };
|
||
new_user.phone = phone;
|
||
|
||
setUserPhone({ dispatch: this.props.dispatch, user: new_user });
|
||
|
||
this.setState({ phone_sms_code_error: false, code_check_loading: false, phone_form_step: 3 });
|
||
})
|
||
.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_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 });
|
||
}
|
||
|
||
_check_fields_disabled = (values) =>
|
||
{
|
||
for(let i in values)
|
||
{
|
||
if(values[i] === "")
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { user, phone, phone_code, phone_number_error, phone_code_error,
|
||
phone_login_disabled, phone_form_step, phone_code_submit_disabled, phone_code_resend_disabled,
|
||
timer, phone_sms_code_error, phone_check_loading, code_check_loading, phone_number_format_error } = this.state;
|
||
|
||
return (
|
||
<React.Fragment>
|
||
<Head>
|
||
<title>ЛК Эволюция автолизинга</title>
|
||
<meta
|
||
name="description"
|
||
content="ЛК Эволюция автолизинга"
|
||
/>
|
||
</Head>
|
||
<Header { ...this.props }/>
|
||
<main>
|
||
<section>
|
||
<div className="clear"></div>
|
||
<div className="container">
|
||
<div className="title_wrapper">
|
||
<div className="left">
|
||
<h1 className="section_title">Вход по номеру телефона</h1>
|
||
</div>
|
||
<Company { ...this.props }/>
|
||
</div>
|
||
<div className="aside_container about">
|
||
<InnerMenu { ...this.props }/>
|
||
<article>
|
||
{ phone_form_step !== 2 && phone_form_step !== 3 && (
|
||
<>
|
||
{ user.phone !== undefined && user.phone !== null && user.phone !== "" ? (
|
||
<p>Номер для авторизации <strong>+{ user.phone.replace(/[^0-9.]/g, '') }</strong>. Вы можете изменить номер телефона для авторизации.</p>
|
||
) : (
|
||
<p>У Вас отсутствует привязанный номер телефона. Вы можете добавить номер телефона для авторизации.</p>
|
||
) }
|
||
</>
|
||
) }
|
||
<p><br/></p>
|
||
<div className={`login recovery`}>
|
||
{ 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>
|
||
</>
|
||
) }
|
||
{ phone_form_step === 3 && (
|
||
<p className="message">Вы успешно привязали номер <strong>+{ phone.replace(/[^0-9.]/g, '') }</strong> к Вашей учетной записи.</p>
|
||
) }
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
<Footer authenticated={ true }/>
|
||
</React.Fragment>
|
||
)
|
||
}
|
||
}
|
||
|
||
function mapStateToProps(state, ownProps)
|
||
{
|
||
return {
|
||
user: state.user,
|
||
}
|
||
}
|
||
|
||
export const getServerSideProps = reduxWrapper.getServerSideProps(store =>
|
||
async ({ req, res, query }) =>
|
||
{
|
||
let props = {};
|
||
|
||
if(req.headers.cookie !== undefined)
|
||
{
|
||
const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : "");
|
||
|
||
if(cookies.jwt === undefined || cookies.jwt === null)
|
||
{
|
||
res.statusCode = 302;
|
||
res.setHeader('Location', `/login`);
|
||
}
|
||
else
|
||
{
|
||
//const tokenValid = await checkToken(cookies.jwt);
|
||
const tokenValid = true;
|
||
if(!tokenValid)
|
||
{
|
||
res.statusCode = 302;
|
||
res.setHeader('Location', `/login`);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
res.statusCode = 302;
|
||
res.setHeader('Location', `/login`);
|
||
}
|
||
|
||
return { props: props };
|
||
}
|
||
);
|
||
|
||
export default withRouter(connect(mapStateToProps)(IndexPage)); |