AutorÃa | Ultima modificación | Ver Log |
import React, { useState, useCallback, useEffect } from 'react'
import { useDropzone } from 'react-dropzone'
import { shareModalTypes } from '../../redux/share-modal/shareModal.types'
import IconButton from '@mui/material/IconButton'
import CloseIcon from '@mui/icons-material/Close'
import styled from 'styled-components'
import FormErrorFeedback from '../UI/FormErrorFeedback'
const DragAndDropContainer = styled.div`
display: flex;
flex-direction: column;
align-items: center;
padding: 2rem 0;
border: 2px dashed #eee;
border-radius: 2;
background-color: #fafafa;
color: #bdbdbd;
outline: none;
transition: border 0.24s ease-in-out;
margin-top: 1rem;
cursor: pointer;
`
const PreviewContainer = styled.div`
display: flex;
margin-top: 16px;
position: relative;
justify-content: center;
img {
width: auto;
height: 100%;
max-height: 200px;
max-width: 350px;
object-fit: contain;
}
`
const CloseButton = styled(IconButton)`
position: absolute;
background-color: #000 !important;
color: #fff;
&:hover {
color: #fff !important;
}
`
const areEqual = (prevProps, nextProps) => {
return prevProps.settedFile === nextProps.settedFile
}
const DropzoneComponent = ({
modalType,
onUploaded,
settedFile,
recomendationText,
}) => {
const [errors, setErrors] = useState([])
const [files, setFiles] = useState([])
const acceptedMimeTypes = () => {
switch (modalType) {
case shareModalTypes.IMAGE:
return 'image/jpeg, image/png, image/jpg'
case shareModalTypes.FILE:
return 'application/pdf, application/vnd.openxmlformats-officedocument.presentationml.presentation'
case shareModalTypes.VIDEO:
return 'video/mp4, video/mpeg, video/webm'
case shareModalTypes.CHAT:
return 'video/mp4, video/mpeg, video/webm, application/pdf, image/jpeg, image/png, image/jpg'
default:
return null
}
}
const onDropRejected = useCallback((rejectedFiles) => {
rejectedFiles.map((fileRejection) => {
switch (fileRejection.errors[0].code) {
case 'too-many-files':
setErrors([...errors, 'solo puedes agregar 1 archivo'])
break
case 'file-invalid-type':
setErrors([...errors, 'por favor seleccione un archivo valido'])
break
default:
setErrors(errors)
break
}
})
}, [])
const { getRootProps, getInputProps } = useDropzone({
accept: acceptedMimeTypes(),
multiple: false,
onDrop: (acceptedFiles) => {
onUploaded(acceptedFiles[0])
setFiles(acceptedFiles.map((file) => file))
},
onDropRejected,
onDropAccepted: () => {
setErrors([])
},
maxFiles: 1,
})
const onDeleteFileHandler = (index) => {
onUploaded('')
setFiles([])
}
useEffect(() => {
if (!settedFile) return
setFiles([settedFile])
}, [settedFile])
const filePreviewTest = (file) => {
switch (modalType) {
case shareModalTypes.IMAGE:
return <img src={URL.createObjectURL(file)} />
case shareModalTypes.VIDEO:
return (
<video
src={URL.createObjectURL(file)}
width="400"
height="300"
controls
autoPlay
muted
/>
)
case shareModalTypes.CHAT:
switch (file.type) {
case 'video/mp4':
case 'video/mpeg':
case 'video/webm':
return (
<video
src={URL.createObjectURL(file)}
width="400"
height="300"
controls
autoPlay
muted
/>
)
case 'image/jpeg':
case 'image/png':
case 'image/jpg':
return <img src={URL.createObjectURL(file)} />
case 'application/pdf':
return (
<object
data={URL.createObjectURL(file)}
type="application/pdf"
width="400"
height="200"
/>
)
default:
break
}
break
case shareModalTypes.FILE:
switch (file.type) {
case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
return (
<iframe
src={`https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(
file
)}`}
width="100%"
height="600px"
/>
)
case 'application/pdf':
return (
<object data={URL.createObjectURL(file)} type="application/pdf" />
)
default:
break
}
}
}
return (
<>
{!files.length ? (
<DragAndDropContainer {...getRootProps({ className: 'dropzone' })}>
<input {...getInputProps()} />
<p>Arrastra el archivo aqui, o haga click para seleccionar</p>
{recomendationText}
</DragAndDropContainer>
) : (
<PreviewContainer>
{files.map((file) => filePreviewTest(file))}
<CloseButton className="close" onClick={() => onDeleteFileHandler()}>
<CloseIcon />
</CloseButton>
</PreviewContainer>
)}
{errors.map((error, index) => (
<FormErrorFeedback key={index}>{error}</FormErrorFeedback>
))}
</>
)
}
export default React.memo(DropzoneComponent, areEqual)