Proyectos de Subversion LeadersLinked - Backend

Rev

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)