Rev 5292 | Rev 6020 | 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, useCallback, useEffect } from 'react'
import { useDropzone } from 'react-dropzone'
import { shareModalTypes } from '../../redux/share-modal/shareModal.types'
import FormErrorFeedback from '../form-error-feedback/FormErrorFeedback'
const areEqual = (prevProps, nextProps) => {
return prevProps.settedFile === nextProps.settedFile
}
const DropzoneComponent = (props) => {
const { modalType, onUploaded, settedFile, recomendationText } = props
const [errors, setErrors] = useState([])
const [files, setFiles] = useState([])
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
}
})
}, [])
useEffect(() => {
if (settedFile) setFiles([settedFile])
}, [settedFile])
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 { getRootProps, getInputProps, acceptedFiles, fileRejections } =
useDropzone({
accept: acceptedMimeTypes(),
multiple: false,
onDrop: (acceptedFiles) => {
onUploaded(acceptedFiles[0])
setFiles(acceptedFiles.map((file) => file))
},
onDropRejected,
onDropAccepted: () => {
setErrors([])
},
maxFiles: 1,
})
const thumbStyle = {
display: 'inline-flex',
borderRadius: '2px',
border: '1px solid #eaeaea',
marginBottom: '8px',
marginRight: '8px',
width: '150px',
height: '150px',
padding: '4px',
boxSizing: 'border-box',
position: 'relative',
zIndex: '100',
}
const thumbInnerStyle = {
display: 'flex',
minWidth: 0,
overflow: 'hidden',
marginRight: '1.5rem',
}
const fileInnerStyle = {
display: 'flex',
overflow: 'hidden',
margin: 'auto',
}
const imgStyle = {
display: 'block',
width: 'auto',
height: '100%',
objectFit: 'contain',
}
const onDeleteFileHandler = (index) => {
const newFiles = files.filter((_, id) => id !== index)
onUploaded('')
setFiles(newFiles)
}
const CloseButtonContainer = {
width: '20px',
height: '20px',
position: 'absolute',
top: '5px',
right: '0px',
cursor: 'pointer',
zIndex: '200',
}
const filePreviewTest = (file, id) => {
switch (modalType) {
case shareModalTypes.IMAGE:
return (
<div style={thumbStyle} key={file.name}>
<div style={thumbInnerStyle}>
<img src={URL.createObjectURL(file)} style={imgStyle} />
</div>
<div
style={CloseButtonContainer}
onClick={() => onDeleteFileHandler(id)}
>
<img
src="/css/icons/x-circle-fill.svg"
alt="close-button"
style={{ width: '100%', height: '100%' }}
/>
</div>
</div>
)
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"
frameBorder="0"
/>
)
case 'application/pdf':
return (
<div
style={{
...thumbStyle,
width: '90%',
height: 'auto',
margin: 'auto',
maxWidth: '90%',
}}
key={file.name}
>
<div style={fileInnerStyle}>
<object
data={URL.createObjectURL(file)}
type="application/pdf"
/>
</div>
<div
style={CloseButtonContainer}
onClick={() => onDeleteFileHandler(id)}
>
<img
src="/css/icons/x-circle-fill.svg"
alt="close-button"
style={{ width: '100%', height: '100%' }}
/>
</div>
</div>
)
}
case shareModalTypes.VIDEO:
return (
<div
style={{
...thumbStyle,
width: 'auto',
height: 'auto',
maxWidth: '100%',
}}
key={file.name}
>
<div style={thumbInnerStyle}>
<video
src={URL.createObjectURL(file)}
width="400"
height="300"
controls
autoPlay
muted
></video>
</div>
<div
style={CloseButtonContainer}
onClick={() => onDeleteFileHandler(id)}
>
<img
src="/css/icons/x-circle-fill.svg"
alt="close-button"
style={{ width: '100%', height: '100%' }}
/>
</div>
</div>
)
case shareModalTypes.CHAT:
switch (file.type) {
case 'video/mp4':
case 'video/mpeg':
case 'video/webm':
return (
<div
style={{
...thumbStyle,
width: '90%',
height: 'auto',
margin: 'auto',
}}
key={file.name}
>
<div style={thumbInnerStyle}>
<video
src={URL.createObjectURL(file)}
width="400"
height="300"
controls
autoPlay
muted
></video>
</div>
<div
style={CloseButtonContainer}
onClick={() => onDeleteFileHandler(id)}
>
<img
src="/css/icons/x-circle-fill.svg"
alt="close-button"
style={{ width: '100%', height: '100%' }}
/>
</div>
</div>
)
case 'image/jpeg':
case 'image/png':
case 'image/jpg':
return (
<div style={thumbStyle} key={file.name}>
<div style={thumbInnerStyle}>
<img src={URL.createObjectURL(file)} style={imgStyle} />
</div>
<div
style={CloseButtonContainer}
onClick={() => onDeleteFileHandler(id)}
>
<img
src="/css/icons/x-circle-fill.svg"
alt="close-button"
style={{ width: '100%', height: '100%' }}
/>
</div>
</div>
)
case 'application/pdf':
return (
<div
style={{
...thumbStyle,
width: '90%',
height: 'auto',
margin: 'auto',
}}
key={file.name}
>
<div style={thumbInnerStyle}>
<object
data={URL.createObjectURL(file)}
type="application/pdf"
width="400"
height="200"
></object>
</div>
<div
style={CloseButtonContainer}
onClick={() => onDeleteFileHandler(id)}
>
<img
src="/css/icons/x-circle-fill.svg"
alt="close-button"
style={{ width: '100%', height: '100%' }}
/>
</div>
</div>
)
default:
break
}
break
default:
break
}
}
const thumbsContainerStyle = {
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
marginTop: 16,
position: 'relative',
justifyContent: 'center',
}
const baseStyle = {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: '2rem 0',
borderWidth: 2,
borderRadius: 2,
borderColor: '#eeeeee',
borderStyle: 'dashed',
backgroundColor: '#fafafa',
color: '#bdbdbd',
outline: 'none',
transition: 'border .24s ease-in-out',
marginTop: '1rem',
cursor: 'pointer',
}
return (
<>
{!files.length && (
<div {...getRootProps({ className: 'dropzone', style: baseStyle })}>
<input {...getInputProps()} />
<p>Arrastra el archivo aqui, o haga click para seleccionar</p>
{recomendationText}
</div>
)}
<div style={thumbsContainerStyle}>
{files.map((file, id) => filePreviewTest(file, id))}
</div>
{errors.map((error, index) => (
<FormErrorFeedback key={index}>{error}</FormErrorFeedback>
))}
</>
)
}
export default React.memo(DropzoneComponent, areEqual)