release v 1.0

This commit is contained in:
merelendor 2021-12-06 15:48:05 +03:00
parent 8348004f49
commit fab3709d57
58 changed files with 5601 additions and 745 deletions

View File

@ -103,64 +103,80 @@ export const sendLoginFormEmail = ({ email, password, dispatch }) =>
}); });
} }
export const sendLoginFormPhone = (fields) => export const sendLoginFormPhone = ({ phone }) =>
{ {
return new Promise((resolve, reject) => return new Promise((resolve, reject) =>
{ {
axios.post(`${ process.env.NEXT_PUBLIC_API_HOST }/api/account/auth/`, fields) axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/auth/phone/check`, { phone })
.then((response) => .then((response) =>
{ {
console.log("sendTermsForm RESPONSE"); console.log("sendTermsForm RESPONSE");
console.log(response.data); console.log(response.data);
if(response.data.status) if(response.data)
{ {
console.log("DATA? ");
resolve(); resolve();
} }
else else
{
console.log("DATA ! ");
reject();
}
})
.catch((error) =>
{
console.log("DATA !!! ");
console.log("error");
console.error(error);
reject();
});
});
}
export const sendSmsCode = ({ dispatch, phone, code }) =>
{
return new Promise((resolve, reject) =>
{
axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/auth/phone/code`, { phone, code })
.then((response) =>
{
console.log("checkSmsCode RESPONSE");
console.log(response.data);
if(response.data.status === "success")
{
const cookies = new Cookies();
cookies.set('jwt', response.data.token, new Date(moment().add(7, 'day').toDate()));
getCompanyInfo({ dispatch })
.then(() =>
{
dispatch({ type: actionTypes.AUTH, data: { logged: true } });
dispatch({ type: actionTypes.USER, data: response.data.user });
resolve();
Router.push('/');
})
.catch(() =>
{
reject();
});
}
else
{ {
reject(); reject();
} }
}) })
.catch((error) => .catch((error) =>
{ {
console.log("DATA !!! ");
console.log("error"); console.log("error");
console.error(error); console.error(error);
reject(); reject();
}); });
if(fields.username === "test@test.com" && fields.password === "test")
{
const cookies = new Cookies();
cookies.set('jwt', 1, new Date(moment().add(1, 'day').toDate()));
}
Router.push('/');
/*
axios.post(`${ process.env.NEXT_PUBLIC_API_HOST }/api/forms/terms/`, fields)
.then((response) =>
{
console.log("sendTermsForm RESPONSE");
console.log(response.data);
if(response.data.status)
{
resolve();
}
else
{
reject();
}
})
.catch((error) =>
{
console.log("error");
console.error(error);
reject();
});
*/
}); });
} }

View File

@ -26,7 +26,7 @@ if(process.browser)
export const getCalendar = ({ dispatch, date_from, date_to }) => export const getCalendar = ({ dispatch, date_from, date_to }) =>
{ {
console.log("getCalendar"); console.log("getCalendar", date_from, date_to);
return new Promise((resolve, reject) => return new Promise((resolve, reject) =>
{ {
axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/calendar`, {}, axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/calendar`, {},

View File

@ -6,6 +6,7 @@ import { nSQL } from "@nano-sql/core";
import * as actionTypes from '../constants/actionTypes'; import * as actionTypes from '../constants/actionTypes';
import * as currentState from '../reducers/initialState'; import * as currentState from '../reducers/initialState';
import { eachSeries } from 'async';
if(process.browser) if(process.browser)
{ {
@ -62,9 +63,10 @@ export const getContractInfo = ({ dispatch, number, }) =>
}) })
.then((response) => .then((response) =>
{ {
dispatch({ type: actionTypes.CONTRACT_DATE, data: { date: response.data.dl_date } }); const info = { date: response.data.dl_date, car: response.data.car };
dispatch({ type: actionTypes.CONTRACT_INFO, data: info });
resolve(); resolve(info);
}) })
.catch((error) => .catch((error) =>
{ {
@ -204,9 +206,75 @@ export const getContractDocuments = ({ dispatch, number, }) =>
{ {
withCredentials: true, withCredentials: true,
}) })
.then((response) => .then(async (response) =>
{ {
dispatch({ type: actionTypes.CONTRACT_DOCUMENTS, data: { documents: response.data } });
console.log("getDocuments", "response.data", response.data);
const documents = { upd: [], upd_avans: [], fines: [] };
await Promise.all([
new Promise((pr) =>
{
let query = nSQL(response.data.upd).query("select");
query = query.orderBy({ date: "desc" });
query.exec().then((rows) =>
{
documents.upd = rows;
pr();
});
}), new Promise((pr) =>
{
let query = nSQL(response.data.upd_avans).query("select");
query = query.orderBy({ date: "desc" });
query.exec().then((rows) =>
{
documents.upd_avans = rows;
pr();
});
}), new Promise((pr) =>
{
let query = nSQL(response.data.fines).query("select");
query = query.orderBy({ date: "desc" });
query.exec().then((rows) =>
{
documents.fines = rows;
pr();
});
})])
.then(() =>
{
console.log("documents");
console.log(documents);
dispatch({ type: actionTypes.CONTRACT_DOCUMENTS, data: { documents: documents } });
resolve();
});
})
.catch((error) =>
{
console.error(error);
reject();
});
});
}
export const getContractRules = ({ dispatch, date, }) =>
{
return new Promise((resolve, reject) =>
{
axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/contract/rules`, {
date: date
},
{
withCredentials: true,
})
.then(async (response) =>
{
console.log("getContractRules", "response.data", response.data);
dispatch({ type: actionTypes.CONTRACT_RULES, data: { rules: response.data.rules } });
resolve(); resolve();
}) })

View File

@ -41,8 +41,16 @@ export const getContractsList = ({ dispatch, order = "date", sort = "desc", page
orderBy[order] = sort; orderBy[order] = sort;
const offset = (page - 1) * page_size; const offset = (page - 1) * page_size;
let query = nSQL(response.data).query("select"); const contracts = [];
let query_total = nSQL(response.data).query("select", ["COUNT(*) AS total"]); for(let i in response.data)
{
const contract = response.data[i];
contract.js_date = moment(contract.date, "YYYY-MM-DD").toDate();
contracts.push(contract);
}
let query = nSQL(contracts).query("select");
let query_total = nSQL(contracts).query("select", ["COUNT(*) AS total"]);
if(search !== undefined && search !== null && search !== "") if(search !== undefined && search !== null && search !== "")
{ {
@ -50,13 +58,17 @@ export const getContractsList = ({ dispatch, order = "date", sort = "desc", page
query_total = query_total.where([["number", "LIKE", `%${ search }%`], "OR", ["car.reg_number", "LIKE", `%${ search }%`], "OR", ["car.vin_number", "LIKE", `%${ search }%`], "OR", ["car.brand.name", "LIKE", `%${ search }%`], "OR", ["car.model.name", "LIKE", `%${ search }%`]]) query_total = query_total.where([["number", "LIKE", `%${ search }%`], "OR", ["car.reg_number", "LIKE", `%${ search }%`], "OR", ["car.vin_number", "LIKE", `%${ search }%`], "OR", ["car.brand.name", "LIKE", `%${ search }%`], "OR", ["car.model.name", "LIKE", `%${ search }%`]])
} }
/*
if(date_from !== undefined && date_from !== null && date_from !== "") if(date_from !== undefined && date_from !== null && date_from !== "")
{ {
query = query.where([["date", ">=", `%${ date_from }%`]]); query = query.where([[ "js_date", ">=", date_from ]]);
query_total = query_total.where([["date", ">=", `%${ date_from }%`]]) query_total = query_total.where([[ "js_date", ">=", date_from ]])
}
if(date_to !== undefined && date_to !== null && date_to !== "")
{
query = query.where([[ "js_date", "<=", date_to ]]);
query_total = query_total.where([[ "js_date", "<=", date_to ]])
} }
*/
if(all) if(all)
{ {

View File

@ -92,4 +92,45 @@ export const getReconciliationFile = ({ contract, date_from, date_to, filename }
reject(); reject();
}); });
}); });
}
export const getBitrixFile = ({ url, filename }) =>
{
console.log("getFile");
return new Promise((resolve, reject) =>
{
axios.get(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/file/bitrix`, {
params: { url, },
responseType: 'blob',
})
.then((response) =>
{
fileDownload(response.data, filename);
resolve();
})
.catch((error) =>
{
console.log("error");
console.error(error);
reject();
});
/*
axios.get(`${ url }`, {
responseType: 'blob',
})
.then((response) =>
{
fileDownload(response.data, filename);
resolve();
})
.catch((error) =>
{
console.log("error");
console.error(error);
reject();
});
*/
});
} }

50
actions/formsActions.js Normal file
View File

@ -0,0 +1,50 @@
import axios from 'axios';
if(process.browser)
{
FormData.prototype.appendObject = function(obj, namespace)
{
let keyName;
for (var key in obj)
{
if (obj.hasOwnProperty(key))
{
keyName = [namespace, '[', key, ']'].join('');
this.append(keyName, obj[key]);
}
}
};
}
export const sendLeasingOrder = ({ name, phone, email, company }) =>
{
return new Promise((resolve, reject) =>
{
var formData = new FormData();
formData.append("form", "FORM_LEASING_REQUESTS");
formData.append("FORM_FIELD_FIO", name);
formData.append("FORM_FIELD_PHONE", phone);
formData.append("FORM_FIELD_EMAIL", email);
formData.append("FORM_FIELD_COMPANY", company);
formData.append("FORM_FIELD_PAGE_NAME", document.title);
formData.append("FORM_FIELD_PAGE_URL", window.location.href);
axios.post(`${ process.env.NEXT_PUBLIC_API_HOST }/api/forms/`, formData)
.then((response) =>
{
if(response.data.status === "complete")
{
resolve();
}
else
{
reject();
}
})
.catch((error) =>
{
console.error(error);
reject();
});
});
}

View File

@ -3,4 +3,6 @@ export * from './contractsActions';
export * from './contractActions'; export * from './contractActions';
export * from './calendarActions'; export * from './calendarActions';
export * from './companyActions'; export * from './companyActions';
export * from './fileActions'; export * from './fileActions';
export * from './navigationActions';
export * from './formsActions';

View File

@ -0,0 +1,33 @@
import axios from 'axios';
if(process.browser)
{
FormData.prototype.appendObject = function(obj, namespace)
{
let keyName;
for (var key in obj)
{
if (obj.hasOwnProperty(key))
{
keyName = [namespace, '[', key, ']'].join('');
this.append(keyName, obj[key]);
}
}
};
}
export const getPrograms = () =>
{
return new Promise((resolve, reject) =>
{
axios.get(`${ process.env.NEXT_PUBLIC_API_HOST }/api/programs/`)
.then((response) =>
{
resolve(response.data.programs);
})
.catch((error) =>
{
console.error(error);
});
});
}

View File

@ -4,11 +4,12 @@ export const COMPANY = 'COMPANY';
export const CONTRACTS = 'CONTRACTS'; export const CONTRACTS = 'CONTRACTS';
export const CONTRACT = 'CONTRACT'; export const CONTRACT = 'CONTRACT';
export const CONTRACT_PAYMENTS = 'CONTRACT_PAYMENTS'; export const CONTRACT_PAYMENTS = 'CONTRACT_PAYMENTS';
export const CONTRACT_DATE = 'CONTRACT_DATE'; export const CONTRACT_INFO = 'CONTRACT_INFO';
export const CONTRACT_INSURANCE = 'CONTRACT_INSURANCE'; export const CONTRACT_INSURANCE = 'CONTRACT_INSURANCE';
export const CONTRACT_HELPCARD = 'CONTRACT_HELPCARD'; export const CONTRACT_HELPCARD = 'CONTRACT_HELPCARD';
export const CONTRACT_REGISTRATION = 'CONTRACT_REGISTRATION'; export const CONTRACT_REGISTRATION = 'CONTRACT_REGISTRATION';
export const CONTRACT_TELEMATIC = 'CONTRACT_TELEMATIC'; export const CONTRACT_TELEMATIC = 'CONTRACT_TELEMATIC';
export const CONTRACT_AGREEMENT = 'CONTRACT_AGREEMENT'; export const CONTRACT_AGREEMENT = 'CONTRACT_AGREEMENT';
export const CONTRACT_DOCUMENTS = 'CONTRACT_DOCUMENTS'; export const CONTRACT_DOCUMENTS = 'CONTRACT_DOCUMENTS';
export const CONTRACT_RULES = 'CONTRACT_RULES';
export const CALENDAR = 'CALENDAR'; export const CALENDAR = 'CALENDAR';

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":3,"sources":["style.less"],"names":[],"mappings":"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"} {"version":3,"sources":["style.less"],"names":[],"mappings":"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"}

View File

@ -150,6 +150,11 @@ button,
background: url("/assets/images/icons/download_icon.svg") no-repeat center; background: url("/assets/images/icons/download_icon.svg") no-repeat center;
overflow: hidden; overflow: hidden;
text-indent: -999px; text-indent: -999px;
svg {
color: var(--blue) !important;
background: #fff;
}
} }
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -678,9 +678,22 @@
@media all and (max-width: 768px) { @media all and (max-width: 768px) {
width: ~"calc(50% - 4px)"; width: ~"calc(50% - 4px)";
} }
.date_input_wrapper {
> .rw-widget .rw-widget-container {
display: block;
> button {
margin: 0;
width: 100%;
}
}
}
} }
button { button.button {
margin-top: 35px; margin-top: 35px;
width: ~"calc(45% - 8px)"; width: ~"calc(45% - 8px)";
@ -720,7 +733,7 @@
width: 100%; width: 100%;
background: #fff; background: #fff;
margin: 100px auto; margin: 100px auto;
padding: 45px 80px; padding: 45px 40px;
.modal_footer { .modal_footer {
text-align: right; text-align: right;
@ -758,7 +771,7 @@
} }
} }
button { button.button {
margin-top: 15px; margin-top: 15px;
width: ~"calc(45% - 8px)"; width: ~"calc(45% - 8px)";
@ -796,7 +809,7 @@
width: 100%; width: 100%;
background: #fff; background: #fff;
margin: 100px auto; margin: 100px auto;
padding: 45px 80px; padding: 45px 40px;
.modal_footer { .modal_footer {
text-align: right; text-align: right;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,4 @@
main { main {
overflow: hidden;
padding-top: 112px; padding-top: 112px;
@media all and (max-width: 1280px) { @media all and (max-width: 1280px) {
@ -64,7 +63,11 @@ main {
.left { .left {
display: flex; display: flex;
max-width: 70%;
@media all and (max-width: 768px) {
max-width: none;
}
} }
.right { .right {
@ -1645,6 +1648,7 @@ main {
font-size: 26px; font-size: 26px;
line-height: 35px; line-height: 35px;
font-weight: 700; font-weight: 700;
min-width: 15%;
} }
ul { ul {
@ -1655,14 +1659,31 @@ main {
margin-bottom: 6px; margin-bottom: 6px;
} }
} }
@media all and (max-width: 767px) {
display: block;
.title {
font-size: 19px;
line-height: 26px;
}
ul {
margin-left: 0;
}
}
} }
} }
&.open { &.open {
.block_header { .block_header {
button { button:not(.rotate) {
background: url("/assets/images/icons/close-blue.svg") no-repeat center; background: url("/assets/images/icons/close-blue.svg") no-repeat center;
} }
button.rotate {
transform: rotate(180deg);
}
} }
.block_body { .block_body {
@ -2398,8 +2419,8 @@ main {
.table_cell { .table_cell {
padding: 16px 8px; padding: 16px 8px;
border: 1px solid #EDEFF5; border: 1px solid #EDEFF5;
width: 14%; width: 13%;
min-width: 14%; min-width: 13%;
&:nth-child(3) { &:nth-child(3) {
width: 16%; width: 16%;
@ -2407,7 +2428,8 @@ main {
} }
&:nth-child(5) { &:nth-child(5) {
word-break: break-all; //word-break: break-all;
width: 19%;
} }
p { p {
@ -2934,6 +2956,10 @@ main {
line-height: 28px; line-height: 28px;
text-align: right; text-align: right;
} }
&:disabled {
opacity: 0.3;
}
} }
} }
} }

View File

@ -38,4 +38,11 @@ q:before, q:after {
table { table {
border-collapse: collapse; border-collapse: collapse;
border-spacing: 0; border-spacing: 0;
} }
.bx-core main {
padding-top: 0;
}
.bx-core header {position: relative;}

View File

@ -1,302 +1 @@
:root { :root{--blue:#1C01A9;--blue-secondary:#85B2FC;--gray:#2C2D2E;--gray-light:rgba(0,16,61,0.06);--primary:#005FF9;--primary-light:rgba(0,95,249,0.1);--red:#ED0A34;--inactive:#EDEFF5;--green:#04A8A4;--text_not_active:#8E94A7}@media all and (max-width:1420px) and (min-width:1280px){html{zoom:.7}html .container,html .bx-breadcrumb{margin-left:auto;margin-right:auto}}body{font-size:15px;line-height:20px;color:#0C0C0C;font-family:'Montserrat',sans-serif;font-weight:400}@media all and (max-width:960px){body{font-size:13px;line-height:20px}}.container{padding-top:80px;padding-bottom:80px;width:100%;max-width:1310px;margin:auto;position:relative}.container:after{content:"";display:block;position:absolute;top:0;left:0;right:-4px;bottom:0;z-index:-1}@media all and (max-width:960px){.container{padding-top:40px;padding-bottom:40px}}.container.wide{max-width:1340px;padding-left:25px;padding-right:25px}@media all and (max-width:768px){.container.wide{padding-left:0;padding-right:0}}@media all and (max-width:1420px){.container{width:calc(100% - 160px);margin:0 80px}}@media all and (max-width:768px){.container{margin:0 16px;width:calc(100% - 32px)}}.aside_container{display:flex;justify-content:space-between}.aside_container aside{width:415px}@media all and (max-width:960px){.aside_container aside{width:100%}}.aside_container article{width:calc(100% - 550px)}.aside_container article:only-child{width:100%}.aside_container article .info_column{padding:20px 40px;display:flex;flex-wrap:wrap;justify-content:space-between;border-bottom:1px solid #EDEFF5}.aside_container article .info_column div{width:calc(50% - 55px)}@media all and (max-width:960px){.aside_container article .info_column{padding:0}.aside_container article .info_column div{width:100%}}@media all and (max-width:960px){.aside_container article{width:100%}.aside_container article .info_column{padding:25px 0}}.aside_container.about aside{width:305px}.aside_container.about article{width:calc(100% - 335px)}@media all and (max-width:1280px){.aside_container.about{display:block}.aside_container.about aside,.aside_container.about article{width:100%}}.section_title{font-size:50px;line-height:60px;font-weight:700;color:#0C0C0C;margin-bottom:35px}.section_title.no-margin{margin-bottom:0}@media all and (max-width:1279px){.section_title{font-size:32px;line-height:44px}}@media all and (max-width:960px){.section_title{font-size:22px;line-height:33px}}@media all and (max-width:768px){.section_title{margin-bottom:25px}}h1{font-size:32px;line-height:40px}h2{font-size:24px;line-height:28px;margin-top:1.5em;margin-bottom:10px}h2.model{font-size:26px;line-height:35px;color:var(--text_not_active);margin-top:0;margin-bottom:0}@media all and (max-width:768px){h2.model{font-size:19px;line-height:26px}}h2:first-child{margin-top:0}h3{font-size:17px;line-height:24px;margin-top:1.5em;margin-bottom:10px}h3:first-child{margin-top:0}h4{font-size:15px;line-height:20px;margin-top:1.5em;margin-bottom:10px}h4:first-child{margin-top:0}.secondary{font-size:13px;line-height:20px}.secondary.not_active{color:#8E94A7}@media all and (max-width:960px){.secondary{font-size:10px;line-height:15px}}b,strong{font-weight:700}p.primary{color:var(--blue)}a{text-decoration:none;color:var(--blue)}div{box-sizing:border-box}.clear{display:block;clear:both}@media all and (max-width:736px){h1{font-size:24px;line-height:32px}h2{font-size:20px;line-height:24px}}.i-phone{padding-left:28px;background:url("/assets/images/icons/icon-phone-hot.svg") no-repeat 0 2px}.i-phone-secondary{padding-left:28px;background:url("/assets/images/icons/icon-phone-secondary.svg") no-repeat 0 2px}.i-address{padding-left:28px;background:url("/assets/images/icons/icon-address.svg") no-repeat 0 2px}.i-worktime{padding-left:28px;background:url("/assets/images/icons/icon-worktime.svg") no-repeat 0 2px}.i-pdf{padding-left:80px;background:url("/assets/images/icons/icon-pdf.svg") no-repeat left center}@media all and (max-width:960px){.i-pdf{padding-left:55px;background-size:32px;background-position:0 5px}}.i-doc{padding-left:80px;background:url("/assets/images/icons/icon-doc.svg") no-repeat left center;background-size:56px}@media all and (max-width:960px){.i-doc{padding-left:55px;background-size:32px;background-position:0 5px}}.success{color:var(--green)}.danger{color:var(--red)}@media all and (max-width:768px){::-webkit-scrollbar{display:none}}/*# sourceMappingURL=./var.css.map */
--blue: #1C01A9;
--blue-secondary: #85B2FC;
--gray: #2C2D2E;
--gray-light: rgba(0, 16, 61, 0.06);
--primary: #005FF9;
--primary-light: rgba(0, 95, 249, 0.1);
--red: #ED0A34;
--inactive: #EDEFF5;
--green: #04A8A4;
--text_not_active: #8E94A7;
}
body {
font-size: 15px;
line-height: 20px;
color: #0C0C0C;
font-family: 'Montserrat', sans-serif;
font-weight: 400;
}
@media all and (max-width: 960px) {
body {
font-size: 13px;
line-height: 20px;
}
}
.container {
padding-top: 80px;
padding-bottom: 80px;
width: 100%;
max-width: 1310px;
margin: auto;
position: relative;
}
.container:after {
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
right: -4px;
bottom: 0;
z-index: -1;
/*
background: repeating-linear-gradient(
90deg,
#fff,
#EDEFF5 1px,
transparent 0px,
transparent 25%);
background: repeating-linear-gradient(to right, transparent 1px, transparent calc(25% - 1px), #EDEFF5 25%, #EDEFF5 25%);
*/
}
@media all and (max-width: 960px) {
.container {
padding-top: 40px;
padding-bottom: 40px;
}
}
.container.wide {
max-width: 1340px;
padding-left: 25px;
padding-right: 25px;
}
@media all and (max-width: 768px) {
.container.wide {
padding-left: 0;
padding-right: 0;
}
}
@media all and (max-width: 1420px) {
.container {
width: calc(100% - 160px);
margin: 0 80px;
}
}
@media all and (max-width: 768px) {
.container {
margin: 0 16px;
width: calc(100% - 32px);
}
}
.aside_container {
display: flex;
justify-content: space-between;
}
.aside_container aside {
width: 415px;
}
@media all and (max-width: 960px) {
.aside_container aside {
width: 100%;
}
}
.aside_container article {
width: calc(100% - 550px);
}
.aside_container article:only-child {
width: 100%;
}
.aside_container article .info_column {
padding: 20px 40px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
border-bottom: 1px solid #EDEFF5;
}
.aside_container article .info_column div {
width: calc(50% - 55px);
}
@media all and (max-width: 960px) {
.aside_container article .info_column {
padding: 0;
}
.aside_container article .info_column div {
width: 100%;
}
}
@media all and (max-width: 960px) {
.aside_container article {
width: 100%;
}
.aside_container article .info_column {
padding: 25px 0;
}
}
.aside_container.about aside {
width: 305px;
}
.aside_container.about article {
width: calc(100% - 335px);
}
@media all and (max-width: 1280px) {
.aside_container.about {
display: block;
}
.aside_container.about aside,
.aside_container.about article {
width: 100%;
}
}
.section_title {
font-size: 50px;
line-height: 60px;
font-weight: 700;
color: #0C0C0C;
margin-bottom: 35px;
}
.section_title.no-margin {
margin-bottom: 0;
}
@media all and (max-width: 1279px) {
.section_title {
font-size: 32px;
line-height: 44px;
}
}
@media all and (max-width: 960px) {
.section_title {
font-size: 22px;
line-height: 33px;
}
}
@media all and (max-width: 768px) {
.section_title {
margin-bottom: 25px;
}
}
h1 {
font-size: 32px;
line-height: 40px;
}
h2 {
font-size: 24px;
line-height: 28px;
margin-top: 1.5em;
margin-bottom: 10px;
}
h2.model {
font-size: 26px;
line-height: 35px;
color: var(--text_not_active);
margin-top: 0;
margin-bottom: 0;
}
@media all and (max-width: 768px) {
h2.model {
font-size: 19px;
line-height: 26px;
}
}
h2:first-child {
margin-top: 0;
}
h3 {
font-size: 17px;
line-height: 24px;
margin-top: 1.5em;
margin-bottom: 10px;
}
h3:first-child {
margin-top: 0;
}
h4 {
font-size: 15px;
line-height: 20px;
margin-top: 1.5em;
margin-bottom: 10px;
}
h4:first-child {
margin-top: 0;
}
.secondary {
font-size: 13px;
line-height: 20px;
}
.secondary.not_active {
color: #8E94A7;
}
@media all and (max-width: 960px) {
.secondary {
font-size: 10px;
line-height: 15px;
}
}
b,
strong {
font-weight: 700;
}
p.primary {
color: var(--blue);
}
a {
text-decoration: none;
color: var(--blue);
}
div {
box-sizing: border-box;
}
.clear {
display: block;
clear: both;
}
@media all and (max-width: 736px) {
h1 {
font-size: 24px;
line-height: 32px;
}
h2 {
font-size: 20px;
line-height: 24px;
}
}
.i-phone {
padding-left: 28px;
background: url("/assets/images/icons/icon-phone-hot.svg") no-repeat 0 2px;
}
.i-phone-secondary {
padding-left: 28px;
background: url("/assets/images/icons/icon-phone-secondary.svg") no-repeat 0 2px;
}
.i-address {
padding-left: 28px;
background: url("/assets/images/icons/icon-address.svg") no-repeat 0 2px;
}
.i-worktime {
padding-left: 28px;
background: url("/assets/images/icons/icon-worktime.svg") no-repeat 0 2px;
}
.i-pdf {
padding-left: 80px;
background: url("/assets/images/icons/icon-pdf.svg") no-repeat left center;
}
@media all and (max-width: 960px) {
.i-pdf {
padding-left: 55px;
background-size: 32px;
background-position: 0 5px;
}
}
.i-doc {
padding-left: 80px;
background: url("/assets/images/icons/icon-doc.svg") no-repeat left center;
background-size: 56px;
}
@media all and (max-width: 960px) {
.i-doc {
padding-left: 55px;
background-size: 32px;
background-position: 0 5px;
}
}
.success {
color: var(--green);
}
.danger {
color: var(--red);
}
@media all and (max-width: 768px) {
::-webkit-scrollbar {
display: none;
}
}

View File

@ -1 +1 @@
{"version":3,"sources":["var.less"],"names":[],"mappings":"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"} {"version":3,"sources":["var.less"],"names":[],"mappings":"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"}

View File

@ -11,6 +11,17 @@
--text_not_active: #8E94A7; --text_not_active: #8E94A7;
} }
html {
@media all and (max-width: 1420px) and (min-width: 1280px) {
zoom: 0.7;
.container, .bx-breadcrumb {
margin-left: auto;
margin-right: auto;
}
}
}
body { body {
font-size: 15px; font-size: 15px;
line-height: 20px; line-height: 20px;

43
lib/SmsCenter/index.js Normal file
View File

@ -0,0 +1,43 @@
const axios = require('axios');
const qs = require('qs');
const SMS_API_HOST = "https://smsc.ru/sys/send.php";
class SmsCenter
{
static send(phoneNumber, code)
{
console.log("SmsCenter", "propagateUser");
return new Promise((resolve, reject) =>
{
const packet = qs.stringify({
login: process.env.SMSC_LOGIN,
psw: process.env.SMSC_PASSWORD,
sender: "Evoleasing",
phones: `+${ phoneNumber }`,
mes: `Код верификации ЛК: ${ code }`,
charset: 'utf-8',
fmt: 3,
});
console.log(packet);
axios.post(SMS_API_HOST, packet, {
"Content-Type": "application/x-www-form-urlencoded"
})
.then((smsSendResponse) =>
{
console.log(smsSendResponse.data);
resolve();
})
.catch((smsSendError) =>
{
console.error(smsSendError);
reject();
});
})
}
}
module.exports = SmsCenter;

View File

@ -14,8 +14,10 @@
"axios": "^0.24.0", "axios": "^0.24.0",
"cookie": "^0.4.1", "cookie": "^0.4.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"ioredis": "^4.28.2",
"js-file-download": "^0.4.12", "js-file-download": "^0.4.12",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"md5": "^2.3.0",
"moment": "^2.29.1", "moment": "^2.29.1",
"next": "11.1.2", "next": "11.1.2",
"next-fonts": "^1.5.1", "next-fonts": "^1.5.1",
@ -24,6 +26,8 @@
"next-with-less": "^1.0.1", "next-with-less": "^1.0.1",
"nextjs-cors": "^2.1.0", "nextjs-cors": "^2.1.0",
"numeral": "^2.0.6", "numeral": "^2.0.6",
"pluralize-ru": "^1.0.1",
"qs": "^6.10.1",
"react": "17.0.2", "react": "17.0.2",
"react-cookie": "^4.1.1", "react-cookie": "^4.1.1",
"react-dom": "17.0.2", "react-dom": "17.0.2",

View File

@ -1,5 +0,0 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}

View File

@ -0,0 +1,73 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import axios from 'axios';
import { Cookies } from 'react-cookie';
import cookie from 'cookie';
import moment from 'moment';
import jwt from 'jsonwebtoken';
import Redis from 'ioredis';
import md5 from 'md5';
import { cors } from '../../../../lib/cors';
const SmsCenter = require('../../../../lib/SmsCenter');
const redis = new Redis(process.env.REDIS_URL);
export default async function handler(req, res)
{
await cors(req, res);
const { phone } = req.body;
const response = await new Promise((resolve, reject) =>
{
console.log("POST", `${ process.env.NEXT_PUBLIC_API_HOST }/api/account/auth/phone/`);
axios.post(`${ process.env.NEXT_PUBLIC_API_HOST }/api/account/auth/phone/`, {
phone: phone,
})
.then((api_response) =>
{
console.log("RESPONSE");
console.log(api_response.data);
resolve(api_response.data);
})
.catch((error) =>
{
console.log("error");
console.error(error);
reject();
});
});
console.log("CHECK response");
console.log(response);
console.log("-".repeat(50));
if(response.status === "success")
{
let code = ``;
for(let i = 0; i < 6; i++) { code = `${code}${Math.floor(Math.random()*10)}`; }
response.code = code;
const key = md5(`sms_code_${ phone }`);
await redis.set(key, JSON.stringify(response), 'EX', 300);
const smsResult = await SmsCenter.send(phone, code)
.then(() =>
{
res.status(200).json({
status: "success",
});
})
.catch((error) =>
{
console.error("SmsCenter.send", "catch");
res.status(404).json();
});
}
else
{
res.status(404).json();
}
}

View File

@ -0,0 +1,45 @@
import axios from 'axios';
import { Cookies } from 'react-cookie';
import cookie from 'cookie';
import moment from 'moment';
import jwt from 'jsonwebtoken';
import Redis from 'ioredis';
import md5 from 'md5';
import { cors } from '../../../../lib/cors';
const redis = new Redis(process.env.REDIS_URL);
export default async function handler(req, res)
{
await cors(req, res);
const { phone, code } = req.body;
let token = "";
const key = md5(`sms_code_${ phone }`);
let existed_data = await redis.get(key);
if(existed_data !== null)
{
const existed_data_json = JSON.parse(existed_data);
if(existed_data_json.code === code)
{
console.log("existed_data_json");
console.log(existed_data_json);
console.log("*".repeat(50));
token = jwt.sign({ "acc_number": existed_data_json.acc_number, }, process.env.JWT_SECRET_CLIENT, { noTimestamp: true });
res.status(200).json({ ...existed_data_json, ...{ status: "success", token: token, } });
}
else
{
res.status(403).json();
}
}
else
{
res.status(403).json();
}
}

View File

@ -19,8 +19,9 @@ export default async function handler(req, res)
var crm_jwt = jwt.sign(client_jwt_decoded, process.env.JWT_SECRET_CRM, { noTimestamp: true }); var crm_jwt = jwt.sign(client_jwt_decoded, process.env.JWT_SECRET_CRM, { noTimestamp: true });
const result = { const result = {
upd: null, upd: [],
fines: null, upd_avans: [],
fines: [],
}; };
await Promise.all([ await Promise.all([
@ -29,7 +30,23 @@ export default async function handler(req, res)
params: { ...client_jwt_decoded, contract_number: req.body.number }, params: { ...client_jwt_decoded, contract_number: req.body.number },
headers: { "Authorization": `Bearer ${ crm_jwt }`, }, headers: { "Authorization": `Bearer ${ crm_jwt }`, },
}) })
.then((crm_response) => { result.upd = crm_response.data; resolve(); }) .then((crm_response) =>
{
for(let i in crm_response.data)
{
console.log("docs".repeat(10));
console.log(crm_response.data[i]);
if(crm_response.data[i].upd !== undefined)
{
result.upd = crm_response.data[i].upd;
}
if(crm_response.data[i].upd_avans !== undefined)
{
result.upd_avans = crm_response.data[i];
}
}
resolve();
})
.catch((error) => { console.error(error); resolve(); }); .catch((error) => { console.error(error); resolve(); });
}), }),
new Promise((resolve) => { new Promise((resolve) => {

View File

@ -42,7 +42,7 @@ export default async function handler(req, res)
.then((crm_response) => .then((crm_response) =>
{ {
console.log("crm_response"); console.log("crm_response");
console.log(crm_response); //console.log(crm_response);
res.status(200).json(crm_response.data); res.status(200).json(crm_response.data);
}) })
.catch((error) => .catch((error) =>

View File

@ -18,7 +18,25 @@ export default async function handler(req, res)
var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT); var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT);
var crm_jwt = jwt.sign(client_jwt_decoded, process.env.JWT_SECRET_CRM, { noTimestamp: true }); var crm_jwt = jwt.sign(client_jwt_decoded, process.env.JWT_SECRET_CRM, { noTimestamp: true });
res.status(200).json(null); const response = await new Promise((resolve) =>
{
axios.get(`${ process.env.CRM_API_HOST }/lk/Contract/GetRegistration`, {
params: { ...client_jwt_decoded, contract_number: req.body.number },
headers: { "Authorization": `Bearer ${ crm_jwt }`, },
withCredentials: true,
})
.then((crm_response) =>
{
resolve(crm_response.data);
})
.catch((error) =>
{
console.error(error);
resolve(error);
});
});
res.status(200).json(response);
} }
else else
{ {

View File

@ -0,0 +1,53 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import axios from 'axios';
import { Cookies } from 'react-cookie';
import cookie from 'cookie';
import moment from 'moment';
import jwt from 'jsonwebtoken';
import { cors } from '../../../lib/cors';
export default async function handler(req, res)
{
await cors(req, res);
if(req.headers.cookie !== undefined)
{
const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : "");
if(cookies.jwt !== undefined && cookies.jwt !== null)
{
if(jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT))
{
const response = await new Promise((resolve, reject) =>
{
axios.post(`${ process.env.NEXT_PUBLIC_API_HOST }/api/account/rules/`, {
date: req.body.date,
})
.then((api_response) =>
{
console.log("RESPONSE");
console.log(api_response.data);
resolve(api_response.data);
})
.catch((error) =>
{
console.log("error");
console.error(error);
reject([]);
});
});
res.status(200).json(response);
}
else
{
res.status(403);
}
}
else
{
res.status(403);
}
}
}

View File

@ -18,7 +18,25 @@ export default async function handler(req, res)
var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT); var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT);
var crm_jwt = jwt.sign(client_jwt_decoded, process.env.JWT_SECRET_CRM, { noTimestamp: true }); var crm_jwt = jwt.sign(client_jwt_decoded, process.env.JWT_SECRET_CRM, { noTimestamp: true });
res.status(200).json(null); const response = await new Promise((resolve) =>
{
axios.get(`${ process.env.CRM_API_HOST }/lk/Contract/GetTelematics`, {
params: { ...client_jwt_decoded, contract_number: req.body.number },
headers: { "Authorization": `Bearer ${ crm_jwt }`, },
withCredentials: true,
})
.then((crm_response) =>
{
resolve(crm_response.data);
})
.catch((error) =>
{
console.error(error);
resolve(error);
});
});
res.status(200).json(response);
} }
else else
{ {

48
pages/api/file/bitrix.js Normal file
View File

@ -0,0 +1,48 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import axios from 'axios';
import { Cookies } from 'react-cookie';
import cookie from 'cookie';
import moment from 'moment';
import jwt from 'jsonwebtoken';
import { cors } from '../../../lib/cors';
export default async function handler(req, res)
{
await cors(req, res);
if(req.headers.cookie !== undefined)
{
const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : "");
if(cookies.jwt !== undefined && cookies.jwt !== null)
{
if(jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT))
{
try
{
axios.get(req.query.url, {
responseType: 'arraybuffer',
})
.then((bitrix_response) =>
{
res.status(200).send(bitrix_response.data);
})
.catch((error) =>
{
console.error(error);
res.status(500);
});
}
catch(e)
{
console.error(e);
res.status(500);
}
}
}
else
{
res.status(403);
}
}
}

View File

@ -1,5 +0,0 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}

View File

@ -0,0 +1,14 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import axios from 'axios';
import { Cookies } from 'react-cookie';
import cookie from 'cookie';
import moment from 'moment';
import jwt from 'jsonwebtoken';
//import { cors } from '../../lib/cors';
export default async function handler(req, res)
{
//await cors(req, res);
res.status(200);
}

View File

@ -2,8 +2,27 @@ import React from "react";
import DatePicker from "react-widgets/DatePicker"; import DatePicker from "react-widgets/DatePicker";
import "react-widgets/styles.css"; import "react-widgets/styles.css";
const messages = {
moveToday: "Сегодня",
moveBack: "Назад",
moveForward: "Вперед",
dateButton: "Выбрать дату",
};
const formats = [
'DD.MM.YYYY'
];
export default class DateInput extends React.Component export default class DateInput extends React.Component
{ {
constructor(props)
{
super(props);
this.state = {
readonly: true,
}
}
_handle_onChange = (date) => _handle_onChange = (date) =>
{ {
if(this.props.onChange !== undefined) if(this.props.onChange !== undefined)
@ -12,11 +31,26 @@ export default class DateInput extends React.Component
} }
} }
_handle_onFocus = () =>
{
console.log("F");
this.setState({ readonly: false });
}
_handle_onBlur = () =>
{
console.log("B");
this.setState({ readonly: true });
}
render() render()
{ {
return ( const { id, placeholder, value, min, max } = this.props;
const { readonly } = this.state;
return (
<div className="date_input_wrapper"> <div className="date_input_wrapper">
<DatePicker placeholder={ this.props.placeholder } value={ this.props.value } onChange={ this._handle_onChange }/> <DatePicker messages={ messages } onFocus={ this._handle_onFocus } onBlur={ this._handle_onBlur } parse={ formats } id={ id } placeholder={ placeholder } value={ value } min={ min } max={ max } onChange={ this._handle_onChange }/>
</div> </div>
) )
} }

View File

@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import { SpinnerCircular } from 'spinners-react'; import { SpinnerCircular } from 'spinners-react';
import { getFile } from "../../../actions"; import { getFile, getBitrixFile } from "../../../actions";
export default class DownloadPdfButton extends React.Component export default class DownloadPdfButton extends React.Component
{ {
@ -15,22 +15,25 @@ export default class DownloadPdfButton extends React.Component
_handle_onDownloadFile = () => _handle_onDownloadFile = () =>
{ {
const { id, filename } = this.props; const { id, filename, url, bitrix } = this.props;
const { downloading } = this.state; const { downloading } = this.state;
if(!downloading) if(!downloading)
{ {
this.setState({ downloading: true }, () => this.setState({ downloading: true }, () =>
{ {
getFile({ id, filename }) if(bitrix)
.then(() =>
{ {
this.setState({ downloading: false }); getBitrixFile({ url, filename })
}) .then(() => { this.setState({ downloading: false }); })
.catch(() => .catch(() => { this.setState({ downloading: false }); });
}
else
{ {
this.setState({ downloading: false }); getFile({ id, filename })
}); .then(() => { this.setState({ downloading: false }); })
.catch(() => { this.setState({ downloading: false }); });
}
}); });
} }
} }

View File

@ -40,7 +40,7 @@ export default class DownloadPrintFormPdfButton extends React.Component
const { downloading } = this.state; const { downloading } = this.state;
return ( return (
<a style={{ cursor: "pointer" }} className="button button-blue" onClick={ () => { this._handle_onDownloadFile() }}> <a style={{ cursor: "pointer" }} className={this.props.className + " button button-blue"} onClick={ () => { this._handle_onDownloadFile() }}>
{ downloading ? ( { downloading ? (
<SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" /> <SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" />
) : "Скачать" } ) : "Скачать" }

View File

@ -1,134 +1,128 @@
import React from "react";
import Link from "next/link"; import Link from "next/link";
import axios from 'axios';
import { getPrograms } from "../../../actions";
export default function Footer() export default class Footer extends React.Component
{ {
return ( constructor(props)
<footer> {
<div className="container"> super(props);
<ul className="column"> this.state = {
<li><b>Программы</b></li> programs: [],
<li> }
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/lizing_dlja_ul_i_ip`}> }
<a>Лизинг для ЮЛ и ИП</a>
</Link> componentDidMount()
</li> {
<li> getPrograms().then((programs) => this.setState({ programs: programs })).catch(() => {});
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/legkovye_avtomobili`}> }
<a>Легковые автомобили</a>
</Link> render()
</li> {
<li> const { programs } = this.state;
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/legkij_kommercheskij_transport`}>
<a>Легкий коммерческий транспорт</a> return (
</Link> <footer>
</li> <div className="container">
<li> <ul className="column">
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/gruzovoj_transport`}> <li><b>Программы</b></li>
<a>Грузовой транспорт</a> { programs.map((program, index) => (
</Link> <li key={ index }>
</li> <Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/${ program.code }/`}>
<li> <a>{ program.name }</a>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/spectehnika`}> </Link>
<a>Спецтехника</a> </li>
</Link> ))}
</li> </ul>
<li> <ul className="column">
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/lizing_taksi`}> <li><b>Каталог техники</b></li>
<a>Лизинг такси</a> <li>
</Link> <Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/catalog/`}>
</li> <a>Легковые</a>
<li> </Link>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/lizing_avto_s_probegomja`}> </li>
<a>Лизинг авто с пробегом</a> {/*}
</Link> <li>
</li> <Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/catalog/legkij_kommercheskij_transport`}>
</ul> <a>Легкий коммерческий транспорт</a>
<ul className="column"> </Link>
<li><b>Каталог техники</b></li> </li>
<li> {*/}
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/catalog/legkovye`}> </ul>
<a>Легковые</a> <ul className="column">
</Link> <li><b>О компании</b></li>
</li> <li>
<li> <Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/news`}>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/catalog/legkij_kommercheskij_transport`}> <a>Новости</a>
<a>Легкий коммерческий транспорт</a> </Link>
</Link> </li>
</li> <li>
</ul> <Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/career`}>
<ul className="column"> <a>Карьера</a>
<li><b>О компании</b></li> </Link>
<li> </li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/news`}> <li>
<a>Новости</a> <Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/contacts`}>
</Link> <a>Контакты</a>
</li> </Link>
<li> </li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/career`}> <li>
<a>Карьера</a> <Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/requisites`}>
</Link> <a>Реквизиты</a>
</li> </Link>
<li> </li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/contacts`}> <li>
<a>Контакты</a> <Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/rules`}>
</Link> <a>Общие условия лизинга</a>
</li> </Link>
<li> </li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/requisites`}> <li>
<a>Реквизиты</a> <Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/revocation`}>
</Link> <a>Отзыв доверенности</a>
</li> </Link>
<li> </li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/rules`}> </ul>
<a>Общие условия лизинга</a> <div className="column">
</Link> <div>
</li> <a href="mailto:">info@evoleasing.ru</a>
<li> </div>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/retmination`}> <div>
<a>Отзыв доверенности</a> <a href="tel:88003337575">8 800 333 75 75</a>
</Link> </div>
</li> <div className="socials">
</ul> <a href="https://www.instagram.com/evoleasing/" target="_blank" rel="nofollow noopener">
<div className="column">
<div>
<a href="mailto:">info@evoleasing.ru</a>
</div>
<div>
<a href="tel:">8 800 333 75 75</a>
</div>
<div className="socials">
<Link href="#">
<a>
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path <path
d="M16.0003 4.36377C12.8401 4.36377 12.4435 4.37759 11.2023 4.43407C9.9636 4.4908 9.11805 4.68692 8.37819 4.97468C7.61288 5.27189 6.96369 5.66947 6.31692 6.3165C5.66967 6.96328 5.2721 7.6125 4.97393 8.37759C4.68545 9.11771 4.4891 9.96353 4.43334 11.2018C4.37783 12.443 4.36328 12.8399 4.36328 16.0001C4.36328 19.1604 4.37734 19.5558 4.43358 20.797C4.49055 22.0358 4.68667 22.8813 4.97417 23.6212C5.27162 24.3866 5.66918 25.0358 6.31619 25.6826C6.96272 26.3298 7.61191 26.7284 8.37673 27.0256C9.11708 27.3133 9.96287 27.5095 11.2014 27.5662C12.4426 27.6227 12.8389 27.6365 15.9988 27.6365C19.1592 27.6365 19.5546 27.6227 20.7958 27.5662C22.0345 27.5095 22.881 27.3133 23.6214 27.0256C24.3864 26.7284 25.0347 26.3298 25.6812 25.6826C26.3284 25.0358 26.726 24.3866 27.0242 23.6215C27.3102 22.8813 27.5066 22.0355 27.5648 20.7972C27.6205 19.556 27.6351 19.1604 27.6351 16.0001C27.6351 12.8399 27.6205 12.4433 27.5648 11.2021C27.5066 9.96328 27.3102 9.11771 27.0242 8.37783C26.726 7.6125 26.3284 6.96328 25.6812 6.3165C25.0339 5.66922 24.3867 5.27165 23.6206 4.97468C22.8788 4.68692 22.0328 4.4908 20.7941 4.43407C19.5529 4.37759 19.1577 4.36377 15.9966 4.36377H16.0003ZM14.9564 6.46074C15.2662 6.46025 15.6119 6.46074 16.0003 6.46074C19.1071 6.46074 19.4753 6.47189 20.7022 6.52765C21.8367 6.57953 22.4524 6.7691 22.8626 6.92838C23.4056 7.13928 23.7928 7.39141 24.1998 7.79868C24.607 8.20595 24.8591 8.59383 25.0705 9.13686C25.2298 9.54656 25.4196 10.1623 25.4712 11.2969C25.527 12.5235 25.5391 12.892 25.5391 15.9975C25.5391 19.1029 25.527 19.4714 25.4712 20.6981C25.4194 21.8326 25.2298 22.4484 25.0705 22.8581C24.8596 23.4011 24.607 23.7878 24.1998 24.1948C23.7925 24.6021 23.4059 24.8542 22.8626 25.0651C22.4529 25.2251 21.8367 25.4142 20.7022 25.4661C19.4755 25.5218 19.1071 25.5339 16.0003 25.5339C12.8932 25.5339 12.525 25.5218 11.2983 25.4661C10.1638 25.4137 9.54809 25.2241 9.13768 25.0649C8.59467 24.8539 8.2068 24.6018 7.79954 24.1946C7.39228 23.7873 7.14017 23.4004 6.92878 22.8571C6.76951 22.4474 6.5797 21.8316 6.52806 20.6971C6.47231 19.4704 6.46116 19.1019 6.46116 15.9946C6.46116 12.8872 6.47231 12.5206 6.52806 11.294C6.57994 10.1594 6.76951 9.54365 6.92878 9.13347C7.13968 8.59044 7.39228 8.20256 7.79954 7.79528C8.2068 7.38801 8.59467 7.13589 9.13768 6.9245C9.54785 6.7645 10.1638 6.57541 11.2983 6.52328C12.3718 6.4748 12.7878 6.46025 14.9564 6.45783V6.46074ZM22.2115 8.39286C21.4406 8.39286 20.8151 9.01759 20.8151 9.78874C20.8151 10.5596 21.4406 11.1851 22.2115 11.1851C22.9824 11.1851 23.6078 10.5596 23.6078 9.78874C23.6078 9.01783 22.9824 8.39237 22.2115 8.39237V8.39286ZM16.0003 10.0244C12.7002 10.0244 10.0247 12.7 10.0247 16.0001C10.0247 19.3003 12.7002 21.9747 16.0003 21.9747C19.3003 21.9747 21.9749 19.3003 21.9749 16.0001C21.9749 12.7 19.3 10.0244 16 10.0244H16.0003ZM16.0003 12.1213C18.1423 12.1213 19.8789 13.8578 19.8789 16.0001C19.8789 18.1422 18.1423 19.8789 16.0003 19.8789C13.858 19.8789 12.1216 18.1422 12.1216 16.0001C12.1216 13.8578 13.858 12.1213 16.0003 12.1213Z" d="M16.0003 4.36377C12.8401 4.36377 12.4435 4.37759 11.2023 4.43407C9.9636 4.4908 9.11805 4.68692 8.37819 4.97468C7.61288 5.27189 6.96369 5.66947 6.31692 6.3165C5.66967 6.96328 5.2721 7.6125 4.97393 8.37759C4.68545 9.11771 4.4891 9.96353 4.43334 11.2018C4.37783 12.443 4.36328 12.8399 4.36328 16.0001C4.36328 19.1604 4.37734 19.5558 4.43358 20.797C4.49055 22.0358 4.68667 22.8813 4.97417 23.6212C5.27162 24.3866 5.66918 25.0358 6.31619 25.6826C6.96272 26.3298 7.61191 26.7284 8.37673 27.0256C9.11708 27.3133 9.96287 27.5095 11.2014 27.5662C12.4426 27.6227 12.8389 27.6365 15.9988 27.6365C19.1592 27.6365 19.5546 27.6227 20.7958 27.5662C22.0345 27.5095 22.881 27.3133 23.6214 27.0256C24.3864 26.7284 25.0347 26.3298 25.6812 25.6826C26.3284 25.0358 26.726 24.3866 27.0242 23.6215C27.3102 22.8813 27.5066 22.0355 27.5648 20.7972C27.6205 19.556 27.6351 19.1604 27.6351 16.0001C27.6351 12.8399 27.6205 12.4433 27.5648 11.2021C27.5066 9.96328 27.3102 9.11771 27.0242 8.37783C26.726 7.6125 26.3284 6.96328 25.6812 6.3165C25.0339 5.66922 24.3867 5.27165 23.6206 4.97468C22.8788 4.68692 22.0328 4.4908 20.7941 4.43407C19.5529 4.37759 19.1577 4.36377 15.9966 4.36377H16.0003ZM14.9564 6.46074C15.2662 6.46025 15.6119 6.46074 16.0003 6.46074C19.1071 6.46074 19.4753 6.47189 20.7022 6.52765C21.8367 6.57953 22.4524 6.7691 22.8626 6.92838C23.4056 7.13928 23.7928 7.39141 24.1998 7.79868C24.607 8.20595 24.8591 8.59383 25.0705 9.13686C25.2298 9.54656 25.4196 10.1623 25.4712 11.2969C25.527 12.5235 25.5391 12.892 25.5391 15.9975C25.5391 19.1029 25.527 19.4714 25.4712 20.6981C25.4194 21.8326 25.2298 22.4484 25.0705 22.8581C24.8596 23.4011 24.607 23.7878 24.1998 24.1948C23.7925 24.6021 23.4059 24.8542 22.8626 25.0651C22.4529 25.2251 21.8367 25.4142 20.7022 25.4661C19.4755 25.5218 19.1071 25.5339 16.0003 25.5339C12.8932 25.5339 12.525 25.5218 11.2983 25.4661C10.1638 25.4137 9.54809 25.2241 9.13768 25.0649C8.59467 24.8539 8.2068 24.6018 7.79954 24.1946C7.39228 23.7873 7.14017 23.4004 6.92878 22.8571C6.76951 22.4474 6.5797 21.8316 6.52806 20.6971C6.47231 19.4704 6.46116 19.1019 6.46116 15.9946C6.46116 12.8872 6.47231 12.5206 6.52806 11.294C6.57994 10.1594 6.76951 9.54365 6.92878 9.13347C7.13968 8.59044 7.39228 8.20256 7.79954 7.79528C8.2068 7.38801 8.59467 7.13589 9.13768 6.9245C9.54785 6.7645 10.1638 6.57541 11.2983 6.52328C12.3718 6.4748 12.7878 6.46025 14.9564 6.45783V6.46074ZM22.2115 8.39286C21.4406 8.39286 20.8151 9.01759 20.8151 9.78874C20.8151 10.5596 21.4406 11.1851 22.2115 11.1851C22.9824 11.1851 23.6078 10.5596 23.6078 9.78874C23.6078 9.01783 22.9824 8.39237 22.2115 8.39237V8.39286ZM16.0003 10.0244C12.7002 10.0244 10.0247 12.7 10.0247 16.0001C10.0247 19.3003 12.7002 21.9747 16.0003 21.9747C19.3003 21.9747 21.9749 19.3003 21.9749 16.0001C21.9749 12.7 19.3 10.0244 16 10.0244H16.0003ZM16.0003 12.1213C18.1423 12.1213 19.8789 13.8578 19.8789 16.0001C19.8789 18.1422 18.1423 19.8789 16.0003 19.8789C13.858 19.8789 12.1216 18.1422 12.1216 16.0001C12.1216 13.8578 13.858 12.1213 16.0003 12.1213Z"
fill="#8E94A7" /> fill="#8E94A7" />
</svg> </svg>
</a> </a>
</Link> <a href="https://www.facebook.com/evoleasing" target="_blank" rel="nofollow noopener">
<Link href="#">
<a>
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" <path fillRule="evenodd" clipRule="evenodd"
d="M4 16C4 21.9333 8.33333 26.8667 14 27.8667L14.0669 27.8132C14.0446 27.8088 14.0223 27.8045 14 27.8V19.3333H11V16H14V13.3333C14 10.3333 15.9333 8.66667 18.6667 8.66667C19.5333 8.66667 20.4667 8.8 21.3333 8.93333V12H19.8C18.3333 12 18 12.7333 18 13.6667V16H21.2L20.6667 19.3333H18V27.8C17.9777 27.8045 17.9554 27.8088 17.9331 27.8132L18 27.8667C23.6667 26.8667 28 21.9333 28 16C28 9.4 22.6 4 16 4C9.4 4 4 9.4 4 16Z" d="M4 16C4 21.9333 8.33333 26.8667 14 27.8667L14.0669 27.8132C14.0446 27.8088 14.0223 27.8045 14 27.8V19.3333H11V16H14V13.3333C14 10.3333 15.9333 8.66667 18.6667 8.66667C19.5333 8.66667 20.4667 8.8 21.3333 8.93333V12H19.8C18.3333 12 18 12.7333 18 13.6667V16H21.2L20.6667 19.3333H18V27.8C17.9777 27.8045 17.9554 27.8088 17.9331 27.8132L18 27.8667C23.6667 26.8667 28 21.9333 28 16C28 9.4 22.6 4 16 4C9.4 4 4 9.4 4 16Z"
fill="#8E94A7" /> fill="#8E94A7" />
</svg> </svg>
</a> </a>
</Link> <a href="https://vk.com/evoleasing" target="_blank" rel="nofollow noopener">
</div> <svg data-name="Layer 21" height="32" id="Layer_21" viewBox="0 0 24 24" width="32" xmlns="http://www.w3.org/2000/svg"><path fill="#8E94A7" d="M21.54736,7H18.25688a.74281.74281,0,0,0-.65452.39156s-1.31237,2.41693-1.73392,3.231C14.73438,12.8125,14,12.125,14,11.10863V7.60417A1.10417,1.10417,0,0,0,12.89583,6.5h-2.474a1.9818,1.9818,0,0,0-1.751.8125s1.25626-.20312,1.25626,1.48958c0,.41974.02162,1.62723.04132,2.64a.72943.72943,0,0,1-1.273.50431,21.54029,21.54029,0,0,1-2.4982-4.54359A.69314.69314,0,0,0,5.5668,7C4.8532,7,3.42522,7,2.57719,7a.508.508,0,0,0-.47969.68481C3.00529,10.17487,6.91576,18,11.37917,18h1.87865A.74219.74219,0,0,0,14,17.25781V16.12342a.7293.7293,0,0,1,1.22868-.5315l2.24861,2.1127A1.08911,1.08911,0,0,0,18.223,18h2.95281c1.42415,0,1.42415-.98824.64768-1.75294-.54645-.53817-2.51832-2.61663-2.51832-2.61663A1.01862,1.01862,0,0,1,19.2268,12.307c.63737-.83876,1.67988-2.21175,2.122-2.79993C21.95313,8.70313,23.04688,7,21.54736,7Z"/></svg>
<p>© ООО "ЛК Эволюция"</p> </a>
<div> </div>
<Link href="#"> <p>© ООО "ЛК Эволюция"</p>
<a>Обработка персональных данных</a> <div>
</Link> <a href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/upload/docs/personal_date_policy.pdf`} target="_blank">
</div> Обработка персональных данных
<div> </a>
<Link href="#"> </div>
<a>Общие условия договора лизинга</a> <div>
</Link> <Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/rules/`}>
<a>Общие условия договора лизинга</a>
</Link>
</div>
</div> </div>
</div> </div>
</div> </footer>
</footer> )
) }
} }

View File

@ -1,14 +1,44 @@
import React from "react"; import React from "react";
import { sendLeasingOrder } from "../../../actions";
export default class FormRequest extends React.Component export default class FormRequest extends React.Component
{ {
constructor(props) constructor(props)
{ {
super(props); super(props);
this.state = {
name: "",
phone: "",
email: "",
company: "",
success: false,
};
}
_onFormSubmit = (event) =>
{
event.preventDefault();
sendLeasingOrder(this.state)
.then(() =>
{
this.setState({ success: true });
})
.catch(() =>
{
});
}
_handle_onPersonaData = () =>
{
window.open(`${ process.env.NEXT_PUBLIC_MAIN_SITE }/personal_data/`, "_blank");
} }
render() render()
{ {
const { name, phone, email, company, success } = this.state;
return ( return (
<section id="order"> <section id="order">
<div className="container wide"> <div className="container wide">
@ -17,24 +47,32 @@ export default class FormRequest extends React.Component
<div className="order_email"> <div className="order_email">
<p>Напишите на <a href="mailto:">info@evoleasing.ru</a> или заполните форму</p> <p>Напишите на <a href="mailto:">info@evoleasing.ru</a> или заполните форму</p>
</div> </div>
<form> <form onSubmit={ (event) => this._onFormSubmit(event) }>
<div className="form_field"> { !success ? (
<input type="text" value="" placeholder="Имя" onChange={ () => {} }/> <>
</div> <div className="form_field">
<div className="form_field"> <input type="text" value={ name } placeholder="Имя" onChange={ (event) => this.setState({ name: event.target.value }) } required={ true }/>
<input type="tel" value="" placeholder="Телефон" onChange={ () => {} }/> </div>
</div> <div className="form_field">
<div className="form_field"> <input type="tel" value={ phone } placeholder="Телефон" onChange={ (event) => this.setState({ phone: event.target.value }) } required={ true }/>
<input type="email" value="" placeholder="E-mail" onChange={ () => {} }/> </div>
</div> <div className="form_field">
<div className="form_field"> <input type="email" value={ email } placeholder="E-mail" onChange={ (event) => this.setState({ email: event.target.value }) } required={ true }/>
<input type="text" value="" placeholder="Организация" onChange={ () => {} }/> </div>
</div> <div className="form_field">
<div className="policy"> <input type="text" value={ company } placeholder="Организация" onChange={ (event) => this.setState({ company: event.target.value }) }/>
<input type="checkbox" name="policy" id="policy" hidden checked onChange={ () => {} }/> </div>
<label htmlFor="policy">Даю свое согласие на обработку моих персональных данных</label> <div className="policy">
</div> <input type="checkbox" name="policy" id="policy" hidden checked onChange={ () => {} }/>
<button className="button">Отправить</button> <label htmlFor="policy">Даю свое согласие на обработку {`\u00A0`}<u onClick={ () => this._handle_onPersonaData() }>моих персональных данных</u></label>
</div>
<button className="button">Отправить</button>
</>
) : (
<div style={{ minHeight: "400px", alignItems: "center", justifyContent: "center", display: "flex" }}>
<p style={{ color: "#fff", fontSize: "24px", lineHeight: "34px" }}>Благодарим Вас за обращение, наши специалисты свяжутся с Вами в ближайшее время.</p>
</div>
) }
</form> </form>
</div> </div>
</div> </div>

View File

@ -44,17 +44,17 @@ export default class Header extends React.Component
</button> </button>
<ul id="menu_list" className={ menuOpened ? "open" : "" }> <ul id="menu_list" className={ menuOpened ? "open" : "" }>
<li> <li>
<Link href="/"> <Link href={`/`} shallow>
<a className={ this.props.router && (this.props.router.route === "/" || this.props.router.route.indexOf("/contract") === 0) ? "active" : "" }>Договоры</a> <a className={ this.props.router && (this.props.router.route === "/" || this.props.router.route.indexOf("/contract") === 0) ? "active" : "" }>Договоры</a>
</Link> </Link>
</li> </li>
<li> <li>
<Link href="/documents/calendar/"> <Link href={`/documents/calendar/`} shallow>
<a className={ this.props.router && this.props.router.route.indexOf("/documents/") === 0 ? "active" : "" }>Взаиморасчеты и закрывающие документы</a> <a className={ this.props.router && this.props.router.route.indexOf("/documents/") === 0 ? "active" : "" }>Взаиморасчеты и закрывающие документы</a>
</Link> </Link>
</li> </li>
<li> <li>
<Link href="/settings/"> <Link href="/settings/" shallow>
<a className={ this.props.router && this.props.router.route === "/settings" ? "active" : "" }>Настройки</a> <a className={ this.props.router && this.props.router.route === "/settings" ? "active" : "" }>Настройки</a>
</Link> </Link>
</li> </li>

View File

@ -56,7 +56,7 @@ class CalendarCellModal extends Component
</Link> </Link>
</div> </div>
<div className="table_cell"> <div className="table_cell">
<b>{ numeral(payment.total_amount).format(' ., ') } </b> <b style={{ whiteSpace: "nowrap" }}>{ numeral(payment.total_amount).format(' ., ') } </b>
</div> </div>
</div> </div>
)) } )) }

View File

@ -14,7 +14,7 @@ import Company from "../components/Company";
import InnerMenu from "./components/InnerMenu"; import InnerMenu from "./components/InnerMenu";
import DownloadPdfButton from "../components/DownloadPdfButton"; import DownloadPdfButton from "../components/DownloadPdfButton";
import { getContractInfo, getContractAgreement, getFile } from "../../actions"; import { getContractInfo, getContractAgreement, getContractRules, getFile } from "../../actions";
class ContractPage extends React.Component class ContractPage extends React.Component
{ {
@ -22,8 +22,11 @@ class ContractPage extends React.Component
{ {
super(props); super(props);
this.state = { this.state = {
date: null,
car: null,
contract_date: null, contract_date: null,
agreement: null, agreement: null,
rules: null,
loading: false, loading: false,
} }
} }
@ -31,8 +34,11 @@ class ContractPage extends React.Component
static getDerivedStateFromProps(nextProps, prevState) static getDerivedStateFromProps(nextProps, prevState)
{ {
return { return {
date: nextProps.date,
car: nextProps.car,
contract_date: nextProps.contract_date, contract_date: nextProps.contract_date,
agreement: nextProps.agreement, agreement: nextProps.agreement,
rules: nextProps.rules,
}; };
} }
@ -42,7 +48,19 @@ class ContractPage extends React.Component
{ {
this.setState({ loading: true }, () => this.setState({ loading: true }, () =>
{ {
getContractInfo({ dispatch: this.props.dispatch, number: this.props.number }); getContractInfo({ dispatch: this.props.dispatch, number: this.props.number }).then((info) =>
{
console.log("info", info);
getContractRules({
dispatch: this.props.dispatch,
date: moment(info.date, "YYYY-MM-DD").format("DD.MM.YYYY"),
}).then(() => {}).catch(() => {});
})
.catch(() =>
{
});
getContractAgreement({ dispatch: this.props.dispatch, number: this.props.number }).then(() => { getContractAgreement({ dispatch: this.props.dispatch, number: this.props.number }).then(() => {
this.setState({ loading: false }); this.setState({ loading: false });
@ -53,9 +71,11 @@ class ContractPage extends React.Component
render() render()
{ {
const { loading, contract_date, agreement, } = this.state; const { loading, date, car, contract_date, agreement, rules, } = this.state;
const { number } = this.props; const { number } = this.props;
console.log("rules", rules);
const types = { const types = {
contracts: "Договор", contracts: "Договор",
redemptions: "Выкупные документы", redemptions: "Выкупные документы",
@ -78,8 +98,9 @@ class ContractPage extends React.Component
<div className="clear"></div> <div className="clear"></div>
<div className="container"> <div className="container">
<div className="title_wrapper"> <div className="title_wrapper">
<div className="left"> <div className="left" style={{ flexDirection: 'column', }}>
<h1 className="section_title">Договор { number }{ contract_date !== null && (<> от { moment(contract_date).format("DD.MM.YYYY") }</>)}</h1> <h1 className="section_title">Договор { number }</h1>
<h5 style={{ fontSize: '14px' }}>{ date !== undefined && date !== null && date !== null && (<> от { moment(date).format("DD.MM.YYYY") }</>)}{ car !== undefined && car !== null ? ` - ${ car.brand.name } ${ car.model.name } | ${ car.reg_number !== null ? car.reg_number : 'без рег. номера' } | ${ car.vin_number }` : '' }</h5>
</div> </div>
<Company/> <Company/>
</div> </div>
@ -101,11 +122,20 @@ class ContractPage extends React.Component
<span style={{ width: "100%"}}>{ file.number } от { file.date }</span> <span style={{ width: "100%"}}>{ file.number } от { file.date }</span>
{ file.type !== undefined && <span>{ file.type }</span> } { file.type !== undefined && <span>{ file.type }</span> }
</p> </p>
<DownloadPdfButton id={ file.url } filename={ `${ file.url }.pdf` }/> <DownloadPdfButton id={ file.url } filename={ `evoleasing_${ document.type }_${ file.number }_${ file.date }.pdf` }/>
</div> </div>
)) } )) }
</React.Fragment> </React.Fragment>
)) } )) }
{ rules !== undefined && rules !== null && rules.map((document, index ) => (
<div className="row" key={ index }>
<p className="doc_name i-pdf">
{ document.name }
<span style={{ width: "100%"}}>Дата вступления в силу: { document.active_from }</span>
</p>
<DownloadPdfButton url={ `${ process.env.NEXT_PUBLIC_MAIN_SITE }${ document.url }` } filename={ `${ document.filename }.pdf` } bitrix={ true }/>
</div>
)) }
</div> </div>
) } ) }
</article> </article>
@ -123,7 +153,10 @@ function mapStateToProps(state, ownProps)
{ {
return { return {
contract_date: state.contract.date, contract_date: state.contract.date,
date: state.contract.date,
car: state.contract.car,
agreement: state.contract.agreement, agreement: state.contract.agreement,
rules: state.contract.rules,
} }
} }

View File

@ -11,28 +11,27 @@ export default class InnerMenu extends React.Component
render() render()
{ {
const { number } = this.props; const { number } = this.props;
console.log("this.props", this.props);
return ( return (
<aside> <aside>
<ul className="aside_nav"> <ul className="aside_nav">
<li> <li>
<Link href={`/contract/${ number }/payments`}> <Link href={`/contract/${ number }/payments`} shallow>
<a className={ this.props.router && this.props.router.asPath.indexOf("payments") > -1 ? "active" : "" }>График платежей</a> <a className={ this.props.router && this.props.router.asPath.indexOf("payments") > -1 ? "active" : "" }>График платежей</a>
</Link> </Link>
</li> </li>
<li> <li>
<Link href={`/contract/${ number }/services`}> <Link href={`/contract/${ number }/services`} shallow>
<a className={ this.props.router && this.props.router.asPath.indexOf("services") > -1 ? "active" : "" }>Дополнительные услуги</a> <a className={ this.props.router && this.props.router.asPath.indexOf("services") > -1 ? "active" : "" }>Дополнительные услуги</a>
</Link> </Link>
</li> </li>
<li> <li>
<Link href={`/contract/${ number }/agreement`}> <Link href={`/contract/${ number }/agreement`} shallow>
<a className={ this.props.router && this.props.router.asPath.indexOf("agreement") > -1 ? "active" : "" }>Договор</a> <a className={ this.props.router && this.props.router.asPath.indexOf("agreement") > -1 ? "active" : "" }>Договор</a>
</Link> </Link>
</li> </li>
<li> <li>
<Link href={`/contract/${ number }/documents`}> <Link href={`/contract/${ number }/documents`} shallow>
<a className={ this.props.router && this.props.router.asPath.indexOf("documents") > -1 ? "active" : "" }>Документы по сделке</a> <a className={ this.props.router && this.props.router.asPath.indexOf("documents") > -1 ? "active" : "" }>Документы по сделке</a>
</Link> </Link>
</li> </li>

View File

@ -4,7 +4,9 @@ import Image from 'next/image';
import { connect } from "react-redux"; import { connect } from "react-redux";
import { withRouter } from 'next/router'; import { withRouter } from 'next/router';
import moment from "moment"; import moment from "moment";
import numeral from "numeral";
import { SpinnerCircular } from 'spinners-react'; import { SpinnerCircular } from 'spinners-react';
import pluralize from 'pluralize-ru';
import { reduxWrapper } from '../../store'; import { reduxWrapper } from '../../store';
@ -17,6 +19,13 @@ import DownloadPrintFormPdfButton from "../components/DownloadPrintFormPdfButton
import { getContractInfo, getContractDocuments, getReconciliationFile } from "../../actions"; import { getContractInfo, getContractDocuments, getReconciliationFile } from "../../actions";
const TYPES = {
upd: "УПД по очередным платежам",
upd_avans: "УПД по авансовым платежам",
billgibdd: "BillGIBDD",
fines: "Штрафы ГИБДД",
};
class ContractDocumentsPage extends React.Component class ContractDocumentsPage extends React.Component
{ {
constructor(props) constructor(props)
@ -24,18 +33,25 @@ class ContractDocumentsPage extends React.Component
super(props); super(props);
this.state = { this.state = {
opened: [], opened: [],
date: null,
car: null,
contract_date: null, contract_date: null,
documents: null, documents: null,
loading: false, loading: false,
valid_date_start: null,
valid_date_end: null,
period_date_start: null, period_date_start: null,
period_date_end: null, period_date_end: null,
reconciliation_requested: false, reconciliation_requested: false,
reconciliation_disabled: false,
} }
} }
static getDerivedStateFromProps(nextProps, prevState) static getDerivedStateFromProps(nextProps, prevState)
{ {
return { return {
date: nextProps.date,
car: nextProps.car,
contract_date: nextProps.contract_date, contract_date: nextProps.contract_date,
documents: nextProps.documents, documents: nextProps.documents,
}; };
@ -45,7 +61,8 @@ class ContractDocumentsPage extends React.Component
{ {
if(!this.state.loading && this.props.number !== undefined) if(!this.state.loading && this.props.number !== undefined)
{ {
this.setState({ loading: true, period_date_end: moment().toDate() }, () => const de = moment().toDate();
this.setState({ loading: true, period_date_end: de, valid_date_end: de }, () =>
{ {
getContractInfo({ dispatch: this.props.dispatch, number: this.props.number }); getContractInfo({ dispatch: this.props.dispatch, number: this.props.number });
@ -62,7 +79,8 @@ class ContractDocumentsPage extends React.Component
{ {
if(prevState.contract_date === null && this.state.contract_date !== null) if(prevState.contract_date === null && this.state.contract_date !== null)
{ {
this.setState({ period_date_start: moment(this.state.contract_date).toDate() }); const ds = moment(this.state.contract_date).toDate();
this.setState({ period_date_start: ds, valid_date_start: ds });
} }
} }
} }
@ -99,26 +117,205 @@ class ContractDocumentsPage extends React.Component
_handle_onPeriodDate_start = (date) => _handle_onPeriodDate_start = (date) =>
{ {
this.setState({ period_date_start: date }); const { valid_date_start, valid_date_end, period_date_start, period_date_end } = this.state;
const md = moment(date, "DD.MM.YYYY");
if(md.isValid())
{
console.log(md);
console.log("vs", valid_date_start);
console.log("ve", valid_date_end);
if(date >= valid_date_start && date < valid_date_end)
{
console.log("ps", period_date_start);
if(date < period_date_end)
{
console.log(">>>>>");
this.setState({ period_date_start: date, reconciliation_disabled: false });
}
else
{
this.setState({ reconciliation_disabled: true });
}
}
else
{
this.setState({ reconciliation_disabled: true });
}
}
else
{
console.log("invalid date", md);
this.setState({ reconciliation_disabled: true });
}
} }
_handle_onPeriodDate_end = (date) => _handle_onPeriodDate_end = (date) =>
{ {
this.setState({ period_date_end: date }); const { valid_date_start, valid_date_end, period_date_start, period_date_end } = this.state;
if(moment(date).isValid())
{
if(date >= valid_date_start && date < valid_date_end)
{
if(date > period_date_start)
{
this.setState({ period_date_end: date, reconciliation_disabled: false });
}
else
{
this.setState({ reconciliation_disabled: true });
}
}
else
{
this.setState({ reconciliation_disabled: true });
}
}
else
{
this.setState({ reconciliation_disabled: true });
}
}
_handle_onGroup = (group) =>
{
console.log("group", group);
const opened = [ ...this.state.opened ];
if(opened.indexOf(group) < 0)
{ opened.push(group); }
else
{ opened.splice(opened.indexOf(group), 1); }
this.setState({ opened: opened });
}
_renderDocuments = (documents, type) =>
{
const { number } = this.props;
const { opened } = this.state;
if(documents.length > 0)
{
return (
<>
<div className={`dropdown_block bt ${ opened.indexOf(type) > -1 ? "open" : "" }`}>
<div className="block_header" onClick={ () => this._handle_onGroup(type) }>
<p>{ TYPES[type] }</p>
{ documents.length > 3 && (
<button className={`block_toggle ${ opened.indexOf(type) > -1 ? "rotate" : "" }`}></button>
) }
</div>
</div>
<div className="dosc_list medium-icon">
{ documents.slice(0, opened.indexOf(type) > -1 ? documents.length : 3).map((doc, index) => (
<div className="row" key={ index }>
<p className="doc_name i-pdf i-medium">
{ doc.num } от { moment(doc.date).format("DD.MM.YYYY") }
</p>
<DownloadPrintFormPdfButton className="download-icon" filename={ `${ number }_${ doc.type }_${ doc.num }.pdf` } contract={ number } num={ doc.num } date={ doc.date } type={ doc.type }/>
</div>
)) }
{ opened.indexOf(type) < 0 && documents.length > 3 && (
<div className="row" style={{ justifyContent: "center", corsor: "pointer" }} onClick={ () => this._handle_onGroup(type) }>
<p style={{ color: "#747474" }}>Еще { documents.length - 3 } { pluralize((documents.length - 3), 'документов', 'документ', 'документа', 'документов') }</p>
</div>
) }
</div>
</>
)
}
if(type !== "upd_avans")
{
return (
<>
<div className={`dropdown_block bt ${ opened.indexOf(type) > -1 ? "open" : "" }`}>
<div className="block_header" onClick={ () => this._handle_onGroup(type) }>
<p>{ TYPES[type] }</p>
</div>
</div>
<div>
<p>Документов пока еще нет.</p>
<p>&nbsp;</p>
</div>
</>
);
}
}
_renderFines = (fines, type) =>
{
const { number } = this.props;
const { opened } = this.state;
if(fines.length > 0)
{
<>
<div className={`dropdown_block bt ${ opened.indexOf('fines') > -1 ? "open" : "" }`}>
<div className="block_header" onClick={ () => this._handle_onGroup('fines') }>
<p>{ TYPES[ 'fines' ] }</p>
{ fines.length > 3 && (
<button className={`block_toggle ${ opened.indexOf('fines') > -1 ? "rotate" : "" }`}></button>
) }
</div>
</div>
<div className="dosc_list medium-icon">
{ fines.slice(0, opened.indexOf('fines') > -1 ? fines.length : 3).map((fine, fine_index) => (
<div className="row" key={ fine_index }>
<div className="block_body" >
<div className="transaction_detail">
<p> постановления: <b>{ fine.fine_number }</b></p>
<ul>
<li>Сумма: <b>{ numeral(fine.amount).format(' ., ') } </b></li>
<li>Дата: <b>{ moment(fine.fine_date).format("DD.MM.YYYY") }</b></li>
<li>Статус: <b className="success">{ fine.status }</b></li>
<li>Штраф: { fine.fine_title }</li>
</ul>
</div>
</div>
{ opened.indexOf(type) < 0 && fines.length > 3 && (
<div className="row" style={{ justifyContent: "center", corsor: "pointer" }} onClick={ () => this._handle_onGroup(type) }>
<p style={{ color: "#747474" }}>Еще { fines.length - 3 } { pluralize((fines.length - 3), 'постановлений', 'постановление', 'постановления', 'постановлений') }</p>
</div>
) }
{/*}
<DownloadPrintFormPdfButton className="download-icon" filename={ `${ number }_${ upd_document.type }_${ upd_document.num }.pdf` } contract={ number } num={ upd_document.num } date={ upd_document.date } type={ upd_document.type }/>
{*/}
</div>
)) }
</div>
</>
}
return (
<>
<div className={`dropdown_block bt ${ opened.indexOf(type) > -1 ? "open" : "" }`}>
<div className="block_header" onClick={ () => this._handle_onGroup(type) }>
<p>{ TYPES[type] }</p>
</div>
</div>
<div>
<p>Штрафов не найдено.</p>
<p>&nbsp;</p>
</div>
</>
);
} }
render() render()
{ {
const { loading, contract_date, documents, period_date_start, period_date_end, reconciliation_requested } = this.state; const { loading, date, car, contract_date, documents, period_date_start, period_date_end, valid_date_start, valid_date_end, reconciliation_requested, reconciliation_disabled, opened } = this.state;
const { number } = this.props; const { number } = this.props;
console.log("documentsdocumentsdocumentsdocumentsdocuments"); console.log("documentsdocumentsdocumentsdocumentsdocuments");
console.log(documents); console.log(documents);
const types = { console.log("opened");
upd: "УПД по очередным платежам", console.log(opened);
upd_avans: "УПД по авансовым платежам",
};
return ( return (
<React.Fragment> <React.Fragment>
@ -135,8 +332,9 @@ class ContractDocumentsPage extends React.Component
<div className="clear"></div> <div className="clear"></div>
<div className="container"> <div className="container">
<div className="title_wrapper"> <div className="title_wrapper">
<div className="left"> <div className="left" style={{ flexDirection: 'column', }}>
<h1 className="section_title">Договор { number }{ contract_date !== null && (<> от { moment(contract_date).format("DD.MM.YYYY") }</>)}</h1> <h1 className="section_title">Договор { number }</h1>
<h5 style={{ fontSize: '14px' }}>{ date !== undefined && date !== null && date !== null && (<> от { moment(date).format("DD.MM.YYYY") }</>)}{ car !== undefined && car !== null ? ` - ${ car.brand.name } ${ car.model.name } | ${ car.reg_number !== null ? car.reg_number : 'без рег. номера' } | ${ car.vin_number }` : '' }</h5>
</div> </div>
<Company /> <Company />
</div> </div>
@ -153,14 +351,14 @@ class ContractDocumentsPage extends React.Component
<p>Акт сверки</p> <p>Акт сверки</p>
<div className="form_group"> <div className="form_group">
<div className="form_field"> <div className="form_field">
<DateInput placeholder="Дата начала периода" value={ period_date_start } onChange={ this._handle_onPeriodDate_start }/> <DateInput placeholder="Дата начала периода" value={ period_date_start } min={ valid_date_start } max={ valid_date_end } onChange={ this._handle_onPeriodDate_start }/>
</div> </div>
<div className="form_field"> <div className="form_field">
<DateInput placeholder="Дата окончания периода" value={ period_date_end } onChange={ this._handle_onPeriodDate_end }/> <DateInput placeholder="Дата окончания периода" value={ period_date_end } min={ valid_date_start } max={ valid_date_end } onChange={ this._handle_onPeriodDate_end }/>
</div> </div>
</div> </div>
<div className="form_group"> <div className="form_group">
<button className="button button-blue" onClick={ () => { this._handle_onReconciliationFileRequest() }}> <button className="button button-blue" disabled={ reconciliation_disabled } onClick={ () => { this._handle_onReconciliationFileRequest() }}>
<> <>
{ reconciliation_requested ? ( { reconciliation_requested ? (
<SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" /> <SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" />
@ -173,26 +371,9 @@ class ContractDocumentsPage extends React.Component
<div className="dropdown_blocks_list"> <div className="dropdown_blocks_list">
{ documents !== undefined && documents !== null ? ( { documents !== undefined && documents !== null ? (
<> <>
{ documents.upd && documents.upd.map((doc, index) => ( { this._renderDocuments(documents.upd, 'upd') }
<React.Fragment key={ index }> { this._renderDocuments(documents.upd_avans, 'upd_avans') }
<div className="dropdown_block bt"> { this._renderFines(documents.fines, 'fines') }
<div className="block_header">
<p>{ types[ doc.type.toLowerCase() ] }</p>
<button className="block_toggle"></button>
</div>
</div>
<div className="dosc_list medium-icon">
{ doc.upd.map((upd_document, upd_document_index) => (
<div className="row" key={ upd_document_index }>
<p className="doc_name i-pdf i-medium">
{ upd_document.num } от { moment(upd_document.date).format("DD.MM.YYYY") }
</p>
<DownloadPrintFormPdfButton filename={ `${ number }_${ upd_document.type }_${ upd_document.num }.pdf` } contract={ number } num={ upd_document.num } date={ upd_document.date } type={ upd_document.type }/>
</div>
)) }
</div>
</React.Fragment>
)) }
</> </>
) : null } ) : null }
</div> </div>
@ -213,6 +394,8 @@ function mapStateToProps(state, ownProps)
{ {
return { return {
contract_date: state.contract.date, contract_date: state.contract.date,
date: state.contract.date,
car: state.contract.car,
documents: state.contract.documents, documents: state.contract.documents,
} }
} }

View File

@ -24,7 +24,8 @@ class ContractSchedulePage extends React.Component
this.state = { this.state = {
loading: false, loading: false,
payments: null, payments: null,
contract_date: null, date: null,
car: null,
full: false, full: false,
opened: [], opened: [],
} }
@ -33,8 +34,9 @@ class ContractSchedulePage extends React.Component
static getDerivedStateFromProps(nextProps, prevState) static getDerivedStateFromProps(nextProps, prevState)
{ {
return { return {
date: nextProps.date,
car: nextProps.car,
payments: nextProps.payments, payments: nextProps.payments,
contract_date: nextProps.contract_date,
}; };
} }
@ -53,6 +55,22 @@ class ContractSchedulePage extends React.Component
} }
} }
_getLastPayDate = () =>
{
let last = null;
const { payments } = this.state;
for(let i in payments)
{
if(payments[i].status === "Paid")
{
last = moment(payments[i].date, "DD-MM-YYYY");
}
}
return last;
}
_handle_onSetFull = () => _handle_onSetFull = () =>
{ {
this.setState({ full: true }); this.setState({ full: true });
@ -72,7 +90,7 @@ class ContractSchedulePage extends React.Component
render() render()
{ {
const { payments, contract_date, full, opened, loading } = this.state; const { payments, date, car, full, opened, loading } = this.state;
const { number } = this.props; const { number } = this.props;
console.log("RENDER", "payments"); console.log("RENDER", "payments");
@ -85,6 +103,7 @@ class ContractSchedulePage extends React.Component
"Paid": "paid", "Paid": "paid",
}; };
let today = moment(); let today = moment();
let last_pay_date = this._getLastPayDate();
return ( return (
<React.Fragment> <React.Fragment>
@ -101,8 +120,9 @@ class ContractSchedulePage extends React.Component
<div className="clear"></div> <div className="clear"></div>
<div className="container"> <div className="container">
<div className="title_wrapper"> <div className="title_wrapper">
<div className="left"> <div className="left" style={{ flexDirection: 'column', }}>
<h1 className="section_title">Договор { number }{ contract_date !== null && (<> от { moment(contract_date).format("DD.MM.YYYY") }</>)}</h1> <h1 className="section_title">Договор { number }</h1>
<h5 style={{ fontSize: '14px' }}>{ date !== undefined && date !== null && date !== null && (<> от { moment(date).format("DD.MM.YYYY") }</>)}{ car !== undefined && car !== null ? ` - ${ car.brand.name } ${ car.model.name } | ${ car.reg_number !== null ? car.reg_number : 'без рег. номера' } | ${ car.vin_number }` : '' }</h5>
</div> </div>
<Company/> <Company/>
</div> </div>
@ -130,7 +150,7 @@ class ContractSchedulePage extends React.Component
{ payments !== null && Object.values(payments).map((payment, index) => { payments !== null && Object.values(payments).map((payment, index) =>
{ {
let pd = moment(payment.date, "DD-MM-YYYY"); let pd = moment(payment.date, "DD-MM-YYYY");
if(!full && today > pd) { return null; } if(!full && pd < last_pay_date) { return null; }
return ( return (
<div className={ `table_row ${ opened.indexOf(payment.number) > -1 ? "opened" : "" }` } data-status={ payment.status === "NotPaid" && pd < today ? "notpaid" : statuses[payment.status] } key={ index }> <div className={ `table_row ${ opened.indexOf(payment.number) > -1 ? "opened" : "" }` } data-status={ payment.status === "NotPaid" && pd < today ? "notpaid" : statuses[payment.status] } key={ index }>
@ -141,9 +161,11 @@ class ContractSchedulePage extends React.Component
<div className="table_cell"> <div className="table_cell">
{ payment.status === "Paid" && "Оплачено" } { payment.status === "Paid" && "Оплачено" }
{ payment.status === "NotPaid" && "Не оплачено" } { payment.status === "NotPaid" && "Не оплачено" }
{ payment.status === "HalfPaid" && "Частично оплачено" } { payment.status === "HalfPaid" && (
<><span>Недоплата</span><br/><span>{ numeral(payment.total_amount - payment.paid_amount).format(' ., ') } </span></>
) }
{ payment.status === "OverPaid" && ( { payment.status === "OverPaid" && (
<div className="table_cell"><span>Переплата</span> <span>{ numeral(payment.total_amount).format(' ., ') } </span></div> <><span>Переплата</span> <span>{ numeral(payment.total_amount).format(' ., ') } </span></>
) } ) }
</div> </div>
<div className="table_cell"> <div className="table_cell">
@ -220,7 +242,8 @@ function mapStateToProps(state, ownProps)
return { return {
company: state.company, company: state.company,
payments: state.contract.payments, payments: state.contract.payments,
contract_date: state.contract.date, date: state.contract.date,
car: state.contract.car,
//schedule: state.payments, //schedule: state.payments,
} }
} }

View File

@ -23,6 +23,8 @@ class ContractServicesPage extends React.Component
super(props); super(props);
this.state = { this.state = {
opened: [], opened: [],
date: null,
car: null,
contract_date: null, contract_date: null,
loading: false, loading: false,
helpcard: null, helpcard: null,
@ -35,11 +37,13 @@ class ContractServicesPage extends React.Component
static getDerivedStateFromProps(nextProps, prevState) static getDerivedStateFromProps(nextProps, prevState)
{ {
return { return {
date: nextProps.date,
car: nextProps.car,
contract_date: nextProps.contract_date, contract_date: nextProps.contract_date,
helpcard: nextProps.helpcard, helpcard: nextProps.helpcard,
insurance: nextProps.insurance, insurance: nextProps.insurance,
registration: nextProps.registration, registration: nextProps.registration,
telematic: nextProps.telematic, telematic: nextProps.telematic,
}; };
} }
@ -80,7 +84,7 @@ class ContractServicesPage extends React.Component
render() render()
{ {
const { opened, loading, contract_date, helpcard, insurance, registration, telematic, } = this.state; const { opened, loading, date, car, contract_date, helpcard, insurance, registration, telematic, } = this.state;
const { number } = this.props; const { number } = this.props;
return ( return (
@ -98,8 +102,9 @@ class ContractServicesPage extends React.Component
<div className="clear"></div> <div className="clear"></div>
<div className="container"> <div className="container">
<div className="title_wrapper"> <div className="title_wrapper">
<div className="left"> <div className="left" style={{ flexDirection: 'column', }}>
<h1 className="section_title">Договор { number }{ contract_date !== null && (<> от { moment(contract_date).format("DD.MM.YYYY") }</>)}</h1> <h1 className="section_title">Договор { number }</h1>
<h5 style={{ fontSize: '14px' }}>{ date !== undefined && date !== null && date !== null && (<> от { moment(date).format("DD.MM.YYYY") }</>)}{ car !== undefined && car !== null ? ` - ${ car.brand.name } ${ car.model.name } | ${ car.reg_number !== null ? car.reg_number : 'без рег. номера' } | ${ car.vin_number }` : '' }</h5>
</div> </div>
<Company/> <Company/>
</div> </div>
@ -127,6 +132,7 @@ class ContractServicesPage extends React.Component
{ entry.card_number !== null ? ( { entry.card_number !== null ? (
<div className="block_body"> <div className="block_body">
<div className="company"> <div className="company">
<p className="title">РАТ</p>
<ul> <ul>
<li>Номер карты: <b>{ entry.card_number }</b></li> <li>Номер карты: <b>{ entry.card_number }</b></li>
<li>Тип карты: <b>{ entry.card_type }</b></li> <li>Тип карты: <b>{ entry.card_type }</b></li>
@ -160,7 +166,7 @@ class ContractServicesPage extends React.Component
<div className="block_body"> <div className="block_body">
{ insurance !== undefined && insurance !== null ? ( { insurance !== undefined && insurance !== null ? (
<> <>
{ insurance.kasko !== undefined && insurance.kasko !== null && insurance.kasko.map((entry, index) => ( { insurance.kasko !== undefined && insurance.kasko !== null && insurance.kasko !== "" && insurance.kasko.map !== undefined && insurance.kasko.map((entry, index) => (
<React.Fragment key={ index }> <React.Fragment key={ index }>
<div className="company"> <div className="company">
<p className="title">КАСКО</p> <p className="title">КАСКО</p>
@ -176,7 +182,7 @@ class ContractServicesPage extends React.Component
{ entry.description && (<p>{ entry.description }</p>) } { entry.description && (<p>{ entry.description }</p>) }
</React.Fragment> </React.Fragment>
)) } )) }
{ insurance.osago !== undefined && insurance.osago !== null && insurance.osago.map((entry, index) => ( { insurance.osago !== undefined && insurance.osago !== null && insurance.osago !== "" && insurance.osago.map !== undefined && insurance.osago.map((entry, index) => (
<React.Fragment key={ index }> <React.Fragment key={ index }>
<div className="company"> <div className="company">
<p className="title">ОСАГО</p> <p className="title">ОСАГО</p>
@ -192,7 +198,7 @@ class ContractServicesPage extends React.Component
{ entry.description && (<p>{ entry.description }</p>) } { entry.description && (<p>{ entry.description }</p>) }
</React.Fragment> </React.Fragment>
)) } )) }
{ insurance.nsib !== undefined && insurance.nsib !== null && insurance.nsib.map((entry, index) => ( { insurance.nsib !== undefined && insurance.nsib !== null && insurance.nsib !== "" && insurance.nsib.map !== undefined && insurance.nsib.map((entry, index) => (
<React.Fragment key={ index }> <React.Fragment key={ index }>
<div className="company"> <div className="company">
<p className="title">НСИБ</p> <p className="title">НСИБ</p>
@ -222,7 +228,24 @@ class ContractServicesPage extends React.Component
</p> </p>
<button className="block_toggle"></button> <button className="block_toggle"></button>
</div> </div>
<div className="block_body"><p>Нет данных</p></div> { registration !== undefined && registration !== null && registration.length > 0 ? registration.map((entry, index) =>
(
<div className="block_body" key={ index }>
<div className="company">
<p className="title">ГИБДД</p>
<ul>
{ entry.package && (
<li>Пакет услуг: <b>{ entry.package }</b></li>
) }
{ entry.amount && (
<li>Стоимость: <b>{ numeral(entry.amount).format(' ., ') } </b></li>
) }
</ul>
</div>
</div>
)) : (
<div className="block_body"><p>Нет данных</p></div>
) }
</div> </div>
<div className={`dropdown_block ${ opened.indexOf("telematic") > -1 ? 'open' : '' }`}> <div className={`dropdown_block ${ opened.indexOf("telematic") > -1 ? 'open' : '' }`}>
<div className="block_header" onClick={ () => this._handle_onCard('telematic') }> <div className="block_header" onClick={ () => this._handle_onCard('telematic') }>
@ -232,7 +255,26 @@ class ContractServicesPage extends React.Component
</p> </p>
<button className="block_toggle"></button> <button className="block_toggle"></button>
</div> </div>
<div className="block_body"><p>Нет данных</p></div> { telematic !== undefined && telematic !== null && telematic.length > 0 ? telematic.map((entry, index) =>
(
<div className="block_body" key={ index }>
<div className="company">
<ul style={{ marginLeft: "0px" }}>
{ entry.provider && (
<li>Поставщик: <b>{ entry.provider }</b></li>
) }
{ entry.equipment && (
<li>Оборудование: <b>{ entry.equipment }</b></li>
) }
{ entry.amount && (
<li>Стоимость: <b>{ numeral(entry.amount).format(' ., ') } </b></li>
) }
</ul>
</div>
</div>
)) : (
<div className="block_body"><p>Нет данных</p></div>
)}
{/*} {/*}
<div className="block_body"> <div className="block_body">
<div className="company"> <div className="company">
@ -264,6 +306,8 @@ function mapStateToProps(state, ownProps)
{ {
return { return {
contract_date: state.contract.date, contract_date: state.contract.date,
date: state.contract.date,
car: state.contract.car,
helpcard: state.contract.helpcard, helpcard: state.contract.helpcard,
insurance: state.contract.insurance, insurance: state.contract.insurance,
registration: state.contract.registration, registration: state.contract.registration,

View File

@ -17,6 +17,7 @@ import Company from "../components/Company";
import CalendarCellModal from "../components/Modal/calendar"; import CalendarCellModal from "../components/Modal/calendar";
import { getCalendar } from '../../actions'; import { getCalendar } from '../../actions';
import { MatchMedia } from '../../utils/mediaqueries';
class CalendarPage extends React.Component class CalendarPage extends React.Component
{ {
@ -29,6 +30,10 @@ class CalendarPage extends React.Component
periods: null, periods: null,
selected_period: moment().format("YYYYMM"), selected_period: moment().format("YYYYMM"),
selected_payment: undefined, selected_payment: undefined,
current_week: parseInt(moment().format('ww'), 10),
selected_week: 0,
weeks_in_month: 1,
perweek: MatchMedia() === "mobile" ? true : false,
}; };
} }
@ -43,8 +48,18 @@ class CalendarPage extends React.Component
componentDidMount() componentDidMount()
{ {
const date_from = moment().startOf("month").toDate(); const date_from = moment().startOf("month").subtract(7, 'day').toDate();
const date_to = moment().endOf("month").toDate(); const date_to = moment().endOf("month").add(7, 'day').toDate();
var clonedMoment = moment();
var first = clonedMoment.startOf('month').week();
var last = clonedMoment.endOf('month').week();
if( first > last) { last = first + last; }
let mw = last - first + 1;
const nwsd = moment().endOf("month").add(1, "day").format("e");
if(nwsd !== 0) { mw = mw - 1; }
this.setState({ weeks_in_month: mw });
getCalendar({ dispatch: this.props.dispatch, date_from, date_to }).then().catch(); getCalendar({ dispatch: this.props.dispatch, date_from, date_to }).then().catch();
} }
@ -76,39 +91,91 @@ class CalendarPage extends React.Component
this.toggleModal(); this.toggleModal();
} }
_handle_onChangePeriod = (period) => _handle_onChangePeriod = (period, new_selected_week) =>
{ {
this.setState({ selected_period: period }, () => var clonedMoment = moment(period, "YYYYMM");
var first = clonedMoment.startOf('month').week();
var last = clonedMoment.endOf('month').week();
if( first > last) { last = first + last; }
let mw = last - first + 1;
const ld = parseInt(moment(period, "YYYYMM").endOf("month").format("e"), 10);
if(ld !== 6) { mw = mw - 1; }
this.setState({ selected_period: period, weeks_in_month: mw, selected_week: new_selected_week}, () =>
{ {
const date_from = moment(period, "YYYYMM").startOf("month").toDate(); const date_from = moment(period, "YYYYMM").startOf("month").subtract(7, 'day').toDate();
const date_to = moment(period, "YYYYMM").endOf("month").toDate(); const date_to = moment(period, "YYYYMM").endOf("month").add(7, 'day').toDate();
getCalendar({ dispatch: this.props.dispatch, date_from, date_to }).then().catch(); getCalendar({ dispatch: this.props.dispatch, date_from, date_to }).then().catch();
}); });
} }
_handle_onWeek_prev = () =>
{
const { selected_period, selected_week, } = this.state;
if(selected_week === 0)
{
var clonedMoment = moment(selected_period, "YYYYMM").subtract(1, "month");
var first = clonedMoment.startOf('month').week();
var last = clonedMoment.endOf('month').week();
if( first > last) { last = first + last; }
let mw = last - first + 1;
const ld = parseInt(clonedMoment.endOf("month").format("e"), 10);
if(ld !== 6) { mw = mw - 1; }
const new_selected_week = mw - 1;
const prev_period = clonedMoment.format("YYYYMM");
this._handle_onChangePeriod(prev_period, new_selected_week);
}
else
{
this.setState({ selected_week: parseInt(selected_week, 10) - 1 }, () =>
{
});
}
}
_getWeekToSwitch = () =>
{
const { selected_period, selected_week, weeks_in_month } = this.state;
}
_handle_onWeek_next = () =>
{
const { selected_period, selected_week, weeks_in_month } = this.state;
const next_week = selected_week + 1;
if(next_week === weeks_in_month)
{
const next_period = moment(selected_period, "YYYYMM").add(1, "month").format("YYYYMM");
this._handle_onChangePeriod(next_period, 0);
}
else
{
this.setState({ selected_week: next_week }, () =>
{
});
}
}
render() render()
{ {
const { selected_period, selected_payment, periods, payments } = this.state; const { selected_period, selected_payment, periods, payments, current_week, selected_week, perweek, weeks_in_month } = this.state;
if(payments === null) { return null; } if(payments === null) { return null; }
let month = moment(selected_period, "YYYYMM").format("M") - 1; let month = moment(selected_period, "YYYYMM").format("M") - 1;
//console.log("periodsperiodsperiodsperiodsperiods");
//console.log(periods);
const dates = []; const dates = [];
const date_sm = moment(selected_period, 'YYYYMM').startOf("month"); const date_sm = moment(selected_period, 'YYYYMM').startOf("month");
const date_em = moment(selected_period, 'YYYYMM').endOf("month"); const date_em = moment(selected_period, 'YYYYMM').endOf("month");
//console.log("date_sm", date_sm.format("YYYY-MM-DD"));
//console.log("date_em", date_em.format("YYYY-MM-DD"));
//console.log("date_sm.day()", date_sm.day());
//console.log("date_em.day()", date_em.day());
let date_s = null; let date_s = null;
if(date_sm.day() !== 1) if(date_sm.clone().isoWeekday() !== 1)
{ date_s = date_sm.subtract(date_sm.day() - 1, "days"); } { date_s = date_sm.clone().subtract(date_sm.clone().isoWeekday() - 1, "days"); }
else else
{ date_s = date_sm; } { date_s = date_sm; }
@ -119,10 +186,6 @@ class CalendarPage extends React.Component
{ date_e = date_em; } { date_e = date_em; }
const date = moment(); const date = moment();
//console.log(date_sm.format("YYYY-MM-DD"));
//console.log(date_sm.day());
//console.log("date_s", date_s.format("YYYY-MM-DD"))
//console.log("date_e", date_e.format("YYYY-MM-DD"))
let d = date_s; let d = date_s;
let payment = this.getPayments(date_s.format("YYYY-MM-DD")); let payment = this.getPayments(date_s.format("YYYY-MM-DD"));
@ -133,24 +196,35 @@ class CalendarPage extends React.Component
while(d.add(1, 'days').diff(date_e) < 0) while(d.add(1, 'days').diff(date_e) < 0)
{ {
//console.log(d.toDate());
let payment = this.getPayments(d.format("YYYY-MM-DD"));
dates.push({ dates.push({
date: d.clone(), date: d.clone(),
payment: payment,
}); });
} }
const dow = date.day(); for(let i in dates)
//console.log(dow); {
//console.log("date.month())", date.month()); dates[i].payment = this.getPayments(dates[i].date.format("YYYY-MM-DD"));
}
const dow = date.day();
const weeks = dates.reduce(function(result, value, index, array) { const weeks = dates.reduce(function(result, value, index, array) {
if (index % 7 === 0) if (index % 7 === 0)
result.push(array.slice(index, index +7)); result.push(array.slice(index, index +7));
return result; return result;
}, []); }, []);
let render_weeks = [];
if(perweek)
{
render_weeks = weeks.slice(selected_week, weeks_in_month);
}
else
{
render_weeks = weeks;
}
const periods_list = Object.values(periods);
return ( return (
<React.Fragment> <React.Fragment>
<Head> <Head>
@ -167,6 +241,7 @@ class CalendarPage extends React.Component
<div className="container"> <div className="container">
<div className="title_wrapper"> <div className="title_wrapper">
<div className="left"> <div className="left">
{/*[{ perweek ? 1 : 0 }, { current_week }, { selected_week }, { weeks_in_month }]*/}
<h1 className="section_title">Календарь оплат</h1> <h1 className="section_title">Календарь оплат</h1>
</div> </div>
<Company/> <Company/>
@ -176,15 +251,17 @@ class CalendarPage extends React.Component
<article> <article>
<div className="calendar_wrapper"> <div className="calendar_wrapper">
<div className="form_field"> <div className="form_field">
<select id="calendar_month" defaultValue={ selected_period } onChange={ (event) => this._handle_onChangePeriod(event.target.value) }> { periods_list.length > 0 && (
{ periods !== null && Object.values(periods).map((period, index) => ( <select id="calendar_month" value={ periods_list.indexOf(selected_period) < 0 ? periods_list[periods_list.length - 1] : selected_period } onChange={ (event) => this._handle_onChangePeriod(event.target.value, 0) }>
<option key={ index } value={ period }>{ moment(period, "YYYYMM").format('MMMM YYYY') }</option> { periods !== null && periods_list.map((period, index) => (
)) } <option key={ index } value={ period }>{ moment(period, "YYYYMM").format('MMMM YYYY') }</option>
</select> )) }
</select>
) }
</div> </div>
<div className="calendar_nav"> <div className="calendar_nav">
<button>Предыдущая неделя</button> <button onClick={ () => this._handle_onWeek_prev() } disabled={ moment(selected_period, "YYYYMM").add(selected_week * 7, "day") <= moment(periods_list[0], "YYYYMM") ? true : false }>Предыдущая неделя</button>
<button>Следующая неделя</button> <button onClick={ () => this._handle_onWeek_next() } disabled={ moment(selected_period, "YYYYMM").add(selected_week * 7, "day") >= moment(periods_list[periods_list.length - 1], "YYYYMM").add(1, "month") ? true : false }>Следующая неделя</button>
</div> </div>
<div className="calendar_grid"> <div className="calendar_grid">
<div className="grid_header"> <div className="grid_header">
@ -197,22 +274,22 @@ class CalendarPage extends React.Component
<div className="grid_cell">Вс</div> <div className="grid_cell">Вс</div>
</div> </div>
<div className="grid_body"> <div className="grid_body">
{ weeks.map((week, index) => { render_weeks.map((week, week_index) =>
{ {
return ( return (
<div className={index == 0 ? "grid_week active" : "grid_week"} key={"week_" + index}> <div className={week_index == 0 ? "grid_week active" : "grid_week"} key={"week_" + week_index}>
{ week.map((day, index) => { { week.map((day, index) => {
if(day.payment) if(day.payment)
{ {
return ( return (
<div key={ index } style={{ cursor: "pointer" }} className={`grid_cell payment ${ day.date.month() !== month ? 'disabled' : '' } ${ day.date.format("YYYYMMDD") === moment().format("YYYYMMDD") ? 'current' : '' } `} onClick={ () => this._handle_onDayClick(day) }> <div key={ index } style={{ cursor: "pointer" }} className={`grid_cell payment ${ !perweek && day.date.month() !== month ? 'disabled' : '' } ${ day.date.format("YYYYMMDD") === moment().format("YYYYMMDD") ? 'current' : '' } `} onClick={ () => this._handle_onDayClick(day) }>
<div className="cell_header"> <div className="cell_header">
<p><span>{ day.date.format("DD") }</span> { day.date.format("MMM").toLocaleLowerCase() } { day.date.format("Y").toLocaleLowerCase() }</p> <p><span>{ day.date.format("DD") }</span> { day.date.format("MMM").toLocaleLowerCase() } { day.date.format("Y").toLocaleLowerCase() }</p>
</div> </div>
<div className="cell_body">{ day.payment && ( <div className="cell_body">{ day.payment && (
<p> <p>
Общий платеж Общий платеж
<span>{ numeral(day.payment.total).format(' ., ') } </span> <span style={ day.payment.total > 1000000 ? { fontSize: '14px', whiteSpace: "nowrap" } : {}}>{ numeral(day.payment.total).format(' ., ') } </span>
</p> </p>
)} )}
</div> </div>
@ -220,7 +297,7 @@ class CalendarPage extends React.Component
) )
} }
return ( return (
<div key={ index } className={`grid_cell ${ day.date.month() !== month ? 'disabled' : '' } ${ day.date.format("YYYYMMDD") === moment().format("YYYYMMDD") ? 'current' : '' } `}> <div key={ index } className={`grid_cell ${ !perweek && day.date.month() !== month ? 'disabled' : '' } ${ day.date.format("YYYYMMDD") === moment().format("YYYYMMDD") ? 'current' : '' } `}>
<div className="cell_header"> <div className="cell_header">
<p><span>{ day.date.format("DD") }</span> { day.date.format("MMM").toLocaleLowerCase() } { day.date.format("Y").toLocaleLowerCase() }</p> <p><span>{ day.date.format("DD") }</span> { day.date.format("MMM").toLocaleLowerCase() } { day.date.format("Y").toLocaleLowerCase() }</p>
</div> </div>

View File

@ -1,33 +1,48 @@
import React from "react"; import React from "react";
import Link from "next/link"; import Link from "next/link";
const menu = [
{id: 1, name: "Календарь оплат", link: "/documents/calendar"},
{id: 2, name: "Акты сверок", link: "/documents/reconciliations"},
{id: 3, name: "Закрывающие документы", link: "/documents/finals"},
]
export default class InnerMenu extends React.Component export default class InnerMenu extends React.Component
{ {
constructor(props) constructor(props)
{ {
super(props); super(props);
this.menuList = React.createRef();
menu.forEach(item => {
this[item.id] = React.createRef();
});
} }
componentDidMount() {
}
scrollToCategory = id => {
};
render() render()
{ {
return ( return (
<aside> <aside>
<ul className="aside_nav"> <ul className="aside_nav" ref={this.menuList}>
<li> {menu.map(item => (
<Link href="/documents/calendar/"> <li key = {item.id} ref={this[item.id]} onClick={() => this.scrollToCategory(item.id)}>
<a className={ this.props.router && this.props.router.route === "/documents/calendar" ? "active" : "" }>Календарь оплат</a> <Link
</Link> href={item.link}
</li> shallow
<li> >
<Link href="/documents/reconciliations/"> <a className={ this.props.router && this.props.router.route === item.link ? "active" : "" }>{item.name}</a>
<a className={ this.props.router && this.props.router.route === "/documents/reconciliations" ? "active" : "" }>Акты сверок</a>
</Link>
</li>
<li>
<Link href="/documents/finals/">
<a className={ this.props.router && this.props.router.route === "/documents/finals" ? "active" : "" }>Закрывающие документы</a>
</Link> </Link>
</li> </li>
))}
</ul> </ul>
</aside> </aside>
) )

View File

@ -114,7 +114,7 @@ class FinalsPage extends React.Component
<SpinnerCircular size={90} thickness={51} speed={100} color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" /> <SpinnerCircular size={90} thickness={51} speed={100} color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" />
</div> </div>
) : ( ) : (
<div className="dosc_list"> <div className="dosc_list" style={ contracts !== undefined && contracts !== null && contracts.length > 0 ? {} : { display: "flex", justifyContent: "center" }}>
{ contracts !== undefined && contracts !== null && ( { contracts !== undefined && contracts !== null && (
<> <>
{ contracts.length > 0 ? contracts.map((contract, index) => ( { contracts.length > 0 ? contracts.map((contract, index) => (

View File

@ -14,7 +14,9 @@ import InnerMenu from "./components/InnerMenu";
import Company from "../components/Company"; import Company from "../components/Company";
import DateInput from '../components/DatePicker'; import DateInput from '../components/DatePicker';
import { getContractsList } from '../../actions'; import { getContractsList, getReconciliationFile } from '../../actions';
import { eachSeries } from "async";
class ReconciliationsPage extends React.Component class ReconciliationsPage extends React.Component
@ -27,6 +29,11 @@ class ReconciliationsPage extends React.Component
contracts: null, contracts: null,
checked: [], checked: [],
checked_all: true, checked_all: true,
valid_date_start: null,
valid_date_end: null,
period_date_start: null,
period_date_end: null,
reconciliation_requested: false,
} }
} }
@ -47,6 +54,22 @@ class ReconciliationsPage extends React.Component
}); });
} }
componentDidUpdate(prevProps, prevState)
{
if(prevState.contracts === null && this.state.contracts !== null)
{
const ds = this.state.contracts.length > 0 ? moment(this.state.contracts[ this.state.contracts.length-1 ].date).toDate() : moment().toDate();
const de = moment().toDate();
this.setState({
period_date_start: ds,
period_date_end: de,
valid_date_start: ds,
valid_date_end: de,
});
}
}
_handle_onAllContracts = () => _handle_onAllContracts = () =>
{ {
this.setState({ checked_all: this.state.checked_all ? false : true, checked: this.state.checked ? [] : this.state.checked }); this.setState({ checked_all: this.state.checked_all ? false : true, checked: this.state.checked ? [] : this.state.checked });
@ -80,9 +103,124 @@ class ReconciliationsPage extends React.Component
} }
} }
_handle_onPeriodDate_start = (date) =>
{
const { valid_date_start, valid_date_end, period_date_start, period_date_end } = this.state;
const md = moment(date, "DD.MM.YYYY");
if(md.isValid())
{
console.log(md);
console.log("vs", valid_date_start);
console.log("ve", valid_date_end);
if(date >= valid_date_start && date < valid_date_end)
{
console.log("ps", period_date_start);
if(date < period_date_end)
{
console.log(">>>>>");
this.setState({ period_date_start: date, reconciliation_disabled: false });
}
else
{
this.setState({ reconciliation_disabled: true });
}
}
else
{
this.setState({ reconciliation_disabled: true });
}
}
else
{
console.log("invalid date", md);
this.setState({ reconciliation_disabled: true });
}
}
_handle_onPeriodDate_end = (date) =>
{
const { valid_date_start, valid_date_end, period_date_start, period_date_end } = this.state;
if(moment(date).isValid())
{
if(date >= valid_date_start && date < valid_date_end)
{
if(date > period_date_start)
{
this.setState({ period_date_end: date, reconciliation_disabled: false });
}
else
{
this.setState({ reconciliation_disabled: true });
}
}
else
{
this.setState({ reconciliation_disabled: true });
}
}
else
{
this.setState({ reconciliation_disabled: true });
}
}
_handle_onReconciliationFiles = () =>
{
const { checked, checked_all, contracts, reconciliation_requested, period_date_start, period_date_end, } = this.state;
let list = [];
if(!reconciliation_requested)
{
if(checked_all)
{
for(let i in contracts)
{
list.push(contracts[i].number);
}
}
else
{
list = checked;
}
console.log(list);
const date_from = moment(period_date_start).format("YYYY-MM-DD");
const date_to = moment(period_date_end).format("YYYY-MM-DD");
this.setState({ reconciliation_requested: true }, () =>
{
eachSeries(list, (number, callback) =>
{
getReconciliationFile({
contract: number,
date_from: date_from,
date_to: date_to,
filename: `${ number }_reconciliation_${ date_from }_${ date_to }.pdf`,
})
.then(() =>
{
callback();
})
.catch(() =>
{
callback();
});
}, () =>
{
this.setState({ reconciliation_requested: false });
});
});
}
}
render() render()
{ {
const { loading, contracts, checked, checked_all, } = this.state; const { loading, contracts, checked, checked_all, valid_date_start, valid_date_end, period_date_start, period_date_end, reconciliation_disabled, reconciliation_requested } = this.state;
return ( return (
<React.Fragment> <React.Fragment>
@ -107,41 +245,53 @@ class ReconciliationsPage extends React.Component
<div className="aside_container about"> <div className="aside_container about">
<InnerMenu { ...this.props }/> <InnerMenu { ...this.props }/>
<article> <article>
<div className="acts_wrapper"> <div className="acts_wrapper" style={{ flex: 1, justifyContent: "center" }}>
<div className="dosc_list acts_list-checkbox"> { loading ? (
{ loading ? ( <div className="table_row table_header" style={{ minHeight: 300, display: "flex", justifyContent: "center", alignItems: "center" }}>
<div className="table_row table_header" style={{ minHeight: 300, 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)" />
<SpinnerCircular size={90} thickness={51} speed={100} color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" /> </div>
</div> ) : (
) : ( <>
<> { contracts !== undefined && contracts !== null && contracts.length > 0 ? (
<div className="row"> <>
<p className="doc_name"> <div className="dosc_list acts_list-checkbox">
<input type="checkbox" name="all" id="all" checked={ checked_all } onChange={ this._handle_onAllContracts } /> <div className="row">
<label htmlFor="all">Все договоры</label> <p className="doc_name">
</p> <input type="checkbox" name="all" id="all" checked={ checked_all } onChange={ this._handle_onAllContracts } />
</div> <label htmlFor="all">Все договоры</label>
{ contracts !== undefined && contracts !== null && contracts.map((contract, index) => ( </p>
<div className="row" key={ index }> </div>
<p className="doc_name i-pdf"> { contracts !== undefined && contracts !== null && contracts.map((contract, index) => (
<input type="checkbox" checked={ checked_all || checked.indexOf(contract.number) > -1 } name={ `contract_${ contract.number }` } id={ `contract_${ contract.number }` } onChange={ () => this._handle_onContract(contract.number) }/> <div className="row" key={ index }>
<label htmlFor={ `contract_${ contract.number }` }>{ contract.number } от { moment(contract.date).format("DD.MM.YYYY") }</label> <p className="doc_name i-pdf">
</p> <input type="checkbox" checked={ checked_all || checked.indexOf(contract.number) > -1 } name={ `contract_${ contract.number }` } id={ `contract_${ contract.number }` } onChange={ () => this._handle_onContract(contract.number) }/>
<label htmlFor={ `contract_${ contract.number }` }>{ contract.number } от { moment(contract.date).format("DD.MM.YYYY") }</label>
</p>
</div>
)) }
</div> </div>
)) } <div className="reconciliation_form small" style={{ alignContent: "flex-start" }}>
</> <div className="form_field">
) } <DateInput placeholder="Дата начала периода" value={ period_date_start } min={ valid_date_start } max={ valid_date_end } onChange={ this._handle_onPeriodDate_start }/>
</div> </div>
<div className="reconciliation_form small"> <div className="form_field">
<div className="form_field"> <DateInput placeholder="Дата окончания периода" value={ period_date_end } min={ valid_date_start } max={ valid_date_end } onChange={ this._handle_onPeriodDate_end }/>
<DateInput placeholder="Дата начала периода" /> </div>
</div> <button className="button button-blue" disabled={ reconciliation_disabled } onClick={ () => { this._handle_onReconciliationFiles() }}>
<div className="form_field"> <>
<DateInput placeholder="Дата окончания периода" /> { reconciliation_requested ? (
</div> <SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" />
<button className="button button-blue">Скачать</button> ) : "Скачать" }
{/*<button className="button button-blue">Отправить в ЭДО</button>*/} </>
</div> </button>
{/*<button className="button button-blue">Отправить в ЭДО</button>*/}
</div>
</>
) : (
<p>Нет договоров для запроса актов сверок</p>
) }
</>
) }
</div> </div>
</article> </article>
</div> </div>

View File

@ -6,12 +6,14 @@ import cookie from 'cookie';
import { connect } from "react-redux"; import { connect } from "react-redux";
import numeral from "numeral"; import numeral from "numeral";
import moment from 'moment'; import moment from 'moment';
import { SpinnerCircular } from 'spinners-react';
import { withRouter } from 'next/router'; import { withRouter } from 'next/router';
import { reduxWrapper } from '../store'; import { reduxWrapper } from '../store';
import Header from './components/Header'; import Header from './components/Header';
import Footer from './components/Footer'; import Footer from './components/Footer';
import Company from "./components/Company";
import DateInput from './components/DatePicker'; import DateInput from './components/DatePicker';
import Pagination from './components/Pagination'; import Pagination from './components/Pagination';
@ -24,7 +26,7 @@ class IndexPage extends React.Component
super(props); super(props);
this.state = { this.state = {
contracts: null, contracts: null,
order: "number", order: "date",
sort_number: "desc", sort_number: "desc",
sort_date: "desc", sort_date: "desc",
sort_status: "desc", sort_status: "desc",
@ -53,7 +55,7 @@ class IndexPage extends React.Component
{ {
this.setState({ loading: true }, () => this.setState({ loading: true }, () =>
{ {
getContractsList({ dispatch: this.props.dispatch }).then(() => { getContractsList({ dispatch: this.props.dispatch, order: this.state.order, sort: this.state.sort_number, }).then(() => {
this.setState({ loading: false }); this.setState({ loading: false });
}).catch(() => {}); }).catch(() => {});
}); });
@ -162,7 +164,15 @@ class IndexPage extends React.Component
<section> <section>
<div className="clear"></div> <div className="clear"></div>
<div className="container"> <div className="container">
<h1 className="section_title">Личный кабинет</h1> <div className="title_wrapper">
<div className="left">
<h1 className="section_title">Личный кабинет</h1>
</div>
<div className="right">
<Company/>
</div>
</div>
<div className="contract_search"> <div className="contract_search">
<form onSubmit={ (event) => { event.preventDefault(); } }> <form onSubmit={ (event) => { event.preventDefault(); } }>
<div className="form_field"> <div className="form_field">
@ -177,60 +187,66 @@ class IndexPage extends React.Component
} }/> } }/>
<label htmlFor="date_from">Дата<br/>договора от</label> <label htmlFor="date_from">Дата<br/>договора от</label>
*/} */}
<DateInput placeholder="Дата договора от" /> <DateInput placeholder="Дата договора от" id={ "date_from" } onChange={ (date) => this.setState({ date_from: date }) }/>
</div> </div>
<div className="form_field"> <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) => { {/*<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); this._handle_onChange_date_to(date);
} }/> } }/>
<label htmlFor="date_for">Дата<br/>договора по</label>*/} <label htmlFor="date_for">Дата<br/>договора по</label>*/}
<DateInput placeholder="Дата договора по" /> <DateInput placeholder="Дата договора по" id={ "date_to" } onChange={ (date) => this.setState({ date_to: date }) }/>
</div> </div>
<button className="button" disabled={ search !== "" || date_from !== "" || date_to !== "" ? false : true } onClick={ this._handle_onSearch }>Поиск</button> <button className="button" disabled={ search !== "" || date_from !== "" || date_to !== "" ? false : true } onClick={ this._handle_onSearch }>Поиск</button>
</form> </form>
</div> </div>
<div className="contract_table" style={ loading ? { opacity: 0.6 } : {} }> { loading ? (
<div className="table_row table_header"> <div className="table_row table_header" style={{ minHeight: 450, display: "flex", justifyContent: "center", alignItems: "center" }}>
<div className={`table_cell caret ${ sort_number === "asc" ? "reverse" : "" }`} onClick={ this._handle_onChangeSort_number }>Номер договора</div> <SpinnerCircular size={90} thickness={51} speed={100} color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" />
<div className={`table_cell caret ${ sort_date === "asc" ? "reverse" : "" }`} onClick={ this._handle_onChangeSort_date }>Дата договора</div>
<div className="table_cell">Автомобиль</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> </div>
{ contracts !== null && ( ) : (
<> <div className="contract_table">
{ contracts.length > 0 ? contracts.map((contract, index) => ( <div className="table_row table_header">
<Link href={`/contract/${ contract.number }/payments`}> <div className={`table_cell caret ${ sort_number === "asc" ? "reverse" : "" }`} onClick={ this._handle_onChangeSort_number }>Номер договора</div>
<div className="table_row" key={ index } style={{ cursor: "pointer" }}> <div className={`table_cell caret ${ sort_date === "asc" ? "reverse" : "" }`} onClick={ this._handle_onChangeSort_date }>Дата договора</div>
<div className="table_cell"><a>{ contract.number }</a></div> <div className="table_cell">Автомобиль</div>
<div className="table_cell">{ moment(contract.date).format("DD.MM.YYYY") }</div> <div className="table_cell">Гос.номер</div>
<div className="table_cell">{ contract.car?.brand?.name } { contract.car?.model?.name }</div> <div className="table_cell">VIN</div>
<div className="table_cell">{ contract.car?.reg_number !== null ? contract.car?.reg_number : "Без рег. номера" }</div> <div className={`table_cell caret ${ sort_status === "asc" ? "reverse" : "" }`} onClick={ this._handle_onChangeSort_status }>Статус</div>
<div className="table_cell">{ contract.car?.vin_number }</div> <div className="table_cell">Следующий платеж</div>
<div className="table_cell"><p className={ contract_status[contract.status] }>{ contract.status }</p></div> </div>
<div className="table_cell"> { contracts !== null && (
{ contract.current_payment_date !== null ? ( <>
<>{ moment(contract.current_payment_date).format("DD.MM.YYYY") }<b className="price">{ numeral(contract.current_payment_amount).format(' ., ') } </b></> { 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 : "Без рег. номера" }</div>
<div className="table_cell">{ contract.car?.vin_number }</div>
<div className="table_cell"><p className={ contract_status[contract.status] }>{ contract.status }</p></div>
<div className="table_cell">
{ contract.current_payment_date !== null ? (
<>{ moment(contract.current_payment_date).format("DD.MM.YYYY") }<b className="price">{ numeral(contract.current_payment_amount).format(' ., ') } </b></>
) : "-" }
</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>
</Link> ) }
)) : ( </>
<div className="table_row"> ) }
<div className="table_cell">-</div> </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 && ( { !all && (
<Pagination page={ page } pages={ pages } onPage={ this._handle_onPage } onAll={ this._handle_onAll } all={ all } showAll={ true }/> <Pagination page={ page } pages={ pages } onPage={ this._handle_onPage } onAll={ this._handle_onAll } all={ all } showAll={ true }/>
) } ) }

View File

@ -4,13 +4,14 @@ import Image from 'next/image';
import { connect } from "react-redux"; import { connect } from "react-redux";
import { withRouter } from 'next/router'; import { withRouter } from 'next/router';
import { reduxWrapper } from '../store'; import { reduxWrapper } from '../store';
import pluralize from 'pluralize-ru';
import Header from './components/Header'; import Header from './components/Header';
import Footer from './components/Footer'; import Footer from './components/Footer';
import MainHeader from "./components/MainHeader"; import MainHeader from "./components/MainHeader";
import FormRequest from "./components/FormRequest"; import FormRequest from "./components/FormRequest";
import { sendLoginFormEmail, sendLoginFormPhone } from '../actions'; import { sendLoginFormEmail, sendLoginFormPhone, sendSmsCode } from '../actions';
class LoginPage extends React.Component class LoginPage extends React.Component
{ {
@ -21,9 +22,22 @@ class LoginPage extends React.Component
email: "", email: "",
password: "", password: "",
phone: "", phone: "",
phone_code: "",
tab: "email", tab: "email",
company: {}, company: {},
email_error: false,
phone_form_step: 1,
phone_number_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,
}; };
this.timer_ref = null;
} }
static getDerivedStateFromProps(nextProps, prevState) static getDerivedStateFromProps(nextProps, prevState)
@ -38,7 +52,15 @@ class LoginPage extends React.Component
event.preventDefault(); event.preventDefault();
const { email, password, } = this.state; const { email, password, } = this.state;
sendLoginFormEmail({ email, password, dispatch: this.props.dispatch }); sendLoginFormEmail({ email, password, dispatch: this.props.dispatch })
.then(() =>
{
})
.catch(() =>
{
this.setState({ email_error: true });
});
} }
_handle_onPhoneSubmit = (event) => _handle_onPhoneSubmit = (event) =>
@ -46,7 +68,52 @@ class LoginPage extends React.Component
event.preventDefault(); event.preventDefault();
const { phone, } = this.state; const { phone, } = this.state;
sendLoginFormPhone({ phone }); sendLoginFormPhone({ phone })
.then(() =>
{
this.setState({ 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 });
});
}
_handle_onCodeSubmit = (event) =>
{
event.preventDefault();
const { phone, phone_code } = this.state;
sendSmsCode({ dispatch: this.props.dispatch, phone, code: phone_code })
.then(() =>
{
this.setState({ phone_sms_code_error: false });
})
.catch(() =>
{
this.setState({ phone_sms_code_error: true });
});
}
_handle_onResendCode = (event) =>
{
this.setState({ phone_sms_code_error: false }, () =>
{
this._handle_onPhoneSubmit(event);
});
} }
_handle_onChangeTab = (tab) => _handle_onChangeTab = (tab) =>
@ -54,9 +121,42 @@ class LoginPage extends React.Component
this.setState({ tab: tab }); this.setState({ tab: tab });
} }
_handle_onEmailChange = (value) =>
{
this.setState({ email: value, email_login_disabled: this._check_fields_disabled([ value, this.state.password ]) });
}
_handle_onPasswordChange = (value) =>
{
this.setState({ password: value, email_login_disabled: this._check_fields_disabled([ value, this.state.email ]) });
}
_handle_onPhoneChange = (value) =>
{
this.setState({ phone: value, phone_login_disabled: this._check_fields_disabled([ value ]) });
}
_handle_onPhoneCodeChange = (value) =>
{
this.setState({ phone_code: value, phone_code_submit_disabled: this._check_fields_disabled([ value ]) });
}
_check_fields_disabled = (values) =>
{
for(let i in values)
{
if(values[i] === "")
{
return true;
}
}
return false;
}
render() render()
{ {
const { email, password, phone, tab } = this.state; 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 } = this.state;
return ( return (
<React.Fragment> <React.Fragment>
@ -84,21 +184,49 @@ class LoginPage extends React.Component
{ tab === "email" ? ( { tab === "email" ? (
<form onSubmit={ this._handle_onEmailSubmit }> <form onSubmit={ this._handle_onEmailSubmit }>
<div className="form_field"> <div className="form_field">
<input type="text" name="email" value={ email } placeholder="Введите логин" onChange={ (event) => this.setState({ email: event.target.value }) }/> <input type="text" name="email" value={ email } placeholder="Введите адрес E-mail" onChange={ (event) => this._handle_onEmailChange(event.target.value) } required={ true }/>
</div> </div>
<div className="form_field"> <div className="form_field">
<input type="password" name="password" value={ password } placeholder="Введите пароль" onChange={ (event) => this.setState({ password: event.target.value }) }/> <input type="password" name="password" value={ password } placeholder="Введите пароль" onChange={ (event) => this._handle_onPasswordChange(event.target.value) } required={ true }/>
</div> </div>
<button type="submit" className="button button-blue">Войти</button> <button type="submit" className="button button-blue" disabled={ email_login_disabled }>Войти</button>
<p>{ email_error ? 'Ошибка: Неверный логин или пароль' : `\u00A0` }</p>
</form> </form>
) : ( ) : (
<form onSubmit={ this._handle_onPhoneSubmit }> <>
<div className="form_field"> { phone_form_step === 1 && (
<input type="text" name="phone" value={ phone } placeholder="Введите номер телефона" onChange={ (event) => this.setState({ phone: event.target.value }) }/> <>
</div> <form onSubmit={ this._handle_onPhoneSubmit }>
<button type="submit" className="button button-blue" disabled>Получить код</button> <div className="form_field">
</form> <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 }>Получить код</button>
</form>
<p>{ phone_number_error ? 'Ошибка: нет аккаунта с таким номером телефона' : `\u00A0` }</p>
</>
) }
{ phone_form_step === 2 && (
<>
<p className="message">На номер <strong>+{ phone }</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 }>Отправить код</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>
</div> </div>
</section> </section>

View File

@ -31,11 +31,12 @@ const contractReducer = (state = initialState.contract, action) =>
}; };
} }
case actionTypes.CONTRACT_DATE: case actionTypes.CONTRACT_INFO:
{ {
return { return {
...state, ...state,
date: action.data.date, date: action.data.date,
car: action.data.car,
}; };
} }
@ -87,6 +88,14 @@ const contractReducer = (state = initialState.contract, action) =>
}; };
} }
case actionTypes.CONTRACT_RULES:
{
return {
...state,
rules: action.data.rules,
};
}
default: { default: {
return state; return state;
} }

View File

@ -23,12 +23,14 @@ export const defaultState = {
contract: { contract: {
payments: null, payments: null,
date: null, date: null,
car: null,
insurance: null, insurance: null,
helpcard: null, helpcard: null,
registration: null, registration: null,
telematic: null, telematic: null,
agreement: null, agreement: null,
documents: null, documents: null,
rules: null,
}, },
calendar: { calendar: {
payments: null, payments: null,

2
start.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
PORT=3000 yarn --cwd /home/bitrix/evolution-account/ start

View File

@ -0,0 +1,79 @@
function RenderMedia({ mobile, tablet, desktop, hd })
{
if(typeof window !== "undefined")
{
const variants = { mobile, tablet, desktop, hd };
const keys = ["hd", "desktop", "tablet", "mobile"];
if(window.matchMedia('(min-width: 1281px)').matches)
{
for(let i in keys)
{
if(variants[keys[i]] !== undefined && variants[keys[i]] !== null)
{
return variants[keys[i]];
}
}
}
if(window.matchMedia('(min-width: 1079px)').matches)
{
let k = keys.slice(1, keys.length);
for(let i in k)
{
if(variants[k[i]] !== undefined && variants[k[i]] !== null)
{
return variants[k[i]];
}
}
}
if(window.matchMedia('(min-width: 737px)').matches)
{
let k = keys.slice(2, keys.length);
for(let i in k)
{
if(variants[k[i]] !== undefined && variants[k[i]] !== null)
{
return variants[k[i]];
}
}
}
if(window.matchMedia('(max-width: 736px)').matches)
{
let k = keys.slice(3, keys.length);
for(let i in k)
{
if(variants[k[i]] !== undefined && variants[k[i]] !== null)
{
return variants[k[i]];
}
}
}
}
return null;
}
function MatchMedia()
{
if(typeof window !== "undefined")
{
if(window.matchMedia('(min-width: 1281px)').matches)
{ return "hd"; }
if(window.matchMedia('(min-width: 961px)').matches)
{ return "desktop"; }
if(window.matchMedia('(min-width: 769px)').matches)
{ return "tablet"; }
if(window.matchMedia('(max-width: 768px)').matches)
{ return "mobile"; }
}
return null;
}
export { RenderMedia, MatchMedia };

105
yarn.lock
View File

@ -749,6 +749,11 @@ chalk@^4.0.0:
ansi-styles "^4.1.0" ansi-styles "^4.1.0"
supports-color "^7.1.0" supports-color "^7.1.0"
charenc@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
chokidar@3.5.1: chokidar@3.5.1:
version "3.5.1" version "3.5.1"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"
@ -806,6 +811,11 @@ clone-deep@^4.0.1:
kind-of "^6.0.2" kind-of "^6.0.2"
shallow-clone "^3.0.0" shallow-clone "^3.0.0"
cluster-key-slot@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d"
integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==
color-convert@^1.9.0: color-convert@^1.9.0:
version "1.9.3" version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@ -935,6 +945,11 @@ cross-spawn@^7.0.2:
shebang-command "^2.0.0" shebang-command "^2.0.0"
which "^2.0.1" which "^2.0.1"
crypt@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
crypto-browserify@3.12.0, crypto-browserify@^3.11.0: crypto-browserify@3.12.0, crypto-browserify@^3.11.0:
version "3.12.0" version "3.12.0"
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
@ -1024,6 +1039,11 @@ define-properties@^1.1.3:
dependencies: dependencies:
object-keys "^1.0.12" object-keys "^1.0.12"
denque@^1.1.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.1.tgz#07f670e29c9a78f8faecb2566a1e2c11929c5cbf"
integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==
depd@~1.1.2: depd@~1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@ -1838,6 +1858,23 @@ invariant@^2.2.4:
dependencies: dependencies:
loose-envify "^1.0.0" loose-envify "^1.0.0"
ioredis@^4.28.2:
version "4.28.2"
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.28.2.tgz#493ccd5d869fd0ec86c96498192718171f6c9203"
integrity sha512-kQ+Iv7+c6HsDdPP2XUHaMv8DhnSeAeKEwMbaoqsXYbO+03dItXt7+5jGQDRyjdRUV2rFJbzg7P4Qt1iX2tqkOg==
dependencies:
cluster-key-slot "^1.1.0"
debug "^4.3.1"
denque "^1.1.0"
lodash.defaults "^4.2.0"
lodash.flatten "^4.4.0"
lodash.isarguments "^3.1.0"
p-map "^2.1.0"
redis-commands "1.7.0"
redis-errors "^1.2.0"
redis-parser "^3.0.0"
standard-as-callback "^2.1.0"
is-arguments@^1.0.4: is-arguments@^1.0.4:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b"
@ -1868,6 +1905,11 @@ is-boolean-object@^1.1.0:
call-bind "^1.0.2" call-bind "^1.0.2"
has-tostringtag "^1.0.0" has-tostringtag "^1.0.0"
is-buffer@~1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
is-callable@^1.1.4, is-callable@^1.2.4: is-callable@^1.1.4, is-callable@^1.2.4:
version "1.2.4" version "1.2.4"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
@ -2157,11 +2199,26 @@ lodash.camelcase@^4.3.0:
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY=
lodash.defaults@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=
lodash.flatten@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
lodash.includes@^4.3.0: lodash.includes@^4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
lodash.isarguments@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=
lodash.isboolean@^3.0.3: lodash.isboolean@^3.0.3:
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
@ -2232,6 +2289,15 @@ md5.js@^1.3.4:
inherits "^2.0.1" inherits "^2.0.1"
safe-buffer "^5.1.2" safe-buffer "^5.1.2"
md5@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==
dependencies:
charenc "0.0.2"
crypt "0.0.2"
is-buffer "~1.1.6"
merge-stream@^2.0.0: merge-stream@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
@ -2608,6 +2674,11 @@ p-locate@^4.1.0:
dependencies: dependencies:
p-limit "^2.2.0" p-limit "^2.2.0"
p-map@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
p-try@^1.0.0: p-try@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
@ -2716,6 +2787,11 @@ platform@1.3.6:
resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7" resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7"
integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg== integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==
pluralize-ru@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/pluralize-ru/-/pluralize-ru-1.0.1.tgz#92c09ced46089b268a530fa895e6b9ec04fe7795"
integrity sha1-ksCc7UYImyaKUw+olea57AT+d5U=
pnp-webpack-plugin@1.6.4: pnp-webpack-plugin@1.6.4:
version "1.6.4" version "1.6.4"
resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149"
@ -2796,6 +2872,13 @@ punycode@^2.1.0:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
qs@^6.10.1:
version "6.10.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a"
integrity sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==
dependencies:
side-channel "^1.0.4"
querystring-es3@0.2.1, querystring-es3@^0.2.0: querystring-es3@0.2.1, querystring-es3@^0.2.0:
version "0.2.1" version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
@ -2973,6 +3056,23 @@ really-small-events@^1.1.0:
resolved "https://registry.yarnpkg.com/really-small-events/-/really-small-events-1.1.0.tgz#ad35eb0afa956c76838c926c8f6734db8524e946" resolved "https://registry.yarnpkg.com/really-small-events/-/really-small-events-1.1.0.tgz#ad35eb0afa956c76838c926c8f6734db8524e946"
integrity sha512-iyh4pULyDYBMecekEYcP3ToJD3ZUdIPfZV9nx1C1lJfMguElkDAZvEMJegy8uE7eIROCuLsqh5r44fVro9nKFg== integrity sha512-iyh4pULyDYBMecekEYcP3ToJD3ZUdIPfZV9nx1C1lJfMguElkDAZvEMJegy8uE7eIROCuLsqh5r44fVro9nKFg==
redis-commands@1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89"
integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==
redis-errors@^1.0.0, redis-errors@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad"
integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=
redis-parser@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4"
integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=
dependencies:
redis-errors "^1.0.0"
redux-persist@^6.0.0: redux-persist@^6.0.0:
version "6.0.0" version "6.0.0"
resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8" resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8"
@ -3190,6 +3290,11 @@ stacktrace-parser@0.1.10:
dependencies: dependencies:
type-fest "^0.7.1" type-fest "^0.7.1"
standard-as-callback@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45"
integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==
"statuses@>= 1.5.0 < 2": "statuses@>= 1.5.0 < 2":
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"