Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 15354 | Rev 16672 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

import React, { useState, useEffect } from 'react'
import axios from 'axios'
import { Modal } from 'react-bootstrap'
import { useForm } from 'react-hook-form'
import { shareModalTypes } from '../redux/share-modal/shareModal.types'
import {
  closeShareModal,
  setModalType
} from '../redux/share-modal/shareModal.actions'
import { useDispatch, useSelector } from 'react-redux'
import DropzoneComponent from './Dropzone/DropzoneComponent'
import { addFeed, fetchFeeds } from '../redux/feed/feed.actions'
import { addNotification } from '../redux/notification/notification.actions'
import Spinner from './Spinner'
import { CKEditor } from 'ckeditor4-react'
import { config } from './helpers/ckeditor_config'

const ShareModal = () => {
  const [loading, setLoading] = useState(false)
  const { postUrl, isOpen, modalType } = useSelector(
    ({ shareModal }) => shareModal
  )
  const { currentPage, timelineUrl, feedSharedId } = useSelector(
    ({ feed }) => feed
  )
  const dispatch = useDispatch()

  const {
    register,
    unregister,
    errors,
    handleSubmit,
    setValue,
    getValues,
    clearErrors,
    reset
  } = useForm({
    defaultValues: {
      description: '',
      share_width: ''
    }
  })

  useEffect(() => {
    register('description', { required: 'El campo es requerido' })
    register('posted_or_shared')
    setValue('posted_or_shared', shareModalTypes.POST)

    if (modalType !== shareModalTypes.POST) {
      register('file', { required: 'El campo es requerido' })
    }

    if (modalType === shareModalTypes.POST) {
      unregister('file')
    }
  }, [modalType])

  const recomendationText = {
    IMAGE: 'Tamaño recomendado: 720x720',
    FILE: 'solo documentos PDF',
    VIDEO: 'Video de extensión mp4, mpeg, webm'
  }

  const closeModal = () => dispatch(closeShareModal())

  useEffect(() => clearErrors(), [isOpen])

  const onSubmit = (data) => {
    setLoading(true)
    const currentFormData = new FormData()

    Object.entries(data).map(([entry, value]) =>
      currentFormData.append(entry, value)
    )

    axios
      .post(postUrl, currentFormData)
      .then(({ data }) => {
        const newFeed = data.data
        if (!data.success) {
          typeof data.data === 'string'
            ? dispatch(
                addNotification({
                  style: 'danger',
                  msg: data.data
                })
              )
            : Object.entries(data.data).map(([key, value]) =>
                value.map((err) =>
                  dispatch(
                    addNotification({
                      style: 'danger',
                      msg: `${key}: ${err}`
                    })
                  )
                )
              )
          return
        }
        reset()
        clearErrors()
        dispatch(
          addNotification({
            style: 'success',
            msg: 'La publicación ha sido compartida'
          })
        )

        if (currentPage && timelineUrl)
          dispatch(fetchFeeds(timelineUrl, currentPage))

        if (feedSharedId) return dispatch(addFeed(newFeed, feedSharedId))

        return dispatch(addFeed(newFeed))
      })
      .catch((err) =>
        dispatch(addNotification({ style: 'danger', msg: `Error: ${err}` }))
      )
      .finally(() => {
        setLoading(false)
        closeModal()
      })
  }

  const onUploadedHandler = (files) => {
    setValue('file', files)
    clearErrors('file')
  }

  return (
    <Modal show={isOpen} onHide={closeModal} autoFocus={false}>
      <form onSubmit={handleSubmit(onSubmit)}>
        <Modal.Header closeButton>
          <Modal.Title>Compartir una publicación</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          {loading ? (
            <Spinner />
          ) : (
            <>
              <CKEditor
                onChange={(e) => setValue('description', e.editor.getData())}
                config={config}
              />
              {errors.description && <p>{errors.description.message}</p>}
              {modalType === shareModalTypes.SURVEY && <SurveyForm />}
              {![shareModalTypes.POST, shareModalTypes.SURVEY].includes(
                modalType
              ) && (
                <DropzoneComponent
                  modalType={modalType}
                  onUploaded={onUploadedHandler}
                  settedFile={getValues('file')}
                  recomendationText={recomendationText[modalType]}
                />
              )}
              {errors.file && <p>{errors.file.message}</p>}
            </>
          )}
        </Modal.Body>
        <Modal.Footer>
          <button
            className="btn btn-sm btn-primary"
            disabled={loading}
            type="submit"
          >
            Enviar
          </button>
          <button
            className="btn btn-sm btn-tertiary"
            disabled={loading}
            onClick={closeModal}
          >
            Cancelar
          </button>
          <button
            className="btn"
            disabled={loading}
            onClick={() => dispatch(setModalType(shareModalTypes.SURVEY))}
          >
            Añadir encuesta
          </button>
        </Modal.Footer>
      </form>
    </Modal>
  )
}

const SurveyForm = () => {
  const { register, reset, errors, watch } = useForm()
  const [optionsNumber, setOptionsNumber] = useState(2)

  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 addOption = () => {
    setOptionsNumber(optionsNumber++)
  }

  const removeOption = () => {
    setOptionsNumber(optionsNumber--)
  }

  return (
    <>
      <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={140}
          id="question"
          name="question"
          ref={register({ required: true })}
        />
        <span>{watch('question').lenght}/140</span>
      </div>
      {options.slice(0, optionsNumber).map((option, index) => (
        <div className="form-group" key={index}>
          <label htmlFor={`option-${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={30}
            id={`option-${index + 1}`}
            name={`option-${index + 1}`}
            ref={register({ required: true })}
          />
          <span>{watch(`option-${index + 1}`).lenght}/30</span>
        </div>
      ))}
      <button className="btn btn-outline-primary rounded" onClick={addOption}>
        Añadir opción
      </button>
    </>
  )
}

export default ShareModal