Proyectos de Subversion LeadersLinked - Backend

Rev

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