· 6 years ago · Nov 06, 2019, 03:52 PM
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { connect } from 'react-redux';
4import { injectIntl } from 'react-intl';
5
6import api from 'api';
7
8import { clearStorageAndCookies, areKeysPresentInObject, getRequiredFields } from 'helpers';
9import { HeaderLogo } from 'helpers/commonStyles';
10
11import { setAuthenticated, setUserLoggedOut } from 'stores/auth';
12import { setDocumentStructure } from 'stores/reportTemplate';
13
14import { GENERAL_KEY, DETAILED_KEY, ACTIONS_KEY } from './parts/constants';
15import ReportingColumn from './parts/ReportingColumn';
16import FirstStep from './parts/FirstStep';
17import SecondStep from './parts/SecondStep';
18import TokenModal from './parts/TokenModal';
19import RouteLoader from 'components/RouteLoader';
20import ReportWrapper from 'components/ReportWrapper';
21import Heading from 'components/Heading';
22
23import { messages } from './messages';
24
25const propTypes = {
26 setAuthenticated: PropTypes.func,
27 setDocumentStructure: PropTypes.func,
28 history: PropTypes.object,
29 reportStructure: PropTypes.object,
30 isTemplateReady: PropTypes.bool,
31 setUserLoggedOut: PropTypes.func,
32 intl: PropTypes.object
33};
34
35class ReportMisconduct extends Component {
36 constructor(props) {
37 super(props);
38
39 this.state = {
40 reportDetails: {
41 [GENERAL_KEY]: {},
42 [DETAILED_KEY]: {},
43 [ACTIONS_KEY]: {}
44 },
45 dataFetched: props.isTemplateReady || false,
46 currentStep: 1,
47 isLoading: false,
48 error: '',
49 reportToken: ''
50 }
51 }
52
53 static isStepFinished(object, keys) {
54 return areKeysPresentInObject(object, keys);
55 }
56
57 isAnswerValid = (object) => {
58 return Object.values(object).every((item) => (
59 item && Array.isArray(item) ? item.length >= 1 : item.length > 2
60 ));
61 };
62
63 componentDidMount() {
64 const { setDocumentStructure, setUserLoggedOut } = this.props;
65
66 clearStorageAndCookies();
67 setUserLoggedOut();
68
69 return api.misconduct
70 .getTemplate()
71 .then(res => {
72 setDocumentStructure(res.data);
73 this.setState({
74 dataFetched: true
75 });
76 })
77 .catch(() => {
78 this.setState({
79 dataFetched: false
80 });
81 });
82 }
83
84 handleFieldChange = (key, id, value) => {
85 this.setState({
86 reportDetails: {
87 ...this.state.reportDetails,
88 [key]: {
89 ...this.state.reportDetails[key],
90 [id]: value
91 }
92 }
93 });
94 };
95
96 isRequestProcessing = (bool) => {
97 this.setState({
98 isLoading: bool
99 })
100 };
101
102 sendMisconduct = (data) => {
103 const serializedData = JSON.stringify(data);
104
105 this.isRequestProcessing(true);
106
107 return api.misconduct
108 .postAnswers(serializedData)
109 .then(res => {
110 this.isRequestProcessing(false);
111 this.setState({
112 reportToken: res.data.report_token,
113 currentStep: 3
114 });
115 })
116 .catch((error) => {
117 this.isRequestProcessing(false);
118 this.setState({
119 error: error.response.data.message
120 });
121 });
122 };
123
124 handleStepChange = () => {
125 const { currentStep, reportDetails } = this.state;
126
127 if (currentStep === 2) {
128 this.sendMisconduct(reportDetails);
129 } else {
130 this.setState({
131 currentStep: 2
132 }, () => window.scrollTo(0, 0))
133 }
134 };
135
136 render() {
137 const { dataFetched, currentStep, reportDetails, error, reportToken } = this.state;
138 const { reportStructure, isTemplateReady, intl } = this.props;
139
140 const isDataFetching = !dataFetched && !isTemplateReady;
141 const isDataFetched = reportStructure && isTemplateReady;
142
143 if (isDataFetching) {
144 return <RouteLoader label={intl.formatMessage(messages.routeLoading)} />;
145 }
146
147 if (isDataFetched) {
148 const firstStepRequiredFields = getRequiredFields(reportStructure[GENERAL_KEY]);
149 const secondStepRequiredFields = getRequiredFields(reportStructure[DETAILED_KEY]);
150 const firstStepFinished = ReportMisconduct.isStepFinished(reportDetails[GENERAL_KEY], firstStepRequiredFields);
151 const secondStepFinished = ReportMisconduct.isStepFinished(reportDetails[DETAILED_KEY], secondStepRequiredFields) && this.isAnswerValid(reportDetails[DETAILED_KEY]);
152 const mergedObject = {[DETAILED_KEY]: reportStructure[DETAILED_KEY], [ACTIONS_KEY]: reportStructure[ACTIONS_KEY]};
153
154 return (
155 <>
156 {currentStep < 3 ?
157 <ReportWrapper
158 isSticky
159 columnComponent={
160 <ReportingColumn
161 step={currentStep}
162 isButtonDisabled={currentStep < 2 ? !firstStepFinished : !secondStepFinished}
163 buttonAction={this.handleStepChange}
164 />
165 }
166 >
167 <HeaderLogo />
168
169 <Heading label={intl.formatMessage(messages.addNewComplain)} />
170
171 <FirstStep
172 isActive={currentStep === 1}
173 questionsObject={reportStructure[GENERAL_KEY]}
174 changeHandler={this.handleFieldChange}
175 />
176
177 <SecondStep
178 isActive={currentStep === 2 && firstStepFinished}
179 questionsObject={mergedObject}
180 detailedFields={reportStructure[DETAILED_KEY]}
181 actionFields={reportStructure[ACTIONS_KEY]}
182 changeHandler={this.handleFieldChange}
183 errorDetails={error}
184 />
185 </ReportWrapper>
186 :
187 reportToken && (<TokenModal token={reportToken} isModalOpen={reportToken} />)
188 }
189 </>
190 );
191 }
192 }
193}
194
195ReportMisconduct.propTypes = propTypes;
196
197const mapDispatchToProps = {
198 setAuthenticated,
199 setUserLoggedOut,
200 setDocumentStructure
201};
202
203export default injectIntl(connect(
204 state => ({
205 reportStructure: state.reportTemplate.reportStructure,
206 isTemplateReady: state.reportTemplate.isTemplateReady
207 }),
208 mapDispatchToProps
209)(ReportMisconduct));