Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 13004 | Rev 13007 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
12709 stevensc 1
/* eslint-disable no-mixed-spaces-and-tabs */
2
import React, { useState, useEffect } from 'react'
3
import axios from 'axios'
12733 stevensc 4
import parse from 'html-react-parser'
12709 stevensc 5
import { useForm } from 'react-hook-form'
6
import { useDispatch } from 'react-redux'
12710 stevensc 7
import { useHistory, useParams } from 'react-router-dom'
12709 stevensc 8
import { addNotification } from '../../../redux/notification/notification.actions'
9
import DescriptionInput from '../../../shared/DescriptionInput'
10
import SectionModal from '../components/SectionModal'
12993 stevensc 11
import DeleteModal from '../../../shared/DeleteModal'
12996 stevensc 12
import QuestionModal from '../components/QuestionModal'
12709 stevensc 13
 
14
const sectionTypeOptions = {
15
	open: 'Abierto',
16
	simple: 'Simple'
17
}
18
 
19
const INITIAL_SECTION = {
20
	slug_section: '',
21
	name: '',
22
	text: '',
23
	position: 0,
24
	questions: [],
25
	status: 0
26
}
27
 
28
const INITIAL_QUESTION = {
29
	slug_section: '',
30
	slug_question: '',
31
	text: '',
32
	type: '',
33
	position: 0,
34
	maxlength: '0',
35
	multiline: '0',
36
	range: '0',
37
	options: [],
38
	answer: ''
39
}
40
 
41
 
42
const FormView = ({ actionLink }) => {
43
 
44
	// Hooks
45
	const history = useHistory()
12710 stevensc 46
	const { action } = useParams()
12709 stevensc 47
	const dispatch = useDispatch()
48
	const { register, setValue, watch, reset } = useForm()
49
 
50
	// Section modal states
51
	const [isShowSection, setIsShowSectionModal] = useState(false)
52
	const [sectionSelected, setSectionSelected] = useState(INITIAL_SECTION)
53
	const [sectionType, setSectionType] = useState('add')
54
 
55
	// Section modal states
56
	const [isShowQuestion, setIsShowQuestionModal] = useState(false)
57
	const [questionSelected, setQuestionSelected] = useState(INITIAL_QUESTION)
58
	const [questionType, setQuestionType] = useState('add')
59
 
60
	const [content, setContent] = useState([])
61
	const [status, setStatus] = useState('A')
12993 stevensc 62
	const [showDeleteModal, setShowDeleteModal] = useState(false)
63
	const [deleteType, setDeleteType] = useState('section')
12709 stevensc 64
 
65
	const showSectionModal = (section = INITIAL_SECTION, type = 'add') => {
66
		setIsShowSectionModal(true)
67
		setSectionSelected(section)
68
		setSectionType(type)
69
	}
70
 
71
	const closeSectionModal = () => {
72
		setIsShowSectionModal(false)
73
		setSectionSelected(INITIAL_SECTION)
74
	}
75
 
12991 stevensc 76
	const addSection = (name, text) => {
12836 stevensc 77
		const uuid = new Date().getTime()
12991 stevensc 78
		let position = content.length
79
		console.log(name)
80
		console.log(text)
12836 stevensc 81
 
12990 stevensc 82
		setContent(prev => [...prev, {
12836 stevensc 83
			slug_section: `section${uuid}`,
84
			name: name,
85
			text: text,
86
			position: position,
87
			questions: [],
88
			status: 0
12990 stevensc 89
		}])
12709 stevensc 90
	}
91
 
12993 stevensc 92
	const deleteSection = (slug) => {
93
		setContent(current =>
94
			current.filter(currentSection => {
95
				return currentSection.slug_section !== slug
96
			}),
97
		)
98
	}
99
 
100
	const deleteHandler = (type, slug) => {
101
		if (type === 'section') {
102
			return deleteSection(slug)
103
		}
104
	}
105
 
12991 stevensc 106
	const editSection = (name, text, slug) => {
12992 stevensc 107
		setContent(current =>
108
			current.map(currentSection => {
109
				if (currentSection.slug_section === slug) {
110
					return { ...currentSection, name: name, text: text }
111
				}
12991 stevensc 112
 
12992 stevensc 113
				return currentSection
114
			})
115
		)
12709 stevensc 116
	}
117
 
118
	const showQuestionModal = (question = INITIAL_QUESTION, type = 'add') => {
119
		setIsShowQuestionModal(true)
120
		setQuestionType(type)
121
		setQuestionSelected(question)
122
	}
123
 
124
	const closeQuestionModal = () => {
125
		setIsShowQuestionModal(false)
126
		setQuestionSelected(INITIAL_QUESTION)
127
	}
128
 
129
	const addQuestion = (question) => {
12996 stevensc 130
		const uuid = new Date().getTime()
131
 
13004 stevensc 132
		setContent(current =>
133
			current.map(currentSection => {
134
				if (currentSection.slug_section === sectionSelected.slug_section) {
135
					return {
136
						...currentSection,
137
						questions: [
138
							...currentSection.questions,
139
							{
140
								...question,
141
								slug_question: `question${uuid}`,
142
								slug_section: sectionSelected.slug_section,
143
							}
144
						]
145
					}
146
				}
13002 stevensc 147
 
13004 stevensc 148
				return currentSection
149
			})
150
		)
12709 stevensc 151
	}
152
 
153
	const editQuestion = (question) => {
13006 stevensc 154
		setContent(current =>
155
			current.map(currentSection => {
156
				if (currentSection.slug_section === sectionSelected.slug_section) {
13001 stevensc 157
 
13006 stevensc 158
					const newQuestions = currentSection.questions.map((currentQuestion) => {
159
						if (currentQuestion.slug_question === question.slug_question) {
160
							return question
161
						}
12709 stevensc 162
 
13006 stevensc 163
						return currentQuestion
164
					})
165
 
166
					return { ...currentSection, questions: newQuestions }
167
				}
168
 
169
				return currentSection
170
			})
171
		)
12709 stevensc 172
	}
173
 
174
	const onSubmit = () => {
175
		const submitData = new FormData()
176
		submitData.append('name', watch('name'))
177
		submitData.append('description', watch('description'))
178
		submitData.append('text', watch('text'))
179
		submitData.append('status', status)
12791 stevensc 180
		submitData.append('content', JSON.stringify(content))
12709 stevensc 181
 
182
		axios.post(actionLink, submitData)
183
			.then(({ data }) => {
184
				if (!data.success) {
185
					return dispatch(addNotification({
186
						style: 'danger',
187
						msg: typeof data.data === 'string'
188
							? data.data
189
							: 'Ha ocurrido un error'
190
					}))
191
				}
192
 
193
				dispatch(addNotification({
194
					style: 'success',
195
					msg: data.data
196
				}))
197
			})
198
	}
199
 
200
	const submitAndClose = () => {
201
		onSubmit()
202
		reset()
203
		history.goBack()
204
	}
205
 
206
	useEffect(() => {
12726 stevensc 207
		if (action === 'edit') {
208
			axios.get(actionLink)
209
				.then(({ data }) => {
210
					if (!data.success) {
211
						return dispatch(addNotification({
212
							style: 'danger',
213
							msg: 'Ha ocurrido un error'
214
						}))
215
					}
12709 stevensc 216
 
12726 stevensc 217
					setValue('name', data.data.name)
218
					setValue('description', data.data.description)
219
					setValue('text', data.data.description)
220
					setContent(data.data.content)
221
					setStatus(data.data.status)
222
				})
223
		}
12709 stevensc 224
	}, [actionLink])
225
 
226
	return (
227
		<>
228
			<section className="content">
229
				<div className="row" style={{ padding: 16 }}>
230
					<div className="col-xs-12 col-md-12">
231
						<div className="form-group">
232
							<label>Nombre</label>
233
							<input type="text" name="name" className='form-control' ref={register({ required: true, maxLength: 50 })} />
234
						</div>
235
						<div className="form-group">
236
							<label htmlFor="form-description">Descripción</label>
12856 stevensc 237
							<DescriptionInput
12733 stevensc 238
								defaultValue={watch('description') ? parse(watch('description')) : ''}
12709 stevensc 239
								name='description'
240
								onChange={setValue}
12856 stevensc 241
							/>
12709 stevensc 242
						</div>
243
						<div className="form-group">
244
							<label htmlFor="form-description">Texto</label>
12856 stevensc 245
							<DescriptionInput
12733 stevensc 246
								defaultValue={watch('text') ? parse(watch('text')) : ''}
12709 stevensc 247
								name='text'
248
								onChange={setValue}
12856 stevensc 249
							/>
12709 stevensc 250
						</div>
251
						<div className="form-group">
252
							<label htmlFor="form-status">Estatus</label>
253
							<select name="form-status" className="form-control" onChange={(e) => setStatus(e.target.value)} value={status}>
12728 stevensc 254
								<option value="A">Activo</option>
255
								<option value="I">Inactivo</option>
12709 stevensc 256
							</select>
257
						</div>
258
						<br />
259
						<div className="row">
260
							<div className="col-xs-12 col-md-12">
261
								<div className="panel-group" id="rows" >
262
									<div className="form-group">
263
										<div className="row">
264
											<div className="col-xs-12 col-md-12">
265
												<hr />
12994 stevensc 266
												<div className="d-flex justify-content-end">
267
													<button className='btn btn-primary' onClick={() => showSectionModal()}>
268
														<i className="fa fa-plus" />
269
														Agregar sección
270
													</button>
271
												</div>
12709 stevensc 272
												<br />
273
												<div className="panel-group" id="rows-job-competencies" >
274
													{
275
														content.length > 0
12836 stevensc 276
														&&
277
														content.map((section) => {
12709 stevensc 278
 
12836 stevensc 279
															return (
280
																<div className="panel panel-default" key={section.slug_section}>
281
																	<div className="panel-heading">
282
																		<h4 className="panel-title">
283
																			<a className="accordion-toggle" data-toggle="collapse" aria-expanded="true" data-parent={`panel-${section.slug_section}`} href={`#collapse-${section.slug_section}`}>
284
																				<span className={`section-name${section.slug_section}`}>
285
																					{section.name}
286
																				</span>
287
																			</a>
288
																		</h4>
289
																	</div>
290
																	<div id="collapse-section1661528423935" className="panel-collapse in collapse show">
291
																		<div className="panel-body">
292
																			<div className="table-responsive">
293
																				<table className="table table-bordered">
294
																					<thead>
295
																						<tr>
296
																							<th style={{ width: '10%' }}>Elemento</th>
297
																							<th style={{ width: '50%' }}>Texto</th>
298
																							<th style={{ width: '10%' }}>Tipo</th>
299
																							<th style={{ width: '20%' }}>Acciones</th>
300
																						</tr>
301
																					</thead>
302
																					<tbody>
303
																						<tr className="tr-section">
304
																							<td className="text-left">Sección</td>
305
																							<td className="text-left">{section.name}</td>
306
																							<td />
307
																							<td>
308
																								<button className="btn btn-default" onClick={() => showSectionModal(section, 'edit')}>
309
																									<i className="fa fa-edit" />
310
																									Editar Sección
311
																								</button>
12994 stevensc 312
																								<button className="btn btn-default" onClick={() => {
12993 stevensc 313
																									setShowDeleteModal(true)
314
																									setDeleteType('section')
12995 stevensc 315
																									setSectionSelected(section)
12993 stevensc 316
																								}}>
12836 stevensc 317
																									<i className="fa fa-ban" />
318
																									Borrar Sección
319
																								</button>
13003 stevensc 320
																								<button className="btn btn-default" onClick={() => {
321
																									showQuestionModal()
322
																									setSectionSelected(section)
323
																								}}>
12836 stevensc 324
																									<i className="fa fa-plus" />
325
																									Agregar  Pregunta
326
																								</button>
327
																							</td>
328
																						</tr>
329
																						{
330
																							section.questions.map((question) => (
331
																								<tr key={question.slug_question} className="tr-question">
332
																									<td className="text-left">Pregunta</td>
333
																									<td className="text-left">
334
																										{parse(question.text)}
335
																									</td>
336
																									<td className="text-capitalize">
337
																										{sectionTypeOptions[question.type]}
338
																									</td>
339
																									<td>
13002 stevensc 340
																										<button className="btn btn-default btn-edit-question" onClick={() => {
341
																											showQuestionModal(question, 'edit')
342
																											setSectionSelected(section)
343
																										}}>
12836 stevensc 344
																											<i className="fa fa-edit" /> Editar Pregunta
345
																										</button>
12996 stevensc 346
																										<button className="btn btn-default btn-delete-question" onClick={() => {
13002 stevensc 347
																											setQuestionSelected(question)
348
																											setDeleteType('question')
12996 stevensc 349
																											setShowDeleteModal(true)
350
																										}}>
12836 stevensc 351
																											<i className="fa fa-ban" /> Borrar Pregunta
352
																										</button>
12996 stevensc 353
																										{
354
																											question.type !== 'open'
355
																											&&
356
																											<button className="btn btn-default btn-delete-question">
357
																												<i className="fa fa-plus" /> Agregar opción
358
																											</button>
359
																										}
12836 stevensc 360
																									</td>
361
																								</tr>
362
																							))
363
																						}
364
																					</tbody>
365
																				</table>
366
																			</div>
367
																		</div>
368
																	</div>
369
																</div>
370
															)
371
														})
12709 stevensc 372
													}
373
												</div>
374
											</div>
375
										</div>
376
									</div>
377
								</div>
378
							</div>
379
						</div>
380
						<div className="d-flex" style={{ gap: '5px' }}>
381
							<button type="button" className="btn btn-info" onClick={onSubmit}>Guardar & Continuar</button>
382
							<button type="button" className="btn btn-primary" onClick={submitAndClose}>Guardar & Cerrar</button>
383
							<button type="button" className="btn btn-secondary" onClick={() => history.goBack()}>Cancelar</button>
384
						</div>
385
					</div>
386
				</div >
387
			</section >
388
			<SectionModal
389
				show={isShowSection}
12836 stevensc 390
				sectionType={sectionType}
12709 stevensc 391
				section={sectionSelected}
392
				closeModal={closeSectionModal}
393
				onSubmit={sectionType === 'add' ? addSection : editSection}
394
			/>
12996 stevensc 395
			<QuestionModal
396
				show={isShowQuestion}
397
				questionType={questionType}
398
				question={questionSelected}
399
				closeModal={closeQuestionModal}
400
				onSubmit={questionType === 'add' ? addQuestion : editQuestion}
401
			/>
12993 stevensc 402
			<DeleteModal
403
				isOpen={showDeleteModal}
404
				closeModal={() => setShowDeleteModal(false)}
405
				onComplete={() => deleteHandler(deleteType, sectionSelected.slug_section)}
406
				message="Registro eliminado"
407
			/>
12709 stevensc 408
		</>
409
	)
410
}
411
 
412
export default FormView