diff --git a/actions/dealsActions.js b/actions/dealsActions.js index e2d35d6..702199b 100644 --- a/actions/dealsActions.js +++ b/actions/dealsActions.js @@ -4,7 +4,10 @@ import Router from 'next/router'; import moment from 'moment'; import { nSQL } from "@nano-sql/core"; -/* +import * as actionTypes from '../constants/actionTypes'; +import * as currentState from '../reducers/initialState'; + +/*DEALS_LIST /lk/ConsiderationOpportunity/quote [{ @@ -24,24 +27,76 @@ import { nSQL } from "@nano-sql/core"; "model_name": "Touareg", "object_count": 1, }] + +[{ + "opp_number": "780", + "statuscode_id": 107, + "statuscode_name": " ", + "comment": null, +}, { + "opp_number": "37197", + "statuscode_id": 101, + "statuscode_name": " ", + "comment": null, +}] +opp_number- номер Лизинговой сделки +statuscode_id - номер этапа +statuscode_name - имя этапа +comment - сопроводительный текст для данного этапа, который надо выводить + */ export const getDeals = ({ dispatch }) => { - //console.log("ACTION", "support", "getAppeals()", `${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/support/appeals`); + console.log("ACTION", "deals", "getDeals()", `${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/deals`); return new Promise((resolve, reject) => { - axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/deals/list`, {}, { + console.log("??????????????????????? WTF"); + + axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/deals`, {}, { withCredentials: true, }) .then((response) => { - //console.log("ACTION", "support", "getAppeals()", "response", response.data); - dispatch({ type: actionTypes.DEALS, data: {} }); + console.log("!!!!!!!!!!!!!!!!!!!!!!!!! GOOOOOOD"); + console.log("ACTION", "deals", "getDeals()", "response", response.data); + dispatch({ + type: actionTypes.DEALS_LIST, + data: { + list: [{ + "opp_number": "780", + "statuscode_id": 107, + "statuscode_name": " ", + "comment": null, + }, { + "opp_number": "37197", + "statuscode_id": 101, + "statuscode_name": " ", + "comment": null, + }] + } + }); resolve(); }) .catch((error) => { + console.log("!!!!!!!!!!!!!!!!!!!!!!!!! ERROR", { action: actionTypes.DEALS_LIST }); + dispatch({ + type: actionTypes.DEALS_LIST, + data: { + list: [{ + "opp_number": "780", + "statuscode_id": 107, + "statuscode_name": " ", + "comment": null, + }, { + "opp_number": "37197", + "statuscode_id": 101, + "statuscode_name": " ", + "comment": null, + }] + } + }); console.error(error); reject(); }); diff --git a/actions/index.js b/actions/index.js index 9c9b45e..8b8f996 100644 --- a/actions/index.js +++ b/actions/index.js @@ -13,4 +13,5 @@ export * from './supportActions'; export * from './adminActions'; export * from './suggestsActions'; export * from './questionnaireActions'; -export * from './feedbackActions'; \ No newline at end of file +export * from './feedbackActions'; +export * from './dealsActions'; \ No newline at end of file diff --git a/components/DealsStatus/DealsList.js b/components/DealsStatus/DealsList.js new file mode 100644 index 0000000..58f9c87 --- /dev/null +++ b/components/DealsStatus/DealsList.js @@ -0,0 +1,45 @@ +import React from "react"; +import DealsListDeal from "./DealsListDeal"; +import SingleDeal from "./SingleDeal"; + +export default class DealsList extends React.Component +{ + constructor(props) + { + super(props); + } + + render() + { + const { deals, dealSelected } = this.props; + + console.log({ deals }); + + return ( +
+ { deals.list !== undefined && deals.list !== null && deals.list.map((deal, index) => + { + if(index === dealSelected) + { + return ( { + this._handleModalToggle("current") + }} + />) + } + else + { + return ( + + ) + } + } )} +
+ ) + } +} \ No newline at end of file diff --git a/components/DealsStatus/DealsListDeal.js b/components/DealsStatus/DealsListDeal.js new file mode 100644 index 0000000..2c5dfe2 --- /dev/null +++ b/components/DealsStatus/DealsListDeal.js @@ -0,0 +1,55 @@ +import React from "react"; +import pluralize from 'pluralize-ru'; + +const statuses = [ + { + title: "Сбор пакета документов", + icon: "/assets/images/status/1.svg", + } +]; + +export default class DealsListDeal extends React.Component +{ + constructor(props) + { + super(props) + } + + render() + { + const { index, comment, opp_number, statuscode_id, statuscode_name } = this.props; + const step = statuscode_id - 100; + + console.log("deal list item", { props: this.props }); + + return ( +
+
+

Сделка { index + 1 }

+
+
+

+ { step === 0 ? "Не начата" : `${ step } ${ pluralize(step, 'этапа', 'этап', 'этапа', 'этапов') } ${ pluralize(step, 'пройдено', 'пройден', 'пройдено', 'пройдено') }` } + {/*} + + + + {*/} +

+
+
+ +

Сбор пакета документов

+
+
+ +
+
+ ) + } +} \ No newline at end of file diff --git a/components/DealsStatus/SingleDeal.js b/components/DealsStatus/SingleDeal.js new file mode 100644 index 0000000..6af26a7 --- /dev/null +++ b/components/DealsStatus/SingleDeal.js @@ -0,0 +1,308 @@ +import React from "react" + +export default class SingleDeal extends React.Component +{ + constructor(props) + { + super(props); + } + + render() + { + const { close } = this.props; + + return ( +
+ {/*} +
+

Статус сделки

+ +
+ {*/} +
+
+

Сделка 1

+ +
+
+ +

Выбор КП

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СтоимостьПервый платеж, р.Первый платеж, %МаркаМодельОбъектов лизинга
+
+ {} }/> + +
+
15 600 000 р.560 000 р.10 %AudiA81 +
+
+
+

+ КП + №1 +

+
+
+
+
+
+ {} }/> + +
+
15 600 000 р.560 000 р.10 %AudiA81 +
+
+
+

+ КП + №1 +

+
+
+
+
+
+
+
+
+

Сделка 1

+ +
+
+ +

Программа финансирования

+
+
+
+

Статусный текст о том что выбирается программа финансированияи может быть по центру иконочка часиков или слева от статусного текста иконочка часиков

+
+
+
+
+
+

Сделка 1

+ +
+
+ +

Сборка пакета документов

+
+
+
+

Вам не требуется актуализация данных анкеты Клиента

+
+
+

Требуется обновить данные в анкете

+ +
+
+

Проводится проверка анкеты Вашей организации

+
+

Устав организации

+
+ +
+
+
+
+
+

№123/2023 от 01.01.2023

+
+
+
+
+

№123/2023 от 01.01.2023

+
+
+
+

Документы, отправленные Вами принадлежат другой организации бла бла коммент от менеджера

+
+
+ +
+

Другое название документа

+
+ +
+
+
+
+
+

Сделка 1

+ +
+
+ +

Проверка документов

+
+
+
+

Статусный текст о том что выбирается программа финансированияи может быть по центру иконочка часиков или слева от статусного текста иконочка часиков

+
+
+
+
+
+

Сделка 1

+ +
+
+ +

Принятие решения по заявке

+
+
+
+

Статусный текст о том что выбирается программа финансированияи может быть по центру иконочка часиков или слева от статусного текста иконочка часиков

+
+
+
+
+
+

Сделка 1

+ +
+
+ +

Оформление лизинга

+
+
+
+

Статусный текст о том что выбирается программа финансированияи может быть по центру иконочка часиков или слева от статусного текста иконочка часиков

+
+
+
+
+
+

Сделка 1

+ +
+
+ +

Выбор типа подписания

+
+
+
+
+
+

Подготовлено 3 из 12

+
+
+
+
+

+ {} }/> + +

+
+
+
+ + +
+
+
+
+
+

К подписанию 3 из 12

+
+
+
+
+

+ №123/2023 от 01.01.2023 +

+ +
+
+

+ №123/2023 от 01.01.2023 +

+ + +
+
+
+
+
+
+

Подписано 3 из 12

+
+
+ +
+
+
+
+

Подготовлено 3 из 12

+
+
+
+
+

+ №123/2023 от 01.01.2023 +

+
+
+
+
+
+
+
+
+ ) + } +} \ No newline at end of file diff --git a/components/DealsStatus/index.js b/components/DealsStatus/index.js index 9da8966..5eae91a 100644 --- a/components/DealsStatus/index.js +++ b/components/DealsStatus/index.js @@ -1,310 +1,8 @@ import React from "react" import { connect } from "react-redux" - -class SingleDeal extends React.Component -{ - constructor(props) - { - super(props); - } - - render() - { - const { close } = this.props; - - return ( -
-
-

Статус сделки

- -
-
-
-

Сделка 1

- -
-
- -

Выбор КП

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
СтоимостьПервый платеж, р.Первый платеж, %МаркаМодельОбъектов лизинга
-
- {} }/> - -
-
15 600 000 р.560 000 р.10 %AudiA81 -
-
-
-

- КП - №1 -

-
-
-
-
-
- {} }/> - -
-
15 600 000 р.560 000 р.10 %AudiA81 -
-
-
-

- КП - №1 -

-
-
-
-
-
-
-
-
-

Сделка 1

- -
-
- -

Программа финансирования

-
-
-
-

Статусный текст о том что выбирается программа финансированияи может быть по центру иконочка часиков или слева от статусного текста иконочка часиков

-
-
-
-
-
-

Сделка 1

- -
-
- -

Сборка пакета документов

-
-
-
-

Вам не требуется актуализация данных анкеты Клиента

-
-
-

Требуется обновить данные в анкете

- -
-
-

Проводится проверка анкеты Вашей организации

-
-

Устав организации

-
- -
-
-
-
-
-

№123/2023 от 01.01.2023

-
-
-
-
-

№123/2023 от 01.01.2023

-
-
-
-

Документы, отправленные Вами принадлежат другой организации бла бла коммент от менеджера

-
-
- -
-

Другое название документа

-
- -
-
-
-
-
-

Сделка 1

- -
-
- -

Проверка документов

-
-
-
-

Статусный текст о том что выбирается программа финансированияи может быть по центру иконочка часиков или слева от статусного текста иконочка часиков

-
-
-
-
-
-

Сделка 1

- -
-
- -

Принятие решения по заявке

-
-
-
-

Статусный текст о том что выбирается программа финансированияи может быть по центру иконочка часиков или слева от статусного текста иконочка часиков

-
-
-
-
-
-

Сделка 1

- -
-
- -

Оформление лизинга

-
-
-
-

Статусный текст о том что выбирается программа финансированияи может быть по центру иконочка часиков или слева от статусного текста иконочка часиков

-
-
-
-
-
-

Сделка 1

- -
-
- -

Выбор типа подписания

-
-
-
-
-
-

Подготовлено 3 из 12

-
-
-
-
-

- {} }/> - -

-
-
-
- - -
-
-
-
-
-

К подписанию 3 из 12

-
-
-
-
-

- №123/2023 от 01.01.2023 -

- -
-
-

- №123/2023 от 01.01.2023 -

- - -
-
-
-
-
-
-

Подписано 3 из 12

-
-
- -
-
-
-
-

Подготовлено 3 из 12

-
-
-
-
-

- №123/2023 от 01.01.2023 -

-
-
-
-
-
-
-
-
- ) - } -} +import DealsList from "./DealsList"; +import SingleDeal from "./SingleDeal"; +import { getDeals } from "../../actions"; class AllContractsModal extends React.Component { @@ -378,105 +76,33 @@ class AllContractsModal extends React.Component } } -class DealsList extends React.Component -{ - constructor(props) - { - super(props) - } - - render() - { - return ( -
-
-
-

Сделка 1

-
-
-

- 2 этапа пройдено - - - -

-
-
- -

Сбор пакета документов

-
-
-

- еще 4 этапа - - - -

-
-
- -
-
-
-
-

Сделка 1

-
-
-

{ this._handleModalToggle("current") }} > - 2 этапа пройдено - - - -

-
-
- -

Сбор пакета документов

-
-
-

{ this._handleModalToggle("current") }} > - еще 4 этапа - - - -

-
-
- -
-
-
- ) - } -} - class DealsStatus extends React.Component { constructor(props) { super(props) this.state = { - currentContractModalOpened: false, - allContractModalOpened: false, - currentSelected: null + currentContractModalOpened: false, + allContractModalOpened: false, + currentSelected: null, + dealSelected: false, + deals: undefined, } } - static getDerivedStateFromProps(nextProps, prevState) { - return {} + static getDerivedStateFromProps(nextProps, prevState) + { + console.log("DealsStatus", "getDerivedStateFromProps", { nextProps }); + return { + deals: nextProps.deals, + } } - componentDidMount() { } + componentDidMount() + { + const { dispatch } = this.props; + getDeals({ dispatch }); + } componentDidUpdate(prevProps, prevState) { } @@ -505,17 +131,14 @@ class DealsStatus extends React.Component render() { - const { currentContractModalOpened, allContractModalOpened, currentSelected } = this.state + const { currentContractModalOpened, allContractModalOpened, currentSelected, dealSelected, deals } = this.state return ( <> - - - { - this._handleModalToggle("current") - }} - /> +
+

Статусы сделок

+
+ {/*} { - const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : ""); - - console.log("req.body"); - console.log(req.body); - - if(cookies.jwt !== undefined && cookies.jwt !== null) + if(req.headers.cookie !== undefined) { - console.log("cookies.jwt"); - console.log(cookies.jwt); + const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : ""); - 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 }); + console.log("req.body"); + console.log(req.body); - console.log("client_jwt_decoded", client_jwt_decoded); - console.log("crm_jwt", crm_jwt); - - const url = `${ process.env.CRM_API_HOST }/lk/ConsiderationOpportunity`; - console.log({ url }); - - try + if(cookies.jwt !== undefined && cookies.jwt !== null) { - await axios.get(url, { - params: { ...client_jwt_decoded, }, - headers: { - "Authorization": `Bearer ${ crm_jwt }`, - }, - withCredentials: true, - }) - .then((crm_response) => - { - console.log("API", "contract", "crm_response.data"); - //console.log("API", "contract", crm_response.data); + console.log("cookies.jwt"); + console.log(cookies.jwt); - res.status(200).json(crm_response.data); - }) - .catch((error) => + var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT); + const crm_payload = { acc_number: client_jwt_decoded.acc_number }; + var crm_jwt = jwt.sign(crm_payload, process.env.JWT_SECRET_CRM, { noTimestamp: true }); + + console.log("client_jwt_decoded", client_jwt_decoded); + console.log("crm_jwt", crm_jwt); + + const url = `${ process.env.CRM_API_HOST }/lk/ConsiderationOpportunity`; + console.log({ url }); + + try { - console.error(error); - res.status(500); - }); + await axios.get(url, { + params: crm_payload, + headers: { + "Authorization": `Bearer ${ crm_jwt }`, + }, + withCredentials: true, + }) + .then((crm_response) => + { + console.log("API", "contract", "crm_response.data"); + //console.log("API", "contract", crm_response.data); + + res.status(200).json(crm_response.data); + resolve(); + }) + .catch((error) => + { + console.error(error); + res.status(500).send(); + resolve(); + }); + } + catch(e) + { + console.error(e); + res.status(500).send(); + resolve(); + } } - catch(e) + else { - console.error(e); - res.status(500); + res.status(403).send(); + resolve(); } } else { - res.status(403); + res.status(403).send(); + resolve(); } - } + }); } \ No newline at end of file diff --git a/pages/components/Manager/index.js b/pages/components/Manager/index.js index 12a9195..0fca919 100644 --- a/pages/components/Manager/index.js +++ b/pages/components/Manager/index.js @@ -4,132 +4,149 @@ import { SpinnerCircular } from "spinners-react" import Rating from "../Rating" import { getImage } from "../../../actions" -class Manager extends React.Component { - constructor(props) { - super(props) - this.state = { - company: {}, - photo: undefined, - loading: true, - full: false - } - } +class Manager extends React.Component +{ + constructor(props) + { + super(props) + this.state = { + company: {}, + photo: undefined, + loading: true, + full: false, + rate: false, + } + } - static getDerivedStateFromProps(nextProps, prevState) { - return { - company: nextProps.company - } - } + static getDerivedStateFromProps(nextProps, prevState) { + return { + company: nextProps.company + } + } - componentDidMount() { - const { company } = this.state + componentDidMount() + { + const { company } = this.state; + this._loadManagerAvatar(); + } - this._loadManagerAvatar() - } + componentDidUpdate(prevProps, prevState) + { + if (prevState.company.manager_photo === undefined && this.state.company.manager_photo !== undefined) + { + this._loadManagerAvatar(); + } + } - componentDidUpdate(prevProps, prevState) { - if (prevState.company.manager_photo === undefined && this.state.company.manager_photo !== undefined) { - this._loadManagerAvatar() - } - } + _loadManagerAvatar = () => + { + const { company } = this.state - _loadManagerAvatar = () => { - const { company } = this.state + if (company.manager_photo !== undefined && company.manager_photo !== null && company.manager_photo !== "") + { + getImage({ id: company.manager_photo }).then((result) => { + this.setState({ photo: result, loading: false }); + }); + } + else + { + if (company.manager_photo !== undefined) { + this.setState({ photo: null, loading: false }); + } + } + } - if (company.manager_photo !== undefined && company.manager_photo !== null && company.manager_photo !== "") { - getImage({ id: company.manager_photo }).then((result) => { - this.setState({ photo: result, loading: false }) - }) - } else { - if (company.manager_photo !== undefined) { - this.setState({ photo: null, loading: false }) - } - } - } + _handle_onFull = () => + { + this.setState({ full: this.state.full ? false : true }); + } - _handle_onFull = () => { - this.setState({ full: this.state.full ? false : true }) - } + _handle_onRate = (rate) => + { + this.setState({ rate }); + } - render() { - const { company, loading, photo, full } = this.state + render() + { + const { company, loading, photo, full, rate } = this.state - return ( -
-
-
- {loading ? ( - - ) : ( - {company.manager_fio} - )} -
-
-

Помогу выбрать новый автомобиль

-

{company.manager_fio}

-

{company.manager_jobtitle}

-
- {company.manager_email} - {company.manager_mobilephone !== undefined && - company.manager_mobilephone !== null && - company.manager_mobilephone !== "" && ( - - {company.manager_mobilephone} - - )} - {company.manager_telegram !== undefined && - company.manager_telegram !== null && - company.manager_telegram !== "" && ( - {`@${company.manager_telegram.replace("@", "")}`} - )} -
-
-
-
-
-
- {loading ? ( - - ) : ( - {company.manager_fio} - )} -
-
+ return ( +
+
+
+ { loading ? ( + + ) : ( + {company.manager_fio} + ) } +
+
+

Помогу выбрать новый автомобиль

+

{company.manager_fio}

+

{company.manager_jobtitle}

+
+ {company.manager_email} + { company.manager_mobilephone !== undefined && + company.manager_mobilephone !== null && + company.manager_mobilephone !== "" && ( + + {company.manager_mobilephone} + + ) } + { company.manager_telegram !== undefined && + company.manager_telegram !== null && + company.manager_telegram !== "" && ( + {`@${company.manager_telegram.replace("@", "")}`} + ) } +
+
+
+
+
+
+ {loading ? ( + + ) : ( + {company.manager_fio} + )} +
+
- {/* Оценка */} - -
- ) - } + {/* Оценка */} + +
+ ) + } } -function mapStateToProps(state, ownProps) { - return { - company: state.company - } +function mapStateToProps(state, ownProps) +{ + return { + company: state.company + } } -export default connect(mapStateToProps)(Manager) +export default connect(mapStateToProps)(Manager); diff --git a/pages/components/Rating/index.js b/pages/components/Rating/index.js index 36531ab..cda06c3 100644 --- a/pages/components/Rating/index.js +++ b/pages/components/Rating/index.js @@ -66,6 +66,8 @@ class Rating extends React.Component hovered: newRating, opened: true, }); + + this.props.onRate(true); } _handle_onFieldChange = (field, value) => @@ -95,6 +97,7 @@ class Rating extends React.Component setTimeout(() => { this.setState({ hidden: true }) + this.props.onRate(false); }, 1000); setTimeout(() => { diff --git a/pages/index.js b/pages/index.js index a5cf2c7..3d9ab9f 100644 --- a/pages/index.js +++ b/pages/index.js @@ -547,13 +547,14 @@ class IndexPage extends React.Component } } -function mapStateToProps(state, ownProps) { - return { - company: state.company, - contracts: state.contracts.list, - page: state.contracts.page, - pages: state.contracts.pages - } +function mapStateToProps(state, ownProps) +{ + return { + company: state.company, + contracts: state.contracts.list, + page: state.contracts.page, + pages: state.contracts.pages + } } export const getServerSideProps = reduxWrapper.getServerSideProps((store) => async ({ req, res, query }) => { diff --git a/reducers/dealsReducer.js b/reducers/dealsReducer.js index f888b28..5c8ab7c 100644 --- a/reducers/dealsReducer.js +++ b/reducers/dealsReducer.js @@ -17,6 +17,12 @@ const dealsReducer = (state = initialState.deals, action) => case actionTypes.DEALS_LIST: { + console.log("actionTypes.DEALS_LIST", actionTypes.DEALS_LIST, { action }); + console.log({ + ...state, + list: action.data.list, + }); + return { ...state, list: action.data.list, diff --git a/reducers/initialState.js b/reducers/initialState.js index 367b9bb..d9035ad 100644 --- a/reducers/initialState.js +++ b/reducers/initialState.js @@ -235,18 +235,18 @@ export const defaultState = { deals: { loaded: false, - list: undefined, + list: null, deal: { loaded: false, offers: { - list: undefined, - filtered: undefined, + list: null, + filtered: null, }, documents: { - list: undefined, + list: null, }, contracts: { - list: undefined, + list: null, }, }, }, diff --git a/store/index.js b/store/index.js index 4711c28..2e378ab 100644 --- a/store/index.js +++ b/store/index.js @@ -15,6 +15,7 @@ import contractsInfoReducer from '../reducers/contractsInfoReducer'; import contractEventsReducer from '../reducers/contractEventsReducer'; import contractFinesReducer from '../reducers/contractFinesReducer'; import questionnaireReducer from '../reducers/questionnaireReducer'; +import dealsReducer from '../reducers/dealsReducer'; const combinedReducer = combineReducers({ auth: authReducer, @@ -31,6 +32,7 @@ const combinedReducer = combineReducers({ contract_events: contractEventsReducer, contract_fines: contractFinesReducer, questionnaire: questionnaireReducer, + deals: dealsReducer, }); const makeStore = (context) =>