Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

/* eslint-disable react/prop-types */
import React, { useState, useEffect } from 'react'
import { connect } from 'react-redux'
import Modal from 'react-bootstrap/Modal'
import Button from 'react-bootstrap/Button'
import { useForm } from 'react-hook-form'
import styled from 'styled-components'
import FormErrorFeedback from '../../../shared/form-error-feedback/FormErrorFeedback'
import Spinner from '../../../shared/loading-spinner/Spinner'
import { addNotification } from '../../../redux/notification/notification.actions'
import { closeShareModal, openShareModal, setModalType } from '../../../redux/share-modal/shareModal.actions'
import { addFeed, fetchFeeds } from '../../../redux/feed/feed.actions'
import DropzoneComponent from '../../../shared/dropzone/DropzoneComponent'
import { shareModalTypes } from '../../../redux/share-modal/shareModal.types'
import { feedTypes } from '../../../redux/feed/feed.types'
import { CKEditor } from 'ckeditor4-react'
import { axios, CKEDITOR_OPTIONS } from '../../../utils'
import ConfirmModal from '../../../shared/confirm-modal/ConfirmModal'

const ShareModal = ({
  postUrl,
  isOpen,
  modalType,
  lastModalType,
  setModalType,
  feedType,
  fetchFeeds,
  currentPage,
  timelineUrl,
  feedSharedId,
  closeShareModal, // Redux action
  addNotification, // Redux action
  addFeed, // Redux action
  openShareModal // Redux action
}) => {
  const [loading, setLoading] = useState(false)
  const [isCKEditorLoading, setIsCKEditorLoading] = useState(true)
  const [showConfirmModal, setShowConfirmModal] = useState(false)

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

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

  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'
      default:
        return ''
    }
  }
  useEffect(() => {
    const postedOrShared = modalType === shareModalTypes.SHARE ? 's' : 'p'
    setValue('posted_or_shared', postedOrShared)
    if (getValues('file') || getValues('description')) {
      if (modalType !== lastModalType) {
        closeShareModal()
        handleShowConfirmModal()
      }
    }
  }, [modalType])

  const hideDuplicatedModal = () => {
    setTimeout(() => {
      const modals = document.getElementsByClassName('modal')
      if (modals.length > 1 && modals[0].style.display !== 'none') {
        const currentModal = modals[0]
        currentModal.style.display = 'none'
        for (let index = 0; index < modals.length; index++) {
          const element = modals[index]
          element.removeAttribute('tabindex')
        }
      }
    }, 3000)
  }

  useEffect(() => {
    clearErrors()
    hideDuplicatedModal()
  }, [isOpen])

  const handleShowConfirmModal = () => {
    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 = async (data, e) => {
    setLoading(true)
    const currentFormData = new FormData()
    for (const input in data) {
      currentFormData.append(input, data[input])
    }
    await axios.post(postUrl, currentFormData).then((response) => {
      const data = response.data
      const newFeed = data.data
      if (data.success) {
        closeShareModal()
        // reset data
        e.target.reset()
        setValue('description', '')
        setValue('file', '')
        clearErrors()
        addNotification({
          style: 'success',
          msg: 'La publicación ha sido compartida'
        })
        if (feedSharedId) {
          addFeed(newFeed, feedSharedId)
        } else {
          addFeed(newFeed)
        }
        if (currentPage && timelineUrl) {
          fetchFeeds(timelineUrl, currentPage)
        }
      } else {
        if (data.data.description || data.data.file || data.data.share_width) {
          Object.entries(data.data)
            .map(([key, value]) => setError(key, { type: 'required', message: value })
            )
        } else {
          addNotification({
            style: 'danger',
            msg: data.data
          })
        }
      }
    })

    setLoading(false)
  }

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

  const dropZoneRender = () => {
    if (
      modalType !== shareModalTypes.POST &&
      modalType !== shareModalTypes.SHARE
    ) {
      return (
        <DropzoneComponent
          modalType={modalType}
          onUploaded={onUploadedHandler}
          settedFile={getValues('file')}
          recomendationText={recomendationText()}
        />
      )
    }
  }

  const SharedWithSelectRender = () => {
    if (feedType === feedTypes.DASHBOARD) {
      return (
        <>
          <select
            name="shared_with"
            id="shared_with"
            className="form-control"
            ref={register({ required: 'El campo es requerido' })}
            defaultValue="p"
          >
            <option disabled="disabled" value="" style={{ display: 'none' }}>
              {LABELS.SHARE_WITH}
            </option>
            <option value="p">{LABELS.PUBLIC}</option>
            <option value="c">{LABELS.CONNECTIONS}</option>
          </select>
          {errors.shared_with && <FormErrorFeedback>{errors.shared_with.message}</FormErrorFeedback>}
        </>
      )
    }
  }

  return (
    <>
      <Modal
        show={isOpen}
        onHide={closeShareModal}
        autoFocus={false}
      >
        <Modal.Header closeButton>
          <Modal.Title>{LABELS.SHARE_A_POST}</Modal.Title>
        </Modal.Header>
        <form encType="multipart/form-data" onSubmit={handleSubmit(onSubmit)}>
          <Modal.Body>
            {SharedWithSelectRender()}
            <CKEditor
              data={watch('description')}
              onChange={(e) => {
                const text = e.editor.getData()
                setValue('description', text)
                if (errors.description && getValues('description')) clearErrors('description')
              }}
              config={CKEDITOR_OPTIONS}
              name="description"
              onDialogShow={() => {
                const modal = document.querySelector('.fade.modal.show')
                modal.removeAttribute('tabindex')
              }}
              onBeforeLoad={() => {
                setIsCKEditorLoading(false)
              }}
            />
            {isCKEditorLoading && <Spinner />}
            {errors.description && <FormErrorFeedback>{errors.description.message}</FormErrorFeedback>}

            {dropZoneRender()}
            {errors.file && <FormErrorFeedback>{errors.file.message}</FormErrorFeedback>}
          </Modal.Body>
          <Modal.Footer>
            <Button size="sm" type="submit">{LABELS.SEND}</Button>
            <Button color="danger" size="sm" variant="danger" onClick={closeShareModal}>
              {LABELS.CANCEL}
            </Button>
          </Modal.Footer>
        </form>
        {loading && <Spinner />}
      </Modal>
      <ConfirmModal
        show={showConfirmModal}
        onClose={handleModalCancel}
        onAccept={handleModalAccept}
        acceptLabel={LABELS.ACCEPT}
        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),
  fetchFeeds: (url, page) => fetchFeeds(url, page)
}

export default connect(mapStateToProps, mapDispatchToProps)(ShareModal)