Rev 16755 | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useState, useEffect } from 'react'
import axios from 'axios'
import { useForm } from 'react-hook-form'
import { connect } from 'react-redux'
import { Button, Modal } from 'react-bootstrap'
import Datetime from 'react-datetime'
import 'react-datetime/css/react-datetime.css'
import { addFeed, fetchFeeds } from '../../../redux/feed/feed.actions'
import { addNotification } from '../../../redux/notification/notification.actions'
import { closeSurveyModal } from '../../../redux/survey-modal/surveyModal.actions'
const SurveyModal = (props) => {
const { addNotification, addFeed, closeSurveyModal } = props // Redux actions
const { postUrl, isOpen, currentPage, timelineUrl, state } = props // Redux states
const [loading, setLoading] = useState(false)
const [selectedDate, setSelectedDate] = useState(null)
const [optionsNumber, setOptionsNumber] = useState(2)
const { register, handleSubmit, setValue, clearErrors, reset } = useForm()
const options = [
{ placeholder: 'Por ejemplo: transporte público' },
{ placeholder: 'Por ejemplo: coche propio' },
{ placeholder: 'Por ejemplo: coche compartido' },
{ placeholder: 'Por ejemplo: bicicleta' },
{ placeholder: 'Por ejemplo: otro' }
]
const calculateMaxDate = () => {
const today = new Date()
const maxDate = today.setDate(today.getDate() + 29)
return new Date(maxDate)
}
const calculateMinDate = () => {
return new Date()
}
const handleChange = (selected) => {
setSelectedDate(selected)
if (!selected) {
return null
}
const currentDate = new Date()
const selectedDt = new Date(selected.format('YYYY-MM-DD HH:mm'))
const timeDiff = selectedDt.getTime() - currentDate.getTime()
const daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24))
const hoursDiff = Math.floor((timeDiff / (1000 * 60 * 60)) % 24)
const minutesDiff = Math.floor((timeDiff / (1000 * 60)) % 60)
setValue('duration_days', daysDiff)
setValue('duration_hours', hoursDiff)
setValue('duration_minutes', minutesDiff)
}
const addOption = () => {
setOptionsNumber(optionsNumber + 1)
}
const removeOption = () => {
setOptionsNumber(optionsNumber - 1)
}
const closeModal = () => {
closeSurveyModal()
}
const onSubmit = handleSubmit((data) => {
setLoading(true)
const formData = new FormData()
Object.entries(data).map(([entry, value]) => formData.append(entry, value))
for (let i = 1; i <= 5; i++) {
!data[`answer${i}`] && formData.append(`answer${i}`, '')
}
const numberOfAnswers = Object.entries(data).filter((entry) =>
entry[0].includes('answer')
).length
formData.append('feed_content_type', 'fast-survey')
formData.append('number_of_answers', numberOfAnswers)
formData.append('posted_or_shared', 'POST')
axios
.post(postUrl, formData)
.then(({ data: response }) => {
const { success, data } = response
if (!success) {
typeof data !== 'string'
? Object.entries(data).map(([key, value]) =>
addNotification({ style: 'danger', msg: `${key}: ${value[0]}` })
)
: addNotification({ style: 'danger', msg: data })
return
}
if (currentPage && timelineUrl) {
fetchFeeds(timelineUrl, currentPage)
}
addFeed(data)
addNotification({
style: 'success',
msg: 'La publicación ha sido compartida'
})
reset()
clearErrors()
closeModal()
})
.catch((err) => {
addNotification({ style: 'danger', msg: `Error: ${err}` })
throw new Error(err)
})
.finally(() => setLoading(false))
})
useEffect(() => {
clearErrors()
}, [isOpen])
useEffect(() => {
register('duration_days')
register('duration_hours')
register('duration_minutes')
}, [])
return (
<Modal show={isOpen} onHide={closeModal}>
<form onSubmit={onSubmit} method="post">
<Modal.Header closeButton>
<Modal.Title>Encuesta rápida</Modal.Title>
</Modal.Header>
<Modal.Body>
<div className="form-row">
<div className="form-group col">
<label htmlFor="privacy">Privacidad</label>
<select
className="form-control"
name="privacy"
id="privacy"
ref={register}
>
<option value="c">Compañía</option>
<option value="p">Público</option>
</select>
</div>
<div className="form-group col">
<label htmlFor="result_type">Resultado</label>
<select
className="form-control"
name="result_type"
id="result_type"
ref={register}
>
<option value="pr">Privado</option>
<option value="pu">Público</option>
</select>
</div>
</div>
<div className="form-group">
<label htmlFor="question">Tu pregunta*</label>
<input
type="text"
className="form-control"
placeholder="Por ejemplo: ¿cómo te desplazas al trabajo?"
maxLength={1024}
id="question"
name="question"
ref={register({ required: true })}
/>
</div>
{options.slice(0, optionsNumber).map((option, index) => (
<div className="form-group" key={index}>
<label htmlFor={`answer${index + 1}`}>Opción {index + 1}*</label>
{index > 1 && (
<button className="btn" onClick={removeOption}>
Eliminar
</button>
)}
<input
type="text"
className="form-control"
placeholder={option.placeholder}
maxLength={100}
id={`answer${index + 1}`}
name={`answer${index + 1}`}
ref={register({ required: true })}
/>
</div>
))}
{optionsNumber < options.length && (
<button
className="btn btn-outline-primary rounded"
onClick={addOption}
>
Añadir opción
</button>
)}
<div className="form-group">
<label htmlFor="question">Duración</label>
<Datetime
dateFormat="DD/MM/YYYY"
onChange={handleChange}
isValidDate={(current) =>
current.isBefore(calculateMaxDate()) &&
current.isAfter(calculateMinDate())
} // Se valida que la fecha esté entre la fecha mínima y la fecha máxima
value={selectedDate}
/>
</div>
</Modal.Body>
<Modal.Footer>
<Button size="sm" type="submit" disabled={loading}>
Enviar
</Button>
<Button
variant="light"
size="sm"
disabled={loading}
onClick={closeModal}
>
Cancelar
</Button>
</Modal.Footer>
</form>
</Modal>
)
}
const mapStateToProps = (state) => ({
isOpen: state.surveyModal.isOpen,
postUrl: state.surveyModal.postUrl,
currentPage: state.feed.currentPage,
timelineUrl: state.feed.timelineUrl,
state: state
})
const mapDispatchToProps = {
addNotification: (notification) => addNotification(notification),
closeSurveyModal: () => closeSurveyModal(),
addFeed: (feed) => addFeed(feed)
}
export default connect(mapStateToProps, mapDispatchToProps)(SurveyModal)