2023-10-27 14:58:24 +03:00

599 lines
19 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 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 AccountLayout from "./components/Layout/Account"
import DealsStatus from "../components/DealsStatus"
import AnnouncementsList from "./components/AnnouncementsList"
import { getCompanyInfo, 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(() => {})
})
}
componentDidMount()
{
const { dispatch } = this.props;
this.setState({ loading: true }, () =>
{
getCompanyInfo({ dispatch }).then(() => {}).catch(() => {});
getContractsList({ 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)
}
_handle_onQuestionnaire = () =>
{
console.log(" _handle_onQuestionnaire ");
this.props.router.push("/questionnaire");
}
_renderQuestionnaireStatus = () =>
{
const { company, contracts } = this.state
if(company.questionnaire_status === "need_to_fill")
{
return (
<div className="contract_table" style={{ flexDirection: "column" }}>
<h4>Анкета лизингополучателя</h4>
<p>Вам необходимо заполнить анкету лизингополучателя для актуализации данных.</p>
<div className="questionnaire status_action" style={{ margin: "0px", "padding": "0px", paddingTop: "30px", }}>
<button className="button button-blue" style={{ width: "100%", minWidth: "255px" }} onClick={ () => this.props.router.push("/questionnaire") }>Заполнить анкету</button>
</div>
</div>
)
}
else
{
if(company.questionnaire_status !== "up_to_date")
{
return (
<div className="contract_table" style={{ flexDirection: "column" }}>
<h4>Анкета лизингополучателя</h4>
<p>Анкета подписана, скоро здесь появятся ваши договоры лизинга.</p>
</div>
);
}
else
{
return null;
}
}
}
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)
console.log("company", company)
return (
<React.Fragment>
<Head>
<title>ЛК Эволюция автолизинга</title>
<meta name="description" content="ЛК Эволюция автолизинга" />
</Head>
<Header {...this.props} />
<AccountLayout { ...this.props }>
<div className="title_wrapper">
<div className="left">
<h1 className="section_title">Личный кабинет</h1>
</div>
<div className="right">
<Company company={company} {...this.props} />
</div>
</div>
<AnnouncementsList />
{ contracts !== null && contracts.length > 0 && company.questionnaire_status === "need_to_fill" && (
<div className="questionnaire message notify" style={{ marginLeft: "0" }}>
<svg width="44" height="45" viewBox="0 0 44 45" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M40.5425 31.1863L25.7969 8.08116C24.9653 6.77804 23.5459 6 22 6C20.4539 6 19.0345 6.77804 18.2032 8.08116L3.45741 31.1862C2.57234 32.5732 2.51363 34.3313 3.30467 35.7746C4.09572 37.2173 5.60918 38.1137 7.25444 38.1137H36.7456C38.3909 38.1137 39.9044 37.2175 40.6956 35.7742C41.4863 34.3313 41.4276 32.5733 40.5425 31.1863ZM22 34.2245C20.644 34.2245 19.5448 33.1252 19.5448 31.7694C19.5448 30.4133 20.6441 29.3141 22 29.3141C23.356 29.3141 24.4551 30.4133 24.4551 31.7694C24.4551 33.1252 23.3559 34.2245 22 34.2245ZM25.403 17.1635L24.1937 25.3052C24.0157 26.5037 22.8999 27.3309 21.7016 27.1529C20.7334 27.0091 20.0075 26.25 19.8582 25.333L18.5451 17.2074C18.2394 15.3155 19.5251 13.534 21.417 13.2283C23.3089 12.9226 25.0904 14.2083 25.3962 16.1002C25.4536 16.4565 25.4517 16.8243 25.403 17.1635Z" fill="white" />
</svg>
<p>
<b>Уточните данные</b>
Требуется уточнить данные в анкете клиента
</p>
<button className="button" onClick={this._handle_onQuestionnaire}>
Подробнее
</button>
</div>
) }
{/*}{*/}
<DealsStatus
questionnaire_status={ company.questionnaire_status }
onQuestionnaire={ this._handle_onQuestionnaire }
router={ this.props.router }
/>
{/*}{*/}
{ contracts !== null && contracts.length > 0 && (
<>
<div>
<p className="contracts_list_title">Список договоров</p>
</div>
<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>
) : (
<React.Fragment>
{ contracts === null || contracts.length === 0 ? (
this._renderQuestionnaireStatus()
) : (
<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 !== undefined && 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(" ., ")}&nbsp;
</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(" ., ")}&nbsp;
</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(" ., ")}&nbsp;
</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`)
}}
/>
) }
{ contract.rat_exists && (
<i title="РАТ" data-additional-service="2" onClick={(event) => {
event.stopPropagation()
event.preventDefault()
this._handle_onService(`/contract/${contract.number}/services#ratcard`)
}}
/>
) }
{ contract.gibddreg_exists && (
<i title="Регистрация в ГИБДД" data-additional-service="3" onClick={(event) => {
event.stopPropagation()
event.preventDefault()
this._handle_onService(`/contract/${contract.number}/services#registration`)
}}
/>
) }
{ contract.fuelcard_exists && (
<i title="Топливные карты" data-additional-service="4" onClick={(event) => {
event.stopPropagation()
event.preventDefault()
this._handle_onService(`/contract/${contract.number}/services#fuelcards`)
}}
/>
) }
{contract.kasko_exists && (
<i title="КАСКО" data-additional-service="5" onClick={(event) => {
event.stopPropagation()
event.preventDefault()
this._handle_onService(`/contract/${contract.number}/services#insurance`)
}}
/>
) }
{ contract.osago_exists && (
<i title="ОСАГО" data-additional-service="6" onClick={(event) => {
event.stopPropagation()
event.preventDefault()
this._handle_onService(`/contract/${contract.number}/services#insurance`)
}}
/>
) }
{ contract.nsib_exists && (
<i title="НСИБ" data-additional-service="7" onClick={(event) => {
event.stopPropagation()
event.preventDefault()
this._handle_onService(`/contract/${contract.number}/services#insurance`)
}}
/>
) }
{ contract.fingap_exists && (
<i title="Safe Finance" data-additional-service="8" onClick={(event) => {
event.stopPropagation()
event.preventDefault()
this._handle_onService(`/contract/${contract.number}/services#insurance`)
}}
/>
) }
</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>
)}
</React.Fragment>
) }
{ !all && (
<Pagination
page={page}
pages={pages}
onPage={this._handle_onPage}
onAll={this._handle_onAll}
all={all}
showAll={true}
/>
) }
</AccountLayout>
<Footer />
</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))