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) =>
{
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) =>
{
console.log("sendTermsForm RESPONSE");
console.log(response.data);
if(response.data.status)
if(response.data)
{
console.log("DATA? ");
resolve();
}
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();
}
})
.catch((error) =>
{
console.log("DATA !!! ");
console.log("error");
console.error(error);
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 }) =>
{
console.log("getCalendar");
console.log("getCalendar", date_from, date_to);
return new Promise((resolve, reject) =>
{
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 currentState from '../reducers/initialState';
import { eachSeries } from 'async';
if(process.browser)
{
@ -62,9 +63,10 @@ export const getContractInfo = ({ dispatch, number, }) =>
})
.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) =>
{
@ -204,9 +206,75 @@ export const getContractDocuments = ({ dispatch, number, }) =>
{
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();
})

View File

@ -41,8 +41,16 @@ export const getContractsList = ({ dispatch, order = "date", sort = "desc", page
orderBy[order] = sort;
const offset = (page - 1) * page_size;
let query = nSQL(response.data).query("select");
let query_total = nSQL(response.data).query("select", ["COUNT(*) AS total"]);
const contracts = [];
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 !== "")
{
@ -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 }%`]])
}
/*
if(date_from !== undefined && date_from !== null && date_from !== "")
{
query = query.where([["date", ">=", `%${ date_from }%`]]);
query_total = query_total.where([["date", ">=", `%${ date_from }%`]])
query = query.where([[ "js_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)
{

View File

@ -92,4 +92,45 @@ export const getReconciliationFile = ({ contract, date_from, date_to, filename }
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 './calendarActions';
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 CONTRACT = 'CONTRACT';
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_HELPCARD = 'CONTRACT_HELPCARD';
export const CONTRACT_REGISTRATION = 'CONTRACT_REGISTRATION';
export const CONTRACT_TELEMATIC = 'CONTRACT_TELEMATIC';
export const CONTRACT_AGREEMENT = 'CONTRACT_AGREEMENT';
export const CONTRACT_DOCUMENTS = 'CONTRACT_DOCUMENTS';
export const CONTRACT_RULES = 'CONTRACT_RULES';
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":"AACA,eACE,YAAA,CACA,cAAA,CACA,UAAA,CACA,gBAAA,CACA,2BAAA,CACA,iBAAA,CACE,UAPJ,cAUE,qBACE,sBAXJ,cAUE,oBAGE,GACE,oBAAA,CACA,sBAEA,cAPJ,oBAGE,EAIG,OACC,WAQJ,cAhBF,oBAgBG,QACC,QAAS,GAAT,CACA,oBAAA,CACA,aAIJ,gBAAmC,kBAAnC,eACE,MAAO,kBAAP,CACA,6BAGF,gBAAkC,iBAAlC,eACE,6BAGF,gBAAkC,iBAAlC,eACE,2BAAA,CACA,MAAO,mBAKX,GACE,aAAA,CACA,UAAA,CACA,UAAA,CACA,kBAAA,CACA,QAAA,CACA,cAIF,OACA,QACE,QAAA,CACA,sBAAA,CACA,eAAA,CACA,eAAA,CACA,cAAA,CACA,qBAAA,CACA,gBAAA,CACA,mBAAA,CACA,kBAAA,CACA,sBAAA,CACA,WAAA,CACA,eAAA,CACA,cAAA,CACA,iBAEA,gBAAmC,kBAAnC,OAAA,QACE,gBAIJ,QACE,MAAO,WAAP,CACA,gBAGA,OAAC,UACC,WAAA,CACA,eAIA,OADD,KACE,QACC,QAAS,EAAT,CACA,aAAA,CACA,UAAA,CACA,WAAA,CACA,kBAIJ,OAAC,aACC,WAAY,WAAZ,CACA,WAEA,OAJD,YAIE,KAAK,QACJ,eAAgB,4DAGlB,OARD,YAQE,aACC,MAAO,WAAP,CACA,uBAEA,OAZH,YAQE,YAIE,KAAK,QACJ,eAAgB,2DAKtB,OAAC,aACC,MAAO,WAAP,CACA,WAAY,kBAEZ,OAJD,YAIE,aACC,MAAO,WAAP,CACA,uBAGF,OATD,YASE,KAAK,QACJ,eAAgB,2DAIpB,OAAC,gBACC,UAAA,CACA,WAAA,CACA,mBAAA,CACA,gBAEA,OAND,eAME,KAAK,QACJ,eAKF,gBAAkC,iBAAlC,OADD,eAEG,UAAA,CACA,WAAA,CACA,eAAgB,0DAAhB,CACA,eAAA,CACA,oBAMN,KAAK,kBACH,YAAA,CACA,kBAEA,KAJG,iBAID,OACA,YAAA,CACA,kBAAA,CACA,eAGA,KAVC,iBAID,MAMC,QACC,QAAS,EAAT,CACA,aAAA,CACA,UAAA,CACA,cAAA,CACA,WAAA,CACA,mCAAA,CACA,qBAAA,CACA,iBAAA,CACA,kBAKF,KAxBC,iBAuBF,QAAS,MACP,QACC,eAAgB,4DAA4D,cAA5E,CACA,aAAc,eAIhB,KA9BC,iBA6BF,SAAU,MACR,QACC,eAAgB,2DAA2D,iBAA3E,CACA,YAKN,KAAK,eACH,YAAA,CACA,kBAEA,KAJG,cAID,OACA,aAAA,CACA,iBAAA,CACA,eAEA,KATC,cAID,MAKC,QACC,QAAS,EAAT,CACA,aAAA,CACA,mCAAA,CACA,qBAAA,CACA,mBAKF,KAnBC,cAkBF,QAAS,MACP,QACC,gBAIF,KAxBC,cAuBF,SAAU,MACR,QACC,WAAa,WAAb,CACA,YAMN,eACE,YAAA,CACA,kBAAA,CACA,sBAAA,CACA,WAAY,iBAAZ,CACA,qBAAA,CACA,cANF,cAQE,KACE,UAAA,CACA,WAAA,CACA,gBAAA,CACA,sBAAA,CACA,iBAbJ,cAgBE,SACE,eAAA,CACA,UAAA,CACA,WAAA,CACA,eAAgB,yDAKpB,aACE,eAAA,CACA,eAAA,CACA,wBAHF,YAKE,IACE,iBAGF,YAAC,kBACC,eAEA,gBAAkC,iBAAlC,YAHD,kBAIG,gBAIJ,YAAC,kBACC,eAEA,gBAAkC,iBAAlC,YAHD,kBAIG,gBAMN,YACE,kBADF,WAGE,QACE,iBAAA,CACA,KAAA,CACA,OAAA,CACA,UAAA,CACA,WAAA,CACA,eAAgB,yDAAhB,CACA,UAVJ,WAaE,OAbF,WAaS,UAbT,WAamB,QACf,mCAAA,CACA,qBAAA,CACA,WAAA,CACA,eAAA,CACA,cAAA,CACA,UAAA,CACA,YAAA,CACA,eAEA,WAVF,MAUG,cAAD,WAVK,SAUJ,cAAD,WAVe,OAUd,cACC,cAAA,CACA,gBAAA,CACA,aAAA,CACA,YAAa,uBAAb,CACA,gBAGF,WAlBF,MAkBG,OAAD,WAlBK,SAkBJ,OAAD,WAlBe,OAkBd,OACC,aAAc,WAGhB,WAtBF,MAsBG,QAAD,WAtBK,SAsBJ,QAAD,WAtBe,OAsBd,QACC,gCAGF,WA1BF,MA0BG,UAAD,WA1BK,SA0BJ,UAAD,WA1Be,OA0Bd,UACC,WAAY,kBAGd,WA9BF,MA8BG,gBAAD,WA9BK,SA8BJ,gBAAD,WA9Be,OA8Bd,gBACC,iBAAA,CACA,qBAAsB,uCAAtB,CACA,2BAAA,CACA,4BAGF,WArCF,MAqCG,cAAD,WArCK,SAqCJ,cAAD,WArCe,OAqCd,cACD,WAtCF,MAsCG,YAAD,WAtCK,SAsCJ,YAAD,WAtCe,OAsCd,YACC,iBAAA,CACA,qBAAsB,qCAAtB,CACA,2BAAA,CACA,4BAEA,WA5CJ,MAqCG,aAOE,4BAAD,WA5CG,SAqCJ,aAOE,4BAAD,WA5Ca,OAqCd,aAOE,4BAAD,WA5CJ,MAsCG,WAME,4BAAD,WA5CG,SAsCJ,WAME,4BAAD,WA5Ca,OAsCd,WAME,4BACD,WA7CJ,MAqCG,aAQE,oCAAD,WA7CG,SAqCJ,aAQE,oCAAD,WA7Ca,OAqCd,aAQE,oCAAD,WA7CJ,MAsCG,WAOE,oCAAD,WA7CG,SAsCJ,WAOE,oCAAD,WA7Ca,OAsCd,WAOE,oCACC,YAAA,CACA,wBAKJ,gBAAkC,iBAAlC,WApDF,OAoDE,WApDK,UAoDL,WApDe,QAqDb,gBAlEN,WAwEE,QACE,qBAAsB,uCAAtB,CACA,2BAAA,CACA,oBAAqB,qBAArB,CACA,uBAAA,CACA,qBAEA,WAPF,OAOG,aACC,aAhFN,WAoFE,UACE,gBAAA,CACA,YAIJ,YACE,YAAA,CACA,8BAKF,SACE,aADF,QAGE,GACE,aAAA,CACA,UAAA,CACA,WAAA,CACA,qBAEA,QANF,EAMG,IAAI,cACH,kBAEA,gBAAmC,kBAAnC,QATJ,EAMG,IAAI,cAID,kBAOR,MACE,aADF,KAGE,MACE,gBAAA,CACA,gBAAA,CACA,cAAA,CACA,eAEA,KANF,KAMG,QACC,WAAY,WAAZ,CACA,UAAA,CACA,eAAA,CACA,eAGF,gBAAkC,iBAAlC,KAbF,MAcI,cAAA,CACA,iBAEA,KAjBJ,KAiBK,QACC,iBAIJ,gBAAkC,iBAAlC,KAtBF,MAuBI,cAAA,CACA,gBAMN,YACE,gBADF,WAGE,IACE,YAAA,CACA,oBAAA,CACA,yBANJ,WAGE,GAKE,IACE,cAAA,CACA,gBAAA,CACA,MAAO,YAXb,WAGE,GAKE,GAKE,GACE,aAAA,CACA,cAKN,gBAAmC,kBAAnC,WACE,IACE,uBAFJ,WACE,GAGE,IACE,cAAA,CACA,gBAAA,CACA,eAPN,WACE,GAGE,GAKE,GACE,iBAAA,CACA,iBAQV,YACE,UAAA,CACA,kBAAA,CACA,YAAA,CACA,WAAY,kBAJd,WAME,KACE,UAAA,CACA,WAAA,CACA,iBAKJ,EAAE,aACA,eAAA,CACA,UAFF,EAAE,YAIA,IACE,iBAAA,CACA,kBAEA,EARF,YAIA,GAIG,QACC,QAAS,EAAT,CACA,aAAA,CACA,iBAAA,CACA,SAAA,CACA,UAAA,CACA,eAAA,CACA,iBAAA,CACA,OAAA,CACA,SAON,oBACE,kBADF,mBAGE,mBACE,mCAAA,YACA,0BAAA,CACA,qBAAA,CACA,WAAA,CACA,eAAA,CACA,eAAA,CAEA,UAAA,CACA,YAAA,CACA,eAbJ,mBAeE,kBACE,qBAAA,CACA,YAAA,CACA,0BAAA,CACA,SAnBJ,mBAsBE,gBAAe,eACb,QAAA,CACA,UAAA,CACA,qBAAsB,qCAAtB,CACA,2BAAA,CACA,2BAAA,CACA,iBAAA,CACA,KAAA,CACA,MAAA,CACA,YAEA,mBAXF,gBAAe,cAWZ,OACC,6BAlCN,mBAsBE,gBAAe,cAeb,KACE"}
{"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;
overflow: hidden;
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) {
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;
width: ~"calc(45% - 8px)";
@ -720,7 +733,7 @@
width: 100%;
background: #fff;
margin: 100px auto;
padding: 45px 80px;
padding: 45px 40px;
.modal_footer {
text-align: right;
@ -758,7 +771,7 @@
}
}
button {
button.button {
margin-top: 15px;
width: ~"calc(45% - 8px)";
@ -796,7 +809,7 @@
width: 100%;
background: #fff;
margin: 100px auto;
padding: 45px 80px;
padding: 45px 40px;
.modal_footer {
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 {
overflow: hidden;
padding-top: 112px;
@media all and (max-width: 1280px) {
@ -64,7 +63,11 @@ main {
.left {
display: flex;
max-width: 70%;
@media all and (max-width: 768px) {
max-width: none;
}
}
.right {
@ -1645,6 +1648,7 @@ main {
font-size: 26px;
line-height: 35px;
font-weight: 700;
min-width: 15%;
}
ul {
@ -1655,14 +1659,31 @@ main {
margin-bottom: 6px;
}
}
@media all and (max-width: 767px) {
display: block;
.title {
font-size: 19px;
line-height: 26px;
}
ul {
margin-left: 0;
}
}
}
}
&.open {
.block_header {
button {
button:not(.rotate) {
background: url("/assets/images/icons/close-blue.svg") no-repeat center;
}
button.rotate {
transform: rotate(180deg);
}
}
.block_body {
@ -2398,8 +2419,8 @@ main {
.table_cell {
padding: 16px 8px;
border: 1px solid #EDEFF5;
width: 14%;
min-width: 14%;
width: 13%;
min-width: 13%;
&:nth-child(3) {
width: 16%;
@ -2407,7 +2428,8 @@ main {
}
&:nth-child(5) {
word-break: break-all;
//word-break: break-all;
width: 19%;
}
p {
@ -2934,6 +2956,10 @@ main {
line-height: 28px;
text-align: right;
}
&:disabled {
opacity: 0.3;
}
}
}
}

View File

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

View File

@ -1,302 +1 @@
: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;
}
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;
}
}
: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 */

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;
}
html {
@media all and (max-width: 1420px) and (min-width: 1280px) {
zoom: 0.7;
.container, .bx-breadcrumb {
margin-left: auto;
margin-right: auto;
}
}
}
body {
font-size: 15px;
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",
"cookie": "^0.4.1",
"cors": "^2.8.5",
"ioredis": "^4.28.2",
"js-file-download": "^0.4.12",
"jsonwebtoken": "^8.5.1",
"md5": "^2.3.0",
"moment": "^2.29.1",
"next": "11.1.2",
"next-fonts": "^1.5.1",
@ -24,6 +26,8 @@
"next-with-less": "^1.0.1",
"nextjs-cors": "^2.1.0",
"numeral": "^2.0.6",
"pluralize-ru": "^1.0.1",
"qs": "^6.10.1",
"react": "17.0.2",
"react-cookie": "^4.1.1",
"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 });
const result = {
upd: null,
fines: null,
upd: [],
upd_avans: [],
fines: [],
};
await Promise.all([
@ -29,7 +30,23 @@ export default async function handler(req, res)
params: { ...client_jwt_decoded, contract_number: req.body.number },
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(); });
}),
new Promise((resolve) => {

View File

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

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 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
{

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 "react-widgets/styles.css";
const messages = {
moveToday: "Сегодня",
moveBack: "Назад",
moveForward: "Вперед",
dateButton: "Выбрать дату",
};
const formats = [
'DD.MM.YYYY'
];
export default class DateInput extends React.Component
{
constructor(props)
{
super(props);
this.state = {
readonly: true,
}
}
_handle_onChange = (date) =>
{
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()
{
return (
const { id, placeholder, value, min, max } = this.props;
const { readonly } = this.state;
return (
<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>
)
}

View File

@ -1,7 +1,7 @@
import React from "react";
import { SpinnerCircular } from 'spinners-react';
import { getFile } from "../../../actions";
import { getFile, getBitrixFile } from "../../../actions";
export default class DownloadPdfButton extends React.Component
{
@ -15,22 +15,25 @@ export default class DownloadPdfButton extends React.Component
_handle_onDownloadFile = () =>
{
const { id, filename } = this.props;
const { id, filename, url, bitrix } = this.props;
const { downloading } = this.state;
if(!downloading)
{
this.setState({ downloading: true }, () =>
{
getFile({ id, filename })
.then(() =>
if(bitrix)
{
this.setState({ downloading: false });
})
.catch(() =>
getBitrixFile({ url, filename })
.then(() => { this.setState({ downloading: false }); })
.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;
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 ? (
<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 axios from 'axios';
import { getPrograms } from "../../../actions";
export default function Footer()
export default class Footer extends React.Component
{
return (
<footer>
<div className="container">
<ul className="column">
<li><b>Программы</b></li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/lizing_dlja_ul_i_ip`}>
<a>Лизинг для ЮЛ и ИП</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/legkovye_avtomobili`}>
<a>Легковые автомобили</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/legkij_kommercheskij_transport`}>
<a>Легкий коммерческий транспорт</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/gruzovoj_transport`}>
<a>Грузовой транспорт</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/spectehnika`}>
<a>Спецтехника</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/lizing_taksi`}>
<a>Лизинг такси</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/lizing_avto_s_probegomja`}>
<a>Лизинг авто с пробегом</a>
</Link>
</li>
</ul>
<ul className="column">
<li><b>Каталог техники</b></li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/catalog/legkovye`}>
<a>Легковые</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/catalog/legkij_kommercheskij_transport`}>
<a>Легкий коммерческий транспорт</a>
</Link>
</li>
</ul>
<ul className="column">
<li><b>О компании</b></li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/news`}>
<a>Новости</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/career`}>
<a>Карьера</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/contacts`}>
<a>Контакты</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/requisites`}>
<a>Реквизиты</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/rules`}>
<a>Общие условия лизинга</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/retmination`}>
<a>Отзыв доверенности</a>
</Link>
</li>
</ul>
<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>
constructor(props)
{
super(props);
this.state = {
programs: [],
}
}
componentDidMount()
{
getPrograms().then((programs) => this.setState({ programs: programs })).catch(() => {});
}
render()
{
const { programs } = this.state;
return (
<footer>
<div className="container">
<ul className="column">
<li><b>Программы</b></li>
{ programs.map((program, index) => (
<li key={ index }>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/programs/${ program.code }/`}>
<a>{ program.name }</a>
</Link>
</li>
))}
</ul>
<ul className="column">
<li><b>Каталог техники</b></li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/catalog/`}>
<a>Легковые</a>
</Link>
</li>
{/*}
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/catalog/legkij_kommercheskij_transport`}>
<a>Легкий коммерческий транспорт</a>
</Link>
</li>
{*/}
</ul>
<ul className="column">
<li><b>О компании</b></li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/news`}>
<a>Новости</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/career`}>
<a>Карьера</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/contacts`}>
<a>Контакты</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/requisites`}>
<a>Реквизиты</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/rules`}>
<a>Общие условия лизинга</a>
</Link>
</li>
<li>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/revocation`}>
<a>Отзыв доверенности</a>
</Link>
</li>
</ul>
<div className="column">
<div>
<a href="mailto:">info@evoleasing.ru</a>
</div>
<div>
<a href="tel:88003337575">8 800 333 75 75</a>
</div>
<div className="socials">
<a href="https://www.instagram.com/evoleasing/" target="_blank" rel="nofollow noopener">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<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"
fill="#8E94A7" />
</svg>
</a>
</Link>
<Link href="#">
<a>
<a href="https://www.facebook.com/evoleasing" target="_blank" rel="nofollow noopener">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<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"
fill="#8E94A7" />
</svg>
</a>
</Link>
</div>
<p>© ООО "ЛК Эволюция"</p>
<div>
<Link href="#">
<a>Обработка персональных данных</a>
</Link>
</div>
<div>
<Link href="#">
<a>Общие условия договора лизинга</a>
</Link>
<a href="https://vk.com/evoleasing" target="_blank" rel="nofollow noopener">
<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>
</a>
</div>
<p>© ООО "ЛК Эволюция"</p>
<div>
<a href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/upload/docs/personal_date_policy.pdf`} target="_blank">
Обработка персональных данных
</a>
</div>
<div>
<Link href={`${ process.env.NEXT_PUBLIC_MAIN_SITE }/about/rules/`}>
<a>Общие условия договора лизинга</a>
</Link>
</div>
</div>
</div>
</div>
</footer>
)
</footer>
)
}
}

View File

@ -1,14 +1,44 @@
import React from "react";
import { sendLeasingOrder } from "../../../actions";
export default class FormRequest extends React.Component
{
constructor(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()
{
const { name, phone, email, company, success } = this.state;
return (
<section id="order">
<div className="container wide">
@ -17,24 +47,32 @@ export default class FormRequest extends React.Component
<div className="order_email">
<p>Напишите на <a href="mailto:">info@evoleasing.ru</a> или заполните форму</p>
</div>
<form>
<div className="form_field">
<input type="text" value="" placeholder="Имя" onChange={ () => {} }/>
</div>
<div className="form_field">
<input type="tel" value="" placeholder="Телефон" onChange={ () => {} }/>
</div>
<div className="form_field">
<input type="email" value="" placeholder="E-mail" onChange={ () => {} }/>
</div>
<div className="form_field">
<input type="text" value="" placeholder="Организация" onChange={ () => {} }/>
</div>
<div className="policy">
<input type="checkbox" name="policy" id="policy" hidden checked onChange={ () => {} }/>
<label htmlFor="policy">Даю свое согласие на обработку моих персональных данных</label>
</div>
<button className="button">Отправить</button>
<form onSubmit={ (event) => this._onFormSubmit(event) }>
{ !success ? (
<>
<div className="form_field">
<input type="text" value={ name } placeholder="Имя" onChange={ (event) => this.setState({ name: event.target.value }) } required={ true }/>
</div>
<div className="form_field">
<input type="tel" value={ phone } placeholder="Телефон" onChange={ (event) => this.setState({ phone: event.target.value }) } required={ true }/>
</div>
<div className="form_field">
<input type="email" value={ email } placeholder="E-mail" onChange={ (event) => this.setState({ email: event.target.value }) } required={ true }/>
</div>
<div className="form_field">
<input type="text" value={ company } placeholder="Организация" onChange={ (event) => this.setState({ company: event.target.value }) }/>
</div>
<div className="policy">
<input type="checkbox" name="policy" id="policy" hidden checked onChange={ () => {} }/>
<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>
</div>
</div>

View File

@ -44,17 +44,17 @@ export default class Header extends React.Component
</button>
<ul id="menu_list" className={ menuOpened ? "open" : "" }>
<li>
<Link href="/">
<Link href={`/`} shallow>
<a className={ this.props.router && (this.props.router.route === "/" || this.props.router.route.indexOf("/contract") === 0) ? "active" : "" }>Договоры</a>
</Link>
</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>
</Link>
</li>
<li>
<Link href="/settings/">
<Link href="/settings/" shallow>
<a className={ this.props.router && this.props.router.route === "/settings" ? "active" : "" }>Настройки</a>
</Link>
</li>

View File

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

View File

@ -14,7 +14,7 @@ import Company from "../components/Company";
import InnerMenu from "./components/InnerMenu";
import DownloadPdfButton from "../components/DownloadPdfButton";
import { getContractInfo, getContractAgreement, getFile } from "../../actions";
import { getContractInfo, getContractAgreement, getContractRules, getFile } from "../../actions";
class ContractPage extends React.Component
{
@ -22,8 +22,11 @@ class ContractPage extends React.Component
{
super(props);
this.state = {
date: null,
car: null,
contract_date: null,
agreement: null,
rules: null,
loading: false,
}
}
@ -31,8 +34,11 @@ class ContractPage extends React.Component
static getDerivedStateFromProps(nextProps, prevState)
{
return {
date: nextProps.date,
car: nextProps.car,
contract_date: nextProps.contract_date,
agreement: nextProps.agreement,
rules: nextProps.rules,
};
}
@ -42,7 +48,19 @@ class ContractPage extends React.Component
{
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(() => {
this.setState({ loading: false });
@ -53,9 +71,11 @@ class ContractPage extends React.Component
render()
{
const { loading, contract_date, agreement, } = this.state;
const { loading, date, car, contract_date, agreement, rules, } = this.state;
const { number } = this.props;
console.log("rules", rules);
const types = {
contracts: "Договор",
redemptions: "Выкупные документы",
@ -78,8 +98,9 @@ class ContractPage extends React.Component
<div className="clear"></div>
<div className="container">
<div className="title_wrapper">
<div className="left">
<h1 className="section_title">Договор { number }{ contract_date !== null && (<> от { moment(contract_date).format("DD.MM.YYYY") }</>)}</h1>
<div className="left" style={{ flexDirection: 'column', }}>
<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>
<Company/>
</div>
@ -101,11 +122,20 @@ class ContractPage extends React.Component
<span style={{ width: "100%"}}>{ file.number } от { file.date }</span>
{ file.type !== undefined && <span>{ file.type }</span> }
</p>
<DownloadPdfButton id={ file.url } filename={ `${ file.url }.pdf` }/>
<DownloadPdfButton id={ file.url } filename={ `evoleasing_${ document.type }_${ file.number }_${ file.date }.pdf` }/>
</div>
)) }
</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>
) }
</article>
@ -123,7 +153,10 @@ function mapStateToProps(state, ownProps)
{
return {
contract_date: state.contract.date,
date: state.contract.date,
car: state.contract.car,
agreement: state.contract.agreement,
rules: state.contract.rules,
}
}

View File

@ -11,28 +11,27 @@ export default class InnerMenu extends React.Component
render()
{
const { number } = this.props;
console.log("this.props", this.props);
return (
<aside>
<ul className="aside_nav">
<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>
</Link>
</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>
</Link>
</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>
</Link>
</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>
</Link>
</li>

View File

@ -4,7 +4,9 @@ import Image from 'next/image';
import { connect } from "react-redux";
import { withRouter } from 'next/router';
import moment from "moment";
import numeral from "numeral";
import { SpinnerCircular } from 'spinners-react';
import pluralize from 'pluralize-ru';
import { reduxWrapper } from '../../store';
@ -17,6 +19,13 @@ import DownloadPrintFormPdfButton from "../components/DownloadPrintFormPdfButton
import { getContractInfo, getContractDocuments, getReconciliationFile } from "../../actions";
const TYPES = {
upd: "УПД по очередным платежам",
upd_avans: "УПД по авансовым платежам",
billgibdd: "BillGIBDD",
fines: "Штрафы ГИБДД",
};
class ContractDocumentsPage extends React.Component
{
constructor(props)
@ -24,18 +33,25 @@ class ContractDocumentsPage extends React.Component
super(props);
this.state = {
opened: [],
date: null,
car: null,
contract_date: null,
documents: null,
loading: false,
valid_date_start: null,
valid_date_end: null,
period_date_start: null,
period_date_end: null,
reconciliation_requested: false,
reconciliation_disabled: false,
}
}
static getDerivedStateFromProps(nextProps, prevState)
{
return {
date: nextProps.date,
car: nextProps.car,
contract_date: nextProps.contract_date,
documents: nextProps.documents,
};
@ -45,7 +61,8 @@ class ContractDocumentsPage extends React.Component
{
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 });
@ -62,7 +79,8 @@ class ContractDocumentsPage extends React.Component
{
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) =>
{
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) =>
{
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()
{
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;
console.log("documentsdocumentsdocumentsdocumentsdocuments");
console.log(documents);
const types = {
upd: "УПД по очередным платежам",
upd_avans: "УПД по авансовым платежам",
};
console.log("opened");
console.log(opened);
return (
<React.Fragment>
@ -135,8 +332,9 @@ class ContractDocumentsPage extends React.Component
<div className="clear"></div>
<div className="container">
<div className="title_wrapper">
<div className="left">
<h1 className="section_title">Договор { number }{ contract_date !== null && (<> от { moment(contract_date).format("DD.MM.YYYY") }</>)}</h1>
<div className="left" style={{ flexDirection: 'column', }}>
<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>
<Company />
</div>
@ -153,14 +351,14 @@ class ContractDocumentsPage extends React.Component
<p>Акт сверки</p>
<div className="form_group">
<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 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 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 ? (
<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">
{ documents !== undefined && documents !== null ? (
<>
{ documents.upd && documents.upd.map((doc, index) => (
<React.Fragment key={ index }>
<div className="dropdown_block bt">
<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>
)) }
{ this._renderDocuments(documents.upd, 'upd') }
{ this._renderDocuments(documents.upd_avans, 'upd_avans') }
{ this._renderFines(documents.fines, 'fines') }
</>
) : null }
</div>
@ -213,6 +394,8 @@ function mapStateToProps(state, ownProps)
{
return {
contract_date: state.contract.date,
date: state.contract.date,
car: state.contract.car,
documents: state.contract.documents,
}
}

View File

@ -24,7 +24,8 @@ class ContractSchedulePage extends React.Component
this.state = {
loading: false,
payments: null,
contract_date: null,
date: null,
car: null,
full: false,
opened: [],
}
@ -33,8 +34,9 @@ class ContractSchedulePage extends React.Component
static getDerivedStateFromProps(nextProps, prevState)
{
return {
date: nextProps.date,
car: nextProps.car,
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 = () =>
{
this.setState({ full: true });
@ -72,7 +90,7 @@ class ContractSchedulePage extends React.Component
render()
{
const { payments, contract_date, full, opened, loading } = this.state;
const { payments, date, car, full, opened, loading } = this.state;
const { number } = this.props;
console.log("RENDER", "payments");
@ -85,6 +103,7 @@ class ContractSchedulePage extends React.Component
"Paid": "paid",
};
let today = moment();
let last_pay_date = this._getLastPayDate();
return (
<React.Fragment>
@ -101,8 +120,9 @@ class ContractSchedulePage extends React.Component
<div className="clear"></div>
<div className="container">
<div className="title_wrapper">
<div className="left">
<h1 className="section_title">Договор { number }{ contract_date !== null && (<> от { moment(contract_date).format("DD.MM.YYYY") }</>)}</h1>
<div className="left" style={{ flexDirection: 'column', }}>
<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>
<Company/>
</div>
@ -130,7 +150,7 @@ class ContractSchedulePage extends React.Component
{ payments !== null && Object.values(payments).map((payment, index) =>
{
let pd = moment(payment.date, "DD-MM-YYYY");
if(!full && today > pd) { return null; }
if(!full && pd < last_pay_date) { return null; }
return (
<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">
{ payment.status === "Paid" && "Оплачено" }
{ 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" && (
<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 className="table_cell">
@ -220,7 +242,8 @@ function mapStateToProps(state, ownProps)
return {
company: state.company,
payments: state.contract.payments,
contract_date: state.contract.date,
date: state.contract.date,
car: state.contract.car,
//schedule: state.payments,
}
}

View File

@ -23,6 +23,8 @@ class ContractServicesPage extends React.Component
super(props);
this.state = {
opened: [],
date: null,
car: null,
contract_date: null,
loading: false,
helpcard: null,
@ -35,11 +37,13 @@ class ContractServicesPage extends React.Component
static getDerivedStateFromProps(nextProps, prevState)
{
return {
date: nextProps.date,
car: nextProps.car,
contract_date: nextProps.contract_date,
helpcard: nextProps.helpcard,
insurance: nextProps.insurance,
registration: nextProps.registration,
telematic: nextProps.telematic,
telematic: nextProps.telematic,
};
}
@ -80,7 +84,7 @@ class ContractServicesPage extends React.Component
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;
return (
@ -98,8 +102,9 @@ class ContractServicesPage extends React.Component
<div className="clear"></div>
<div className="container">
<div className="title_wrapper">
<div className="left">
<h1 className="section_title">Договор { number }{ contract_date !== null && (<> от { moment(contract_date).format("DD.MM.YYYY") }</>)}</h1>
<div className="left" style={{ flexDirection: 'column', }}>
<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>
<Company/>
</div>
@ -127,6 +132,7 @@ class ContractServicesPage extends React.Component
{ entry.card_number !== null ? (
<div className="block_body">
<div className="company">
<p className="title">РАТ</p>
<ul>
<li>Номер карты: <b>{ entry.card_number }</b></li>
<li>Тип карты: <b>{ entry.card_type }</b></li>
@ -160,7 +166,7 @@ class ContractServicesPage extends React.Component
<div className="block_body">
{ 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 }>
<div className="company">
<p className="title">КАСКО</p>
@ -176,7 +182,7 @@ class ContractServicesPage extends React.Component
{ entry.description && (<p>{ entry.description }</p>) }
</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 }>
<div className="company">
<p className="title">ОСАГО</p>
@ -192,7 +198,7 @@ class ContractServicesPage extends React.Component
{ entry.description && (<p>{ entry.description }</p>) }
</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 }>
<div className="company">
<p className="title">НСИБ</p>
@ -222,7 +228,24 @@ class ContractServicesPage extends React.Component
</p>
<button className="block_toggle"></button>
</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 className={`dropdown_block ${ opened.indexOf("telematic") > -1 ? 'open' : '' }`}>
<div className="block_header" onClick={ () => this._handle_onCard('telematic') }>
@ -232,7 +255,26 @@ class ContractServicesPage extends React.Component
</p>
<button className="block_toggle"></button>
</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="company">
@ -264,6 +306,8 @@ function mapStateToProps(state, ownProps)
{
return {
contract_date: state.contract.date,
date: state.contract.date,
car: state.contract.car,
helpcard: state.contract.helpcard,
insurance: state.contract.insurance,
registration: state.contract.registration,

View File

@ -17,6 +17,7 @@ import Company from "../components/Company";
import CalendarCellModal from "../components/Modal/calendar";
import { getCalendar } from '../../actions';
import { MatchMedia } from '../../utils/mediaqueries';
class CalendarPage extends React.Component
{
@ -29,6 +30,10 @@ class CalendarPage extends React.Component
periods: null,
selected_period: moment().format("YYYYMM"),
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()
{
const date_from = moment().startOf("month").toDate();
const date_to = moment().endOf("month").toDate();
const date_from = moment().startOf("month").subtract(7, 'day').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();
}
@ -76,39 +91,91 @@ class CalendarPage extends React.Component
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_to = moment(period, "YYYYMM").endOf("month").toDate();
const date_from = moment(period, "YYYYMM").startOf("month").subtract(7, 'day').toDate();
const date_to = moment(period, "YYYYMM").endOf("month").add(7, 'day').toDate();
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()
{
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; }
let month = moment(selected_period, "YYYYMM").format("M") - 1;
//console.log("periodsperiodsperiodsperiodsperiods");
//console.log(periods);
const dates = [];
const date_sm = moment(selected_period, 'YYYYMM').startOf("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;
if(date_sm.day() !== 1)
{ date_s = date_sm.subtract(date_sm.day() - 1, "days"); }
if(date_sm.clone().isoWeekday() !== 1)
{ date_s = date_sm.clone().subtract(date_sm.clone().isoWeekday() - 1, "days"); }
else
{ date_s = date_sm; }
@ -119,10 +186,6 @@ class CalendarPage extends React.Component
{ date_e = date_em; }
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 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)
{
//console.log(d.toDate());
let payment = this.getPayments(d.format("YYYY-MM-DD"));
dates.push({
date: d.clone(),
payment: payment,
});
}
const dow = date.day();
//console.log(dow);
//console.log("date.month())", date.month());
for(let i in dates)
{
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) {
if (index % 7 === 0)
result.push(array.slice(index, index +7));
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 (
<React.Fragment>
<Head>
@ -167,6 +241,7 @@ class CalendarPage extends React.Component
<div className="container">
<div className="title_wrapper">
<div className="left">
{/*[{ perweek ? 1 : 0 }, { current_week }, { selected_week }, { weeks_in_month }]*/}
<h1 className="section_title">Календарь оплат</h1>
</div>
<Company/>
@ -176,15 +251,17 @@ class CalendarPage extends React.Component
<article>
<div className="calendar_wrapper">
<div className="form_field">
<select id="calendar_month" defaultValue={ selected_period } onChange={ (event) => this._handle_onChangePeriod(event.target.value) }>
{ periods !== null && Object.values(periods).map((period, index) => (
<option key={ index } value={ period }>{ moment(period, "YYYYMM").format('MMMM YYYY') }</option>
)) }
</select>
{ periods_list.length > 0 && (
<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) }>
{ periods !== null && periods_list.map((period, index) => (
<option key={ index } value={ period }>{ moment(period, "YYYYMM").format('MMMM YYYY') }</option>
)) }
</select>
) }
</div>
<div className="calendar_nav">
<button>Предыдущая неделя</button>
<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 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 className="calendar_grid">
<div className="grid_header">
@ -197,22 +274,22 @@ class CalendarPage extends React.Component
<div className="grid_cell">Вс</div>
</div>
<div className="grid_body">
{ weeks.map((week, index) =>
{ render_weeks.map((week, week_index) =>
{
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) => {
if(day.payment)
{
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">
<p><span>{ day.date.format("DD") }</span> { day.date.format("MMM").toLocaleLowerCase() } { day.date.format("Y").toLocaleLowerCase() }</p>
</div>
<div className="cell_body">{ day.payment && (
<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>
)}
</div>
@ -220,7 +297,7 @@ class CalendarPage extends React.Component
)
}
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">
<p><span>{ day.date.format("DD") }</span> { day.date.format("MMM").toLocaleLowerCase() } { day.date.format("Y").toLocaleLowerCase() }</p>
</div>

View File

@ -1,33 +1,48 @@
import React from "react";
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
{
constructor(props)
{
super(props);
this.menuList = React.createRef();
menu.forEach(item => {
this[item.id] = React.createRef();
});
}
componentDidMount() {
}
scrollToCategory = id => {
};
render()
{
return (
<aside>
<ul className="aside_nav">
<li>
<Link href="/documents/calendar/">
<a className={ this.props.router && this.props.router.route === "/documents/calendar" ? "active" : "" }>Календарь оплат</a>
</Link>
</li>
<li>
<Link href="/documents/reconciliations/">
<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>
<ul className="aside_nav" ref={this.menuList}>
{menu.map(item => (
<li key = {item.id} ref={this[item.id]} onClick={() => this.scrollToCategory(item.id)}>
<Link
href={item.link}
shallow
>
<a className={ this.props.router && this.props.router.route === item.link ? "active" : "" }>{item.name}</a>
</Link>
</li>
))}
</ul>
</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)" />
</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.length > 0 ? contracts.map((contract, index) => (

View File

@ -14,7 +14,9 @@ import InnerMenu from "./components/InnerMenu";
import Company from "../components/Company";
import DateInput from '../components/DatePicker';
import { getContractsList } from '../../actions';
import { getContractsList, getReconciliationFile } from '../../actions';
import { eachSeries } from "async";
class ReconciliationsPage extends React.Component
@ -27,6 +29,11 @@ class ReconciliationsPage extends React.Component
contracts: null,
checked: [],
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 = () =>
{
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()
{
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 (
<React.Fragment>
@ -107,41 +245,53 @@ class ReconciliationsPage extends React.Component
<div className="aside_container about">
<InnerMenu { ...this.props }/>
<article>
<div className="acts_wrapper">
<div className="dosc_list acts_list-checkbox">
{ loading ? (
<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)" />
</div>
) : (
<>
<div className="row">
<p className="doc_name">
<input type="checkbox" name="all" id="all" checked={ checked_all } onChange={ this._handle_onAllContracts } />
<label htmlFor="all">Все договоры</label>
</p>
</div>
{ contracts !== undefined && contracts !== null && contracts.map((contract, index) => (
<div className="row" key={ index }>
<p className="doc_name i-pdf">
<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 className="acts_wrapper" style={{ flex: 1, justifyContent: "center" }}>
{ loading ? (
<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)" />
</div>
) : (
<>
{ contracts !== undefined && contracts !== null && contracts.length > 0 ? (
<>
<div className="dosc_list acts_list-checkbox">
<div className="row">
<p className="doc_name">
<input type="checkbox" name="all" id="all" checked={ checked_all } onChange={ this._handle_onAllContracts } />
<label htmlFor="all">Все договоры</label>
</p>
</div>
{ contracts !== undefined && contracts !== null && contracts.map((contract, index) => (
<div className="row" key={ index }>
<p className="doc_name i-pdf">
<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">
<div className="form_field">
<DateInput placeholder="Дата начала периода" />
</div>
<div className="form_field">
<DateInput placeholder="Дата окончания периода" />
</div>
<button className="button button-blue">Скачать</button>
{/*<button className="button button-blue">Отправить в ЭДО</button>*/}
</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 className="form_field">
<DateInput placeholder="Дата окончания периода" value={ period_date_end } min={ valid_date_start } max={ valid_date_end } onChange={ this._handle_onPeriodDate_end }/>
</div>
<button className="button button-blue" disabled={ reconciliation_disabled } onClick={ () => { this._handle_onReconciliationFiles() }}>
<>
{ reconciliation_requested ? (
<SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" />
) : "Скачать" }
</>
</button>
{/*<button className="button button-blue">Отправить в ЭДО</button>*/}
</div>
</>
) : (
<p>Нет договоров для запроса актов сверок</p>
) }
</>
) }
</div>
</article>
</div>

View File

@ -6,12 +6,14 @@ import cookie from 'cookie';
import { connect } from "react-redux";
import numeral from "numeral";
import moment from 'moment';
import { SpinnerCircular } from 'spinners-react';
import { withRouter } from 'next/router';
import { reduxWrapper } from '../store';
import Header from './components/Header';
import Footer from './components/Footer';
import Company from "./components/Company";
import DateInput from './components/DatePicker';
import Pagination from './components/Pagination';
@ -24,7 +26,7 @@ class IndexPage extends React.Component
super(props);
this.state = {
contracts: null,
order: "number",
order: "date",
sort_number: "desc",
sort_date: "desc",
sort_status: "desc",
@ -53,7 +55,7 @@ class IndexPage extends React.Component
{
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 });
}).catch(() => {});
});
@ -162,7 +164,15 @@ class IndexPage extends React.Component
<section>
<div className="clear"></div>
<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">
<form onSubmit={ (event) => { event.preventDefault(); } }>
<div className="form_field">
@ -177,60 +187,66 @@ class IndexPage extends React.Component
} }/>
<label htmlFor="date_from">Дата<br/>договора от</label>
*/}
<DateInput placeholder="Дата договора от" />
<DateInput placeholder="Дата договора от" id={ "date_from" } onChange={ (date) => this.setState({ date_from: date }) }/>
</div>
<div className="form_field">
{/*<input type={ date_to_type } id="date_for" className="date_input" value="" placeholder="Дата договора по" onFocus={ () => this.setState({ date_from_type: "date" }) } onBlur={ () => { this.setState({ date_from_type: "text" }) } } onChange={ (date) => {
this._handle_onChange_date_to(date);
} }/>
<label htmlFor="date_for">Дата<br/>договора по</label>*/}
<DateInput placeholder="Дата договора по" />
<DateInput placeholder="Дата договора по" id={ "date_to" } onChange={ (date) => this.setState({ date_to: date }) }/>
</div>
<button className="button" disabled={ search !== "" || date_from !== "" || date_to !== "" ? false : true } onClick={ this._handle_onSearch }>Поиск</button>
</form>
</div>
<div className="contract_table" style={ loading ? { opacity: 0.6 } : {} }>
<div className="table_row table_header">
<div className={`table_cell caret ${ sort_number === "asc" ? "reverse" : "" }`} onClick={ this._handle_onChangeSort_number }>Номер договора</div>
<div className={`table_cell caret ${ sort_date === "asc" ? "reverse" : "" }`} onClick={ this._handle_onChangeSort_date }>Дата договора</div>
<div className="table_cell">Автомобиль</div>
<div className="table_cell">Гос.номер</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>
{ loading ? (
<div className="table_row table_header" style={{ minHeight: 450, display: "flex", justifyContent: "center", alignItems: "center" }}>
<SpinnerCircular size={90} thickness={51} speed={100} color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" />
</div>
{ contracts !== null && (
<>
{ contracts.length > 0 ? contracts.map((contract, index) => (
<Link href={`/contract/${ contract.number }/payments`}>
<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 className="contract_table">
<div className="table_row table_header">
<div className={`table_cell caret ${ sort_number === "asc" ? "reverse" : "" }`} onClick={ this._handle_onChangeSort_number }>Номер договора</div>
<div className={`table_cell caret ${ sort_date === "asc" ? "reverse" : "" }`} onClick={ this._handle_onChangeSort_date }>Дата договора</div>
<div className="table_cell">Автомобиль</div>
<div className="table_cell">Гос.номер</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>
{ contracts !== null && (
<>
{ contracts.length > 0 ? contracts.map((contract, index) => (
<Link href={`/contract/${ contract.number }/payments`} key={ index }>
<div className="table_row" key={ index } style={{ cursor: "pointer" }}>
<div className="table_cell"><a>{ contract.number }</a></div>
<div className="table_cell">{ moment(contract.date).format("DD.MM.YYYY") }</div>
<div className="table_cell">{ contract.car?.brand?.name } { contract.car?.model?.name }</div>
<div className="table_cell">{ contract.car?.reg_number !== null ? contract.car?.reg_number : "Без рег. номера" }</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>
</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>
</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>
) }
</>
) }
</div>
) }
{ !all && (
<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 { withRouter } from 'next/router';
import { reduxWrapper } from '../store';
import pluralize from 'pluralize-ru';
import Header from './components/Header';
import Footer from './components/Footer';
import MainHeader from "./components/MainHeader";
import FormRequest from "./components/FormRequest";
import { sendLoginFormEmail, sendLoginFormPhone } from '../actions';
import { sendLoginFormEmail, sendLoginFormPhone, sendSmsCode } from '../actions';
class LoginPage extends React.Component
{
@ -21,9 +22,22 @@ class LoginPage extends React.Component
email: "",
password: "",
phone: "",
phone_code: "",
tab: "email",
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)
@ -38,7 +52,15 @@ class LoginPage extends React.Component
event.preventDefault();
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) =>
@ -46,7 +68,52 @@ class LoginPage extends React.Component
event.preventDefault();
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) =>
@ -54,9 +121,42 @@ class LoginPage extends React.Component
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()
{
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 (
<React.Fragment>
@ -84,21 +184,49 @@ class LoginPage extends React.Component
{ tab === "email" ? (
<form onSubmit={ this._handle_onEmailSubmit }>
<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 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>
<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 onSubmit={ this._handle_onPhoneSubmit }>
<div className="form_field">
<input type="text" name="phone" value={ phone } placeholder="Введите номер телефона" onChange={ (event) => this.setState({ phone: event.target.value }) }/>
</div>
<button type="submit" className="button button-blue" disabled>Получить код</button>
</form>
) }
<>
{ phone_form_step === 1 && (
<>
<form onSubmit={ this._handle_onPhoneSubmit }>
<div className="form_field">
<input type="text" name="phone" value={ phone } placeholder="Введите номер телефона, например +7 900 111 22 33" onChange={ (event) => this._handle_onPhoneChange(event.target.value) } required={ true }/>
</div>
<button type="submit" className="button button-blue" disabled={ phone_login_disabled }>Получить код</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>
</section>

View File

@ -31,11 +31,12 @@ const contractReducer = (state = initialState.contract, action) =>
};
}
case actionTypes.CONTRACT_DATE:
case actionTypes.CONTRACT_INFO:
{
return {
...state,
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: {
return state;
}

View File

@ -23,12 +23,14 @@ export const defaultState = {
contract: {
payments: null,
date: null,
car: null,
insurance: null,
helpcard: null,
registration: null,
telematic: null,
agreement: null,
documents: null,
rules: null,
},
calendar: {
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"
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:
version "3.5.1"
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"
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:
version "1.9.3"
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"
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:
version "3.12.0"
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
@ -1024,6 +1039,11 @@ define-properties@^1.1.3:
dependencies:
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:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@ -1838,6 +1858,23 @@ invariant@^2.2.4:
dependencies:
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:
version "1.1.1"
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"
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:
version "1.2.4"
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"
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:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
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:
version "3.0.3"
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"
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:
version "2.0.0"
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
@ -2608,6 +2674,11 @@ p-locate@^4.1.0:
dependencies:
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:
version "1.0.0"
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"
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:
version "1.6.4"
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"
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:
version "0.2.1"
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"
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:
version "6.0.0"
resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8"
@ -3190,6 +3290,11 @@ stacktrace-parser@0.1.10:
dependencies:
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":
version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"