389 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from "react";
import Head from "next/head";
import Image from "next/image";
import { connect } from "react-redux";
import { withRouter } from "next/router";
import moment from "moment";
import { SpinnerCircular } from "spinners-react";
import Dropzone from 'react-dropzone';
import Select from 'react-select'
import { reduxWrapper } from "../../store";
import Header from "../components/Header";
import Footer from "../components/Footer";
import Company from "../components/Company";
import InnerMenu from "./components/InnerMenu";
import SuccessMessage from "./components/SuccessMessage";
import {
getSupportThemes,
getContractsList,
getBitrixFile
} from "../../actions";
class TemplateFile extends React.Component
{
constructor(props)
{
super(props);
this.state = {
downloading: false
}
}
_handle_onDownloadFile = () =>
{
const { filename, url } = this.props.template;
const { downloading } = this.state;
if(!downloading)
{
this.setState({ downloading: true }, () =>
{
getBitrixFile({ url, filename })
.then(() => { this.setState({ downloading: false }); })
.catch(() => { this.setState({ downloading: false }); });
});
}
}
render()
{
const { template } = this.props;
const { downloading } = this.state;
return (
<div className="row interactive" onClick={ this._handle_onDownloadFile }>
<p className="doc_name i-pdf extension" data-format={ template.extension }>{ template.filename }<span style={{ position: "relative", color: downloading ? "#8e94a780" : "#8e94a7" }}>Скачать шаблон{ downloading ? (<SpinnerCircular size={ 20 } thickness={ 100 } speed={ 100 } color="rgba(236, 239, 244, 1)" secondaryColor="rgba(28, 1, 169, 1)" style={{ position: "absolute", right: 0, marginRight: "-26px", top: 0, }} />) : null }</span></p>
</div>
)
}
}
class FileDropzone extends React.Component
{
constructor(props)
{
super(props);
this.state = {}
}
render()
{
const { files, onAddFile, onDeleteFile } = this.props;
return (
<>
{ files.length > 0 && (
<div className="column">
<div className="column_text_block">
<p><b>Приложенные файлы</b></p>
{ files.map((file, index) => (
<p key={ index }>{ file.name } <small style={{ color: "red", textDecoration: "underline", cursor: "pointer" }} onClick={ () => onDeleteFile(file.name) }>[ удалить ]</small></p>
)) }
</div>
</div>
) }
<Dropzone onDrop={ (acceptedFiles) => onAddFile(acceptedFiles) }>
{ ({getRootProps, getInputProps}) => (
<div className="file_upload dropzone" { ...getRootProps() }>
<div className="files"></div>
<div>
<p data-sm-text="Выберите файлы">
<span>Перенесите файлы на экран для быстрой загрузки или выберите файл с компьютера </span>
</p>
<label htmlFor="" className="button button-blue">Загрузить файл</label>
</div>
<input { ...getInputProps() } />
</div>
) }
</Dropzone>
</>
)
}
}
class SupportRequestPage extends React.Component
{
constructor(props) {
super(props);
this.state = {
loading: false,
contracts: null,
themes: null,
name: "",
phone: "",
email: "",
question: "",
selected_contracts: [],
file: null,
files: [],
opened_theme: 0,
opened_question: 0,
success: false,
};
}
static getDerivedStateFromProps(nextProps, prevState)
{
return {
contracts: nextProps.contracts,
themes: nextProps.themes,
};
}
componentDidMount()
{
console.log("CDM", "SupportRequestPage", this.state);
if (!this.state.loading)
{
this.setState({ loading: true }, () =>
{
Promise.all([
getContractsList({ dispatch: this.props.dispatch, all: true }),
getSupportThemes({ dispatch: this.props.dispatch })
])
.then(() =>
{
this.setState({ loading: false });
})
.catch(() => {});
});
}
}
componentDidUpdate(prevProps, prevState)
{
}
_handle_onBack = () =>
{
this.props.router.push('/support/faq/');
}
_handle_onChangeTheme = (index) =>
{
this.setState({ opened_theme: index, opened_question: 0 });
}
_handle_onSendAppeal = () =>
{
const { name, phone, email, question, selected_contracts, } = this.state;
const appeal = {
phone: phone,
email: email,
description: question,
contract_numbers: selected_contracts
}
}
_handle_onContract = (options) =>
{
const selected_contracts = [];
for(let i in options)
{
selected_contracts.push(options[i].value);
this.setState({ selected_contracts });
}
}
_handle_onAddFile = (files) =>
{
console.log("_handle_onAdd", files);
const existed_files = [ ...this.state.files ];
for(let nf in files)
{
let e = false;
for(let ef in this.state.files)
{
if(this.state.files[ef].name === files[nf].name) { e = true; }
}
if(!e)
{
existed_files.push(files[nf]);
}
}
this.setState({ files: existed_files });
}
_handle_onDeleteFile = (file_name) =>
{
const files = [];
for(let i in this.state.files)
{
if(this.state.files[i].name !== file_name)
{
files.push(this.state.files[i]);
}
}
this.setState({ files });
}
_renderForm = () =>
{
const { loading, contracts, themes, name, phone, email, question, file, files, opened_theme, opened_question } = this.state;
const contracts_list = [];
for(let i in contracts)
{
contracts_list.push({
value: contracts[i].number, label: contracts[i].number
});
}
return (
<form>
<div className="form_field">
<Select
options={ contracts_list }
isMulti
className="custom-multi-select form_field"
classNamePrefix="custom-select"
placeholder="Выберите договоры"
onChange={ this._handle_onContract }
/>
</div>
<div className="form_field">
<input
type="text"
name="name"
placeholder="Ваше ФИО"
/>
</div>
<div className="form_field">
<input type="tel" name="name" placeholder="Телефон" />
</div>
<div className="form_field">
<input type="email" name="name" placeholder="Email" />
</div>
<div className="form_field">
<textarea placeholder="Введите текст запроса" style={{ resize: "none" }}></textarea>
</div>
<FileDropzone files={ files } onAddFile={ this._handle_onAddFile } onDeleteFile={ this._handle_onDeleteFile }/>
</form>
)
}
render()
{
const { number } = this.props;
const { loading, success, themes, opened_theme, opened_question } = this.state;
const procedure = themes !== undefined && themes !== null ? themes[opened_theme].questions[opened_question] : undefined;
return (
<React.Fragment>
<Head>
<title>ЛК Эволюция автолизинга</title>
<meta name="description" content="ЛК Эволюция автолизинга" />
</Head>
<Header { ...this.props } />
<main>
<section>
<div className="clear"></div>
<div className="container">
<div className="title_wrapper">
<div className="left" style={{ alignItems: "center", flexWrap: "wrap" }}>
<button className="back" onClick={ this._handle_onBack }>Назад</button>
<h1 className="section_title">Новое обращение</h1>
</div>
<Company { ...this.props }/>
</div>
<div className="aside_container about">
{ loading ? (
<div className="container" style={{ display: "flex", alignItems: "center", justifyContent: "center", }}>
<SpinnerCircular size={ 90 } thickness={ 51 } speed={ 100 } color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" />
</div>
) : (
<>
{ success ? (
<SuccessMessage/>
) : (
<article className="full">
<div className="new_appeal">
<div className="column">
<div className="dropdown_blocks_list appeal_list visible">
{ themes !== undefined && themes !== null && themes.map((theme, theme_index) =>
(
<React.Fragment key={ `theme_${ theme_index }` } >
<div className={ `appeal_item dropdown_block ${ theme_index === opened_theme && "open" }` } style={ theme_index === opened_theme ? { backgroundColor: "unset"} : {} } onClick={ () => this._handle_onChangeTheme(theme_index) }>
<div className="block_header">
<p style={{ fontWeight: "bold" }}>{ theme.name }</p>
<button className="rotate"></button>
</div>
</div>
{ theme_index === opened_theme && theme.questions.map((question, question_index) => (
<div key={ `question_${ question_index }` } className={ `appeal_item dropdown_block ${ question_index === opened_question && "open" }` } style={{ paddingLeft: "20px" }} onClick={ () => this.setState({ opened_question: question_index }) }>
<div className="block_header">
<p>{ question.title }</p>
<button className="rotate"></button>
</div>
</div>
) )}
</React.Fragment>
)) }
</div>
</div>
{ themes !== undefined && themes !== null && (
<div className="column">
<div className="column_text_block">
<p><b>Процедура</b></p>
<p dangerouslySetInnerHTML={{ __html: procedure.answer }}/>
</div>
{ procedure.documents !== null && (
<div className="column_text_block">
<p><b>Документы</b></p>
<p dangerouslySetInnerHTML={{ __html: procedure.documents }}/>
</div>
) }
{ procedure.templates !== null && (
<div className="column_text_block">
<p><b>Документы</b></p>
<div className="dosc_list medium-icon">
{ procedure.templates.map((template, index) => (<TemplateFile key={ `template_${ index }` } template={ template } />)) }
</div>
</div>
) }
{ this._renderForm() }
</div>
) }
</div>
</article>
) }
</>
) }
</div>
</div>
</section>
</main>
<Footer />
</React.Fragment>
);
}
}
function mapStateToProps(state, ownProps)
{
return {
contracts: state.contracts.list,
themes: state.support.themes,
appeal: state.support.appeal,
};
}
export const getServerSideProps = reduxWrapper.getServerSideProps(
(store) =>
async ({ req, res, query }) => {
return {
props: {
},
};
}
);
export default withRouter(connect(mapStateToProps)(SupportRequestPage));