Rev 5255 | 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}
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)