353 lines
14 KiB
JavaScript
353 lines
14 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 moment from 'moment';
|
||
import { SpinnerCircular } from 'spinners-react';
|
||
|
||
import { withRouter } from 'next/router';
|
||
import { reduxWrapper } from '../store';
|
||
|
||
import Header from './components/Header';
|
||
import Footer from './components/Footer';
|
||
import Company from "./components/Company";
|
||
import DateInput from './components/DatePicker';
|
||
import Pagination from './components/Pagination';
|
||
import Manager from "./components/Manager";
|
||
|
||
import AnnouncementsList from "./components/AnnouncementsList";
|
||
|
||
import { getContractsList, getImage } from '../actions';
|
||
|
||
class IndexPage extends React.Component
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
company: {},
|
||
contracts: null,
|
||
order: "date",
|
||
sort_number: "desc",
|
||
sort_date: "desc",
|
||
sort_status: "desc",
|
||
search: "",
|
||
date_from: undefined,
|
||
date_from_type: "text",
|
||
date_to: undefined,
|
||
date_to_type: "text",
|
||
loading: false,
|
||
page: 1,
|
||
pages: 1,
|
||
all: false,
|
||
};
|
||
}
|
||
|
||
static getDerivedStateFromProps(nextProps, prevState)
|
||
{
|
||
return {
|
||
company: nextProps.company,
|
||
contracts: nextProps.contracts,
|
||
page: nextProps.page,
|
||
pages: nextProps.pages,
|
||
};
|
||
}
|
||
|
||
componentDidMount()
|
||
{
|
||
this.setState({ loading: true }, () =>
|
||
{
|
||
getContractsList({ dispatch: this.props.dispatch, order: this.state.order, sort: this.state.sort_number, }).then(() => {
|
||
this.setState({ loading: false });
|
||
}).catch(() => {});
|
||
});
|
||
}
|
||
|
||
_handle_onChange_search = (value) =>
|
||
{
|
||
this.setState({ search: value });
|
||
}
|
||
|
||
_handle_onChange_date_from = (value) =>
|
||
{
|
||
this.setState({ date_from: value });
|
||
}
|
||
|
||
_handle_onChange_date_to = (value) =>
|
||
{
|
||
this.setState({ date_to: value });
|
||
}
|
||
|
||
_handle_onChangeSort_number = () =>
|
||
{
|
||
this.setState({ loading: true, order: "number", sort_number: this.state.sort_number === "desc" ? "asc" : "desc" }, () =>
|
||
{
|
||
getContractsList({ dispatch: this.props.dispatch, order: this.state.order, sort: this.state.sort_number, all: this.state.all, }).then(() => {
|
||
this.setState({ loading: false });
|
||
}).catch(() => {});
|
||
});
|
||
}
|
||
|
||
_handle_onChangeSort_date = () =>
|
||
{
|
||
this.setState({ loading: true, order: "date", sort_date: this.state.sort_date === "desc" ? "asc" : "desc" }, () =>
|
||
{
|
||
getContractsList({ dispatch: this.props.dispatch, order: this.state.order, sort: this.state.sort_date, all: this.state.all, }).then(() => {
|
||
this.setState({ loading: false });
|
||
}).catch(() => {});
|
||
});
|
||
}
|
||
|
||
_handle_onChangeSort_status = () =>
|
||
{
|
||
this.setState({ loading: true, order: "status", sort_status: this.state.sort_status === "desc" ? "asc" : "desc" }, () =>
|
||
{
|
||
getContractsList({ dispatch: this.props.dispatch, order: this.state.order, sort: this.state.sort_status, all: this.state.all, }).then(() => {
|
||
this.setState({ loading: false });
|
||
}).catch(() => {});
|
||
});
|
||
}
|
||
|
||
_handle_onPage = (page) =>
|
||
{
|
||
const { order, sort_number, sort_status, search, date_from, date_to, } = this.state;
|
||
|
||
this.setState({ loading: true, }, () =>
|
||
{
|
||
getContractsList({ dispatch: this.props.dispatch, order, sort_number, sort_status, search, date_from, date_to, page, all: this.state.all, }).then(() => {
|
||
this.setState({ loading: false });
|
||
}).catch(() => {});
|
||
});
|
||
}
|
||
|
||
_handle_onAll = () =>
|
||
{
|
||
const { order, sort_number, sort_status, search, date_from, date_to, } = this.state;
|
||
|
||
this.setState({ loading: true, all: true }, () =>
|
||
{
|
||
getContractsList({ dispatch: this.props.dispatch, order, sort_number, sort_status, search, date_from, date_to, all: this.state.all, }).then(() => {
|
||
this.setState({ loading: false });
|
||
}).catch(() => {});
|
||
});
|
||
}
|
||
|
||
_handle_onSearch = () =>
|
||
{
|
||
const { search, date_from, date_to, } = this.state;
|
||
|
||
this.setState({ loading: true, }, () =>
|
||
{
|
||
getContractsList({ dispatch: this.props.dispatch, search, date_from, date_to, all: this.state.all, }).then(() => {
|
||
this.setState({ loading: false });
|
||
}).catch(() => {});
|
||
});
|
||
}
|
||
|
||
_handle_onService = (url) =>
|
||
{
|
||
this.props.router.push(url);
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { company, loading, page, pages, search, date_from, date_from_type, date_to, date_to_type, contracts, sort_number, sort_date, sort_status, all } = this.state;
|
||
|
||
const contract_status = {
|
||
"Действующий": "opened",
|
||
"Закрыт": "closed",
|
||
};
|
||
|
||
console.log("contracts", contracts);
|
||
|
||
return (
|
||
<React.Fragment>
|
||
<Head>
|
||
<title>ЛК Эволюция автолизинга</title>
|
||
<meta
|
||
name="description"
|
||
content="ЛК Эволюция автолизинга"
|
||
/>
|
||
</Head>
|
||
<Header { ...this.props }/>
|
||
<main>
|
||
<section>
|
||
<div className="clear"></div>
|
||
<div className="overflow">
|
||
<div className="container">
|
||
<div className="title_wrapper">
|
||
<div className="left">
|
||
<h1 className="section_title">Личный кабинет</h1>
|
||
</div>
|
||
<div className="right">
|
||
<Company company={ company } { ...this.props }/>
|
||
</div>
|
||
</div>
|
||
<AnnouncementsList />
|
||
<div className="contract_search">
|
||
<form onSubmit={ (event) => { event.preventDefault(); } }>
|
||
<div className="form_field">
|
||
<input type="search" value={ search } placeholder="Поиск" onChange={ (event) => {
|
||
this._handle_onChange_search(event.target.value);
|
||
} }/>
|
||
</div>
|
||
<div className="form_field">
|
||
{/*
|
||
<input type={ date_from_type } id="date_from" className="date_input" value="" placeholder="Дата договора от" onFocus={ () => this.setState({ date_from_type: "date" }) } onBlur={ () => { this.setState({ date_from_type: "text" }) } } onChange={ (date) => {
|
||
this._handle_onChange_date_from(date);
|
||
} }/>
|
||
<label htmlFor="date_from">Дата<br/>договора от</label>
|
||
*/}
|
||
<DateInput placeholder="Дата договора от" id={ "date_from" } onChange={ (date) => this.setState({ date_from: date }) }/>
|
||
</div>
|
||
<div className="form_field">
|
||
{/*<input type={ date_to_type } id="date_for" className="date_input" value="" placeholder="Дата договора по" onFocus={ () => this.setState({ date_from_type: "date" }) } onBlur={ () => { this.setState({ date_from_type: "text" }) } } onChange={ (date) => {
|
||
this._handle_onChange_date_to(date);
|
||
} }/>
|
||
<label htmlFor="date_for">Дата<br/>договора по</label>*/}
|
||
<DateInput placeholder="Дата договора по" id={ "date_to" } onChange={ (date) => this.setState({ date_to: date }) }/>
|
||
</div>
|
||
<button className="button" disabled={ search !== "" || date_from !== "" || date_to !== "" ? false : true } onClick={ this._handle_onSearch }>Поиск</button>
|
||
</form>
|
||
</div>
|
||
{ loading ? (
|
||
<div className="table_row table_header" style={{ minHeight: 450, display: "flex", justifyContent: "center", alignItems: "center" }}>
|
||
<SpinnerCircular size={90} thickness={51} speed={100} color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" />
|
||
</div>
|
||
) : (
|
||
<div className="contract_table">
|
||
<div className="table_row table_header">
|
||
<div className={`table_cell caret ${ sort_number === "asc" ? "reverse" : "" }`} onClick={ this._handle_onChangeSort_number }>Номер договора</div>
|
||
<div className={`table_cell caret ${ sort_date === "asc" ? "reverse" : "" }`} onClick={ this._handle_onChangeSort_date }>Дата договора</div>
|
||
<div className="table_cell">Автомобиль</div>
|
||
<div className="table_cell">Гос.номер / VIN</div>
|
||
<div className={`table_cell caret ${ sort_status === "asc" ? "reverse" : "" }`} onClick={ this._handle_onChangeSort_status }>Статус</div>
|
||
<div className="table_cell">Следующий платеж</div>
|
||
<div className="table_cell">Дополнительные услуги</div>
|
||
</div>
|
||
{ contracts !== null && (
|
||
<>
|
||
{ contracts.length > 0 ? contracts.map((contract, index) => (
|
||
<Link href={`/contract/${ contract.number }/payments`} key={ index }>
|
||
<div className="table_row" key={ index } style={{ cursor: "pointer" }}>
|
||
<div className="table_cell"><a>{ contract.number }</a></div>
|
||
<div className="table_cell">{ moment(contract.date).format("DD.MM.YYYY") }</div>
|
||
<div className="table_cell">{ contract.car?.brand?.name } { contract.car?.model?.name }</div>
|
||
<div className="table_cell">
|
||
{ contract.car?.reg_number !== null ? contract.car?.reg_number : "Без рег. номера" }
|
||
<span>{ contract.car?.vin_number }</span>
|
||
</div>
|
||
<div className="table_cell">
|
||
<p className={ contract_status[contract.status] }>{ contract.status }</p>
|
||
{ contract.debt_leasing !== undefined && contract.debt_leasing !== null && parseFloat(contract.debt_leasing) > 0 && (
|
||
<p className="contract_debt">
|
||
<span>Задолжность:</span>
|
||
{ numeral(contract.debt_leasing).format(' ., ') } ₽
|
||
</p>
|
||
) }
|
||
{ contract.debt_penalty_fee !== undefined && contract.debt_penalty_fee !== null && parseFloat(contract.debt_penalty_fee) > 0 && (
|
||
<p className="contract_debt">
|
||
<span>Пени:</span>
|
||
{ numeral(contract.debt_penalty_fee).format(' ., ') } ₽
|
||
</p>
|
||
) }
|
||
</div>
|
||
<div className="table_cell">
|
||
{ contract.current_payment_date !== null ? (
|
||
<>{ moment(contract.current_payment_date).format("DD.MM.YYYY") }<b className="price" style={{ whiteSpace: "nowrap" }}>{ numeral(contract.current_payment_amount).format(' ., ') } ₽</b></>
|
||
) : "-" }
|
||
</div>
|
||
<div className="table_cell">
|
||
<div className="service_list">
|
||
{ contract.telematics_exists && <i title="Телематика" data-additional-service="1" onClick={ (event) => { event.stopPropagation(); event.preventDefault(); this._handle_onService(`/contract/${ contract.number }/services#telematic`) } }></i> }
|
||
{ contract.rat_exists && <i title="РАТ" data-additional-service="2" onClick={ (event) => { event.stopPropagation(); event.preventDefault(); this._handle_onService(`/contract/${ contract.number }/services#ratcard`) } }></i> }
|
||
{ contract.gibddreg_exists && <i title="Регистрация в ГИБДД" data-additional-service="3" onClick={ (event) => { event.stopPropagation(); event.preventDefault(); this._handle_onService(`/contract/${ contract.number }/services#registration`) } }></i> }
|
||
{ contract.fuelcard_exists && <i title="Топливные карты" data-additional-service="4" onClick={ (event) => { event.stopPropagation(); event.preventDefault(); this._handle_onService(`/contract/${ contract.number }/services#fuelcards`) } }></i> }
|
||
{ contract.kasko_exists && <i title="КАСКО" data-additional-service="5" onClick={ (event) => { event.stopPropagation(); event.preventDefault(); this._handle_onService(`/contract/${ contract.number }/services#insurance`) } }></i> }
|
||
{ contract.osago_exists && <i title="ОСАГО" data-additional-service="6" onClick={ (event) => { event.stopPropagation(); event.preventDefault(); this._handle_onService(`/contract/${ contract.number }/services#insurance`) } }></i> }
|
||
{ contract.nsib_exists && <i title="НСИБ" data-additional-service="7" onClick={ (event) => { event.stopPropagation(); event.preventDefault(); this._handle_onService(`/contract/${ contract.number }/services#insurance`) } }></i> }
|
||
{ contract.fingap_exists && <i title="FinGAP" data-additional-service="8" onClick={ (event) => { event.stopPropagation(); event.preventDefault(); this._handle_onService(`/contract/${ contract.number }/services#insurance`) } }></i> }
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Link>
|
||
)) : (
|
||
<div className="table_row">
|
||
<div className="table_cell">-</div>
|
||
<div className="table_cell">-</div>
|
||
<div className="table_cell">-</div>
|
||
<div className="table_cell">-</div>
|
||
<div className="table_cell">-</div>
|
||
<div className="table_cell">-</div>
|
||
<div className="table_cell">-</div>
|
||
</div>
|
||
) }
|
||
</>
|
||
) }
|
||
</div>
|
||
) }
|
||
{ !all && (
|
||
<Pagination page={ page } pages={ pages } onPage={ this._handle_onPage } onAll={ this._handle_onAll } all={ all } showAll={ true }/>
|
||
) }
|
||
|
||
<Manager/>
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
<Footer authenticated={ true }/>
|
||
</React.Fragment>
|
||
)
|
||
}
|
||
}
|
||
|
||
function mapStateToProps(state, ownProps)
|
||
{
|
||
return {
|
||
company: state.company,
|
||
contracts: state.contracts.list,
|
||
page: state.contracts.page,
|
||
pages: state.contracts.pages,
|
||
}
|
||
}
|
||
|
||
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)); |