Proyectos de Subversion LeadersLinked - SPA

Rev

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

import React, { useEffect, useState } from 'react'
import { useForm } from 'react-hook-form'
import { connect, useSelector } from 'react-redux'
import { CKEditor } from 'ckeditor4-react'

import { axios, CKEDITOR_OPTIONS } from '@app/utils'
import { addNotification } from '@app/redux/notification/notification.actions'
import {
  closeShareModal,
  openShareModal,
  setModalType
} from '@app/redux/share-modal/shareModal.actions'
import { addFeed } from '@app/redux/feed/feed.actions'

import { shareModalTypes } from '@app/redux/share-modal/shareModal.types'
import { feedTypes } from '@app/redux/feed/feed.types'

import DropzoneComponent from '../dropzone/DropzoneComponent'
import FormErrorFeedback from '../UI/form/FormErrorFeedback'
import Modal from '../UI/modal/Modal'
import Spinner from '../UI/Spinner'
import ConfirmModal from './ConfirmModal'

const ShareModal = ({
  postUrl,
  isOpen,
  modalType,
  lastModalType,
  setModalType,
  feedType,
  feedSharedId,
  closeShareModal, // Redux action
  addNotification, // Redux action
  addFeed, // Redux action
  openShareModal // Redux action
}) => {
  const [isCKEditorLoading, setIsCKEditorLoading] = useState(true)
  const [showConfirmModal, setShowConfirmModal] = useState(false)
  const labels = useSelector(({ intl }) => intl.labels)

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

  const recomendationText = () => {
    switch (modalType) {
      case shareModalTypes.IMAGE:
        return 'Tamaño recomendado: 720x720'
      case shareModalTypes.FILE:
        return 'solo documentos PDF'
      case shareModalTypes.VIDEO:
        return 'Video de extensión mp4, mpeg, webm, mov'
      default:
        return ''
    }
  }

  const toggleConfirmModal = () => setShowConfirmModal(!showConfirmModal)

  const handleModalAccept = () => {
    setShowConfirmModal(false)
    setValue('description', '')
    setValue('file', '')
    openShareModal(postUrl, modalType, feedType)
    clearErrors()
  }

  const handleModalCancel = () => {
    setShowConfirmModal(false)
    closeShareModal()
    setModalType(lastModalType)
    openShareModal(postUrl, lastModalType, feedType)
  }

  const onSubmit = handleSubmit((data) => {
    const currentFormData = new FormData()

    Object.entries(data).forEach(([key, value]) =>
      currentFormData.append(key, value)
    )

    axios
      .post(postUrl, currentFormData)
      .then((response) => {
        const { data, success } = response.data

        if (!success && typeof data !== 'string') {
          Object.entries(data).map(([key, value]) =>
            setError(key, { type: 'required', message: value[0] })
          )
          return
        }

        if (!success && typeof data === 'string') {
          throw new Error(data)
        }

        const newFeed = data

        addNotification({
          style: 'success',
          msg: 'La publicación ha sido compartida'
        })
        reset()
        onClose()

        if (feedSharedId) {
          addFeed(newFeed, feedSharedId)
        } else {
          addFeed(newFeed)
        }
      })
      .catch((error) => {
        console.log(error)
        addNotification({
          style: 'danger',
          msg: 'Ha ocurrido un error al publicar, intente más tarde.'
        })
      })
  })

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

  const onClose = () => {
    clearErrors()
    closeShareModal()
  }

  useEffect(() => {
    const postedOrShared = modalType === shareModalTypes.SHARE ? 's' : 'p'

    register('posted_or_shared')
    setValue('posted_or_shared', postedOrShared)

    if (
      modalType !== shareModalTypes.POST &&
      modalType !== shareModalTypes.SHARE
    ) {
      register('file', {
        required: { value: 'true', message: 'El campo es requerido' }
      })
    } else {
      if (!getValues('file')) unregister('file')
    }

    if (getValues('file') || getValues('description')) {
      if (modalType !== lastModalType) {
        onClose()
        toggleConfirmModal()
      }
    }
  }, [modalType])

  useEffect(() => {
    if (isOpen) {
      register('description', { required: 'El campo es requerido' })
    }
  }, [isOpen])

  return (
    <>
      <Modal
        show={isOpen}
        title={labels.share_a_post}
        labelAccept={labels.send}
        labelReject={labels.cancel}
        onClose={onClose}
        onAccept={onSubmit}
      >
        {feedType === feedTypes.DASHBOARD ? (
          <select
            name='shared_with'
            className='form-control'
            defaultValue='p'
            ref={register}
          >
            <option value='p'>{labels.public}</option>
            <option value='c'>{labels.connections}</option>
          </select>
        ) : null}

        <CKEditor
          data={getValues('description')}
          config={CKEDITOR_OPTIONS}
          onChange={({ editor }) => setValue('description', editor.getData())}
          onDialogShow={() => {
            const modal = document.querySelector('.fade.modal.show')
            modal.removeAttribute('tabindex')
          }}
          onBeforeLoad={() => setIsCKEditorLoading(false)}
        />

        {isCKEditorLoading && <Spinner />}

        {errors.description && (
          <FormErrorFeedback>{errors.description.message}</FormErrorFeedback>
        )}

        {![shareModalTypes.POST, shareModalTypes.SHARE].includes(modalType) ? (
          <DropzoneComponent
            modalType={modalType}
            onUploaded={onUploadedHandler}
            settedFile={watch('file')}
            recomendationText={recomendationText()}
          />
        ) : null}

        {errors.file && (
          <FormErrorFeedback>{errors.file.message}</FormErrorFeedback>
        )}
      </Modal>
      <ConfirmModal
        show={showConfirmModal}
        onClose={handleModalCancel}
        onAccept={handleModalAccept}
        message='¿No se ha compartido tu publicación , desea descartarlo?'
      />
    </>
  )
}

const mapStateToProps = (state) => ({
  isOpen: state.shareModal.isOpen,
  postUrl: state.shareModal.postUrl,
  modalType: state.shareModal.modalType,
  lastModalType: state.shareModal.lastModalType,
  feedType: state.shareModal.feedType,
  feedSharedId: state.shareModal.feedSharedId
})

const mapDispatchToProps = {
  addNotification: (notification) => addNotification(notification),
  closeShareModal: () => closeShareModal(),
  openShareModal: (postUrl, modalType, feedType) =>
    openShareModal(postUrl, modalType, feedType),
  setModalType: (modalType) => setModalType(modalType),
  addFeed: (feed, feedSharedId) => addFeed(feed, feedSharedId)
}

export default connect(mapStateToProps, mapDispatchToProps)(ShareModal)