diff --git a/actions/supportActions.js b/actions/supportActions.js index e594195..0e20589 100644 --- a/actions/supportActions.js +++ b/actions/supportActions.js @@ -1,4 +1,5 @@ import axios from 'axios'; +import { eachSeries } from 'async'; import * as actionTypes from '../constants/actionTypes'; import * as currentState from '../reducers/initialState'; @@ -105,24 +106,61 @@ export const sendNewAppeal = (appeal) => return new Promise((resolve, reject) => { - return new Promise((resolve, reject) => + axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/support/request`, appeal, { - axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/support/request`, { - query - }, + withCredentials: true, + }) + .then(async (response) => + { + console.log("sendNewAppeal", "response.data", response.data); + resolve(response.data); + }) + .catch((error) => + { + console.error(error); + reject(); + }); + }); +} + +export const sendAppealAttachments = (payload) => +{ + console.log("ACTION", "support", "sendAppealAttachments", payload); + + return new Promise((resolve, reject) => + { + eachSeries(payload.files, (file, callback) => + { + let data = new FormData(); + data.append('file', file); + + axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/support/attachment?request_client_number=${ payload.request_client_number }`, data, { + headers: { + "Content-Type": "multipart/form-data", + }, withCredentials: true, }) .then(async (response) => { - console.log("sendNewAppeal", "response.data", response.data); - resolve(); + console.log("sendAppealAttachments", "response.data", response.data); + callback(null); }) .catch((error) => { console.error(error); - reject(); + callback(true); }); + }, (err) => + { + if(!err) + { + resolve(); + } + else + { + reject(); + } }); }); } \ No newline at end of file diff --git a/pages/api/support/attachment.js b/pages/api/support/attachment.js index b7c08bf..9cea6a8 100644 --- a/pages/api/support/attachment.js +++ b/pages/api/support/attachment.js @@ -5,51 +5,190 @@ import cookie from 'cookie'; import moment from 'moment'; import jwt from 'jsonwebtoken'; import { cors } from '../../../lib/cors'; +import { inspect } from 'util'; +//import formidable from 'formidable'; export default async function handler(req, res) { + console.log("API", "support", "attachment"); await cors(req, res); - console.log("API", "support", "request"); - console.log(req.body); - console.log("-".repeat(50)); + console.log("req.query", req.query); - if(req.headers.cookie !== undefined) + return new Promise((resolve) => { - const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : ""); - if(cookies.jwt !== undefined && cookies.jwt !== null) + if(req.headers.cookie !== undefined) { - if(jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT)) + const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : ""); + + if(cookies.jwt !== undefined && cookies.jwt !== null) { - const response = await new Promise((resolve, reject) => - { - axios.post(`${ process.env.CRM_API_HOST }/lk/incident/UploadDocument`, req.body) - .then((api_response) => - { - console.log("RESPONSE"); - console.log(api_response.data); + console.log("cookies.jwt"); + console.log(cookies.jwt); + + var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT); + var crm_jwt = jwt.sign({ acc_number: client_jwt_decoded.acc_number }, process.env.JWT_SECRET_CRM, { noTimestamp: true }); - resolve(api_response.data); + //const path = `${ process.env.CRM_API_HOST }/lk/incident/RequestClient/UploadDocument?request_client_number=${ fields.request_client_number }`; + const path = `${ process.env.CRM_API_HOST }/lk/incident/RequestClient/UploadDocument?request_client_number=${ req.query.request_client_number }`; + console.log("API", "support", "request", "path", path); + + console.log("*".repeat(50)); + console.log(req.headers); + console.log("*".repeat(50)); + + try + { + console.log("??????", req.headers['content-type']); + axios.post(path, req.body, + { + headers: { + "Content-Type": req.headers['content-type'], + //"Content-Type": "multipart/form-data", + "Authorization": `Bearer ${ crm_jwt }`, + }, + withCredentials: true, + }) + .then((crm_response) => + { + console.log("crm_response for", path); + console.log(inspect(crm_response.data, true, null, true)); + + res.status(200).json(crm_response.data); + resolve(); }) .catch((error) => { - console.log("error"); console.error(error); + console.error("-".repeat(30), "error.response.data:"); + console.error(error.response.data); - reject([]); + res.status(500).json(error.response.data); + resolve(); }); - }); - - res.status(200).json(response); + } + catch(e) + { + console.error(e); + res.status(500).end(e); + resolve(); + } } else { res.status(403); + resolve(); } } else { res.status(403); + resolve(); + } + }); +} + +/* +export default async function handler(req, res) +{ + console.log("API", "support", "attachment"); + await cors(req, res); + + return new Promise((resolve) => + { + if(req.headers.cookie !== undefined) + { + const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : ""); + + if(cookies.jwt !== undefined && cookies.jwt !== null) + { + console.log("cookies.jwt"); + console.log(cookies.jwt); + + var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT); + var crm_jwt = jwt.sign({ acc_number: client_jwt_decoded.acc_number }, process.env.JWT_SECRET_CRM, { noTimestamp: true }); + + const form = formidable({}); + form.parse(req, (err, fields, files) => + { + if(err) + { + console.error(err); + res.status(500).end(""); + resolve(); + } + else + { + console.log("fields", fields); + console.log("files", files); + console.log("API", "support", "attachment", "-".repeat(50)); + + //const path = `${ process.env.CRM_API_HOST }/lk/incident/RequestClient/UploadDocument?request_client_number=${ fields.request_client_number }`; + const path = `${ process.env.CRM_API_HOST }/lk/incident/RequestClient/UploadDocument?request_client_number=REQ2022_0000092`; + console.log("API", "support", "request", "path", path); + + try + { + axios.post(path, req.body, + { + headers: { + //"Content-Type": "application/json", + "Content-Type": "multipart/form-data", + "Authorization": `Bearer ${ crm_jwt }`, + }, + withCredentials: true, + }) + .then((crm_response) => + { + console.log("crm_response for", path); + console.log(inspect(crm_response.data, true, null, true)); + + res.status(200).json(crm_response.data); + resolve(); + }) + .catch((error) => + { + console.error(error); + console.error("-".repeat(30), "error.response.data:"); + console.error(error.response.data); + + res.status(500).json(error.response.data); + resolve(); + }); + } + catch(e) + { + console.error(e); + res.status(500).end(e); + resolve(); + } + } + }); + } + else + { + res.status(403); + resolve(); + } + } + else + { + res.status(403); + resolve(); + } + }); +} + +export const config = { + api: { + bodyParser: false + } +} +*/ +export const config = { + api: { + bodyParser: { + sizeLimit: '1000mb' } } } \ No newline at end of file diff --git a/pages/api/support/request.js b/pages/api/support/request.js index b5a4705..106c2c8 100644 --- a/pages/api/support/request.js +++ b/pages/api/support/request.js @@ -1,11 +1,69 @@ // Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import CRMRequestPost from '../../../lib/CRMRequestPost'; +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'; +import { inspect } from 'util'; export default async function handler(req, res) { console.log("API", "support", "request"); console.log(req.body); console.log("-".repeat(50)); + await cors(req, res); - await CRMRequestPost(req, res, `${ process.env.CRM_API_HOST }/lk/incident/CreateRequestClient`, req.body); + if(req.headers.cookie !== undefined) + { + const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : ""); + + if(cookies.jwt !== undefined && cookies.jwt !== null) + { + console.log("cookies.jwt"); + console.log(cookies.jwt); + + var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT); + var crm_jwt = jwt.sign({ acc_number: client_jwt_decoded.acc_number }, process.env.JWT_SECRET_CRM, { noTimestamp: true }); + + const path = `${ process.env.CRM_API_HOST }/lk/incident/RequestClient/CreateRequestClient?acc_number=${ client_jwt_decoded.acc_number }`; + console.log("API", "support", "request", "path", path); + + try + { + await axios.post(path, req.body, + { + headers: { + //"Content-Type": "application/json", + "Authorization": `Bearer ${ crm_jwt }`, + }, + withCredentials: true, + }) + .then((crm_response) => + { + console.log("crm_response for", path); + console.log(inspect(crm_response.data, true, null, true)); + + res.status(200).json(crm_response.data); + }) + .catch((error) => + { + console.error(error); + console.error("-".repeat(30), "error.response.data:"); + console.error(error.response.data); + + res.status(500).json(error.response.data); + }); + } + catch(e) + { + console.error(e); + res.status(500).send(e); + } + } + else + { + res.status(403); + } + } } \ No newline at end of file diff --git a/pages/settings/admin.js b/pages/settings/admin.js index 18b23fa..202460b 100644 --- a/pages/settings/admin.js +++ b/pages/settings/admin.js @@ -19,15 +19,116 @@ import Company from "../components/Company"; import { getUsers, sendPhoneChangeNumber, sendPhoneChangeNumberSmsCode, setUserPhone } from '../../actions'; -class IndexPage extends React.Component +class Form extends React.Component +{ + constructor(props) + { + super(props); + this.state = { + name: "", + email: "", + selection: false, + selected_companies_all: false, + selected_companies_list: [], + }; + } + + _handle_onChange = (field, value) => + { + this.setState({ [ field ]: value }); + } + + _handle_onCompaniesSelection = () => + { + this.setState({ selection: this.state.selection ? false : true }); + } + + _handle_onChangeCompanies_all = () => + { + const { selected_companies_all } = this.state; + this.setState({ selected_companies_all: selected_companies_all ? false : true }); + } + + _handle_onCompanySelect = (company) => + { + const { selected_companies_list } = this.state; + const selected_companies = []; + + let add = true; + for(let i in selected_companies_list) + { + if(selected_companies_list[i].inn !== company.inn) + { + selected_companies.push(selected_companies_list[i]); + } + else + { + add = false; + } + } + if(add) + { + selected_companies.push(company); + } + + this.setState({ selected_companies_list: selected_companies }); + } + + render() + { + const { companies } = this.props; + const { name, email, selection, selected_companies_all, selected_companies_list, } = this.state; + + return ( +
+
+ { this._handle_onChange("name", event.target.value) } }/> +
+
+ { this._handle_onChange("email", event.target.value) } }/> +
+
Пользователь
+
+ +
+
+ + +
+ { companies !== undefined && companies !== null && companies.map((company, index) => ( +
+ this._handle_onCompanySelect(company) }/> + +
+ )) } +
+
+
-
+
+ +
+
+ ) + } +} + +class AdminPage extends React.Component { constructor(props) { super(props); this.state = { - user: {}, loading: false, + user: {}, users: null, + companies: null, + add: false, + edit: false, }; } @@ -36,6 +137,7 @@ class IndexPage extends React.Component return { user: nextProps.user, users: nextProps.users, + companies: nextProps.companies, }; } @@ -55,9 +157,34 @@ class IndexPage extends React.Component }); } + _handle_onAdd = () => + { + this.setState({ add: true }); + } + + _handle_onEdit = () => + { + this.setState({ edit: true }); + } + + _handle_onSave = () => + { + this.setState({ add: false, edit: false }); + } + render() { - const { user, users } = this.state; + const { user, users, companies, add, edit } = this.state; + console.log("users"); + console.log(users); + + console.log(".".repeat(100)); + console.log("user"); + console.log(user); + + console.log(".".repeat(100)); + console.log("companies"); + console.log(companies); return ( @@ -85,8 +212,14 @@ class IndexPage extends React.Component

Настройки доступа к личному кабинету

- - + { add || edit ? ( + + ) : ( + <> + + + + ) }
@@ -104,8 +237,8 @@ class IndexPage extends React.Component { return (
-
{ entry.name }
-
{ user.email }
+
{ entry.name } (Вы)
+
{ entry.email }
Администратор
Все организации
Активен
@@ -123,7 +256,7 @@ class IndexPage extends React.Component return (
{ entry.name }
-
{ user.email }
+
{ entry.email }
Администратор
{ entry.companies.map((company, c_index) => (

{ company.title }

@@ -160,44 +293,11 @@ class IndexPage extends React.Component
-
-
- -
-
- -
-
Пользователь
-
- -
-
- - -
-
- - -
-
- - -
-
-
-
-
-
- -
-
+ {*/} + { add && ( +
+ ) } + {/*} {*/}
@@ -216,6 +316,7 @@ function mapStateToProps(state, ownProps) return { user: state.user, users: state.admin.users, + companies: state.companies.list, } } @@ -254,4 +355,4 @@ export const getServerSideProps = reduxWrapper.getServerSideProps(store => } ); -export default withRouter(connect(mapStateToProps)(IndexPage)); \ No newline at end of file +export default withRouter(connect(mapStateToProps)(AdminPage)); \ No newline at end of file diff --git a/pages/support/components/SuccessMessage/index.js b/pages/support/components/SuccessMessage/index.js index 0c6a9a3..4da5903 100644 --- a/pages/support/components/SuccessMessage/index.js +++ b/pages/support/components/SuccessMessage/index.js @@ -19,7 +19,7 @@ export default class SuccessMessage extends React.Component

{ comment }


-

Перейти в раздел «Документы по договору»

+

Сообщение успешно отправлено, ожидайте, пожалуйста, ответа от ответсвенного сотрудника Отдела
по работе с клиентами.

Перейти к списку обращений

); diff --git a/pages/support/request.js b/pages/support/request.js index 28b1617..c1b76de 100644 --- a/pages/support/request.js +++ b/pages/support/request.js @@ -19,7 +19,9 @@ import SuccessMessage from "./components/SuccessMessage"; import { getSupportThemes, getContractsList, - getBitrixFile + getBitrixFile, + sendNewAppeal, + sendAppealAttachments } from "../../actions"; class TemplateFile extends React.Component @@ -78,7 +80,7 @@ class FileDropzone extends React.Component

Приложенные файлы

{ files.map((file, index) => ( -

{ file.name } onDeleteFile(file.name) }>[ удалить ]

+

{ file.name } onDeleteFile(file.name) }>[ удалить ]

)) }
@@ -166,15 +168,55 @@ class SupportRequestPage extends React.Component this.setState({ opened_theme: index, opened_question: 0 }); } - _handle_onSendAppeal = () => + _handle_onChangeField = (field, value) => { - const { name, phone, email, question, selected_contracts, } = this.state; + this.setState({ [ field ]: value, }); + } - const appeal = { - phone: phone, - email: email, - description: question, - contract_numbers: selected_contracts + _handle_onSendAppeal = (event) => + { + event.preventDefault(); + + if(!this._checkDisabled()) + { + const { name, phone, email, question, selected_contracts, files } = this.state; + + this.setState({ loading: true }, () => + { + sendNewAppeal({ + phone: phone, + email: email, + description: question, + contract_numbers: selected_contracts + }) + .then((result) => + { + console.log("SupportRequestPage", "_handle_onSendAppeal", result); + if(files.length > 0) + { + sendAppealAttachments({ + request_client_number: result.request_client_number, + files: files, + }) + .then(() => + { + this.setState({ loading: false, success: true, }); + }) + .catch(() => + { + this.setState({ loading: false }); + }); + } + else + { + this.setState({ loading: false, success: true, }); + } + }) + .catch(() => + { + this.setState({ loading: false }); + }); + }); } } @@ -224,6 +266,17 @@ class SupportRequestPage extends React.Component this.setState({ files }); } + _checkDisabled = () => + { + const { phone, email, question, } = this.state; + if(phone === "" || email === "" || question === "") + { + return true; + } + + return false; + } + _renderForm = () => { const { loading, contracts, themes, name, phone, email, question, file, files, opened_theme, opened_question } = this.state; @@ -237,7 +290,7 @@ class SupportRequestPage extends React.Component } return ( - +
+ { this._handle_onChangeField("name", event.target.value) } }/>
- + { this._handle_onChangeField("phone", event.target.value) } }/>
- + { this._handle_onChangeField("email", event.target.value) } }/>
- +