Rev 3476 | AutorÃa | Ultima modificación | Ver Log |
import React, { useState, useCallback, useEffect, useRef } from 'react';
import { useDropzone } from 'react-dropzone';
import { IconButton, styled } from '@mui/material';
import Close from '@mui/icons-material/Close';
import { useMobile } from '@hooks';
import { shareModalTypes } from '@app/redux/share-modal/shareModal.types';
import FormErrorFeedback from '../UI/form/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;
text-align: center;
cursor: pointer;
`;
const PreviewContainer = styled('div')`
display: flex;
position: relative;
justify-content: center;
img,
video,
object {
width: 80%;
max-height: 200px;
max-width: 350px;
object-fit: contain;
display: block;
margin: 0 auto;
}
`;
const CloseButton = styled(IconButton)`
position: absolute;
background-color: #000;
color: #fff;
right: 1rem;
svg {
font-size: 1rem;
}
`;
const DropzoneComponent = ({ type, onUploaded, settedFile, recomendationText }) => {
const [errors, setErrors] = useState([]);
const [files, setFiles] = useState([]);
const mobileFileInputRef = useRef();
const isMobile = useMobile();
const acceptedMimeTypes = (type = '') => {
switch (type) {
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, video/quicktime';
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.forEach((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 onDropAccepted = useCallback((acceptedFiles) => {
onUploaded(acceptedFiles[0]);
setFiles(acceptedFiles.map((file) => file));
}, []);
const { getRootProps, getInputProps } = useDropzone({
accept: acceptedMimeTypes(type),
multiple: false,
onDrop: onDropAccepted,
onDropRejected,
onDropAccepted: () => {
setErrors([]);
},
maxFiles: 1
});
const onDeleteFileHandler = () => {
setFiles([]);
onUploaded('');
};
useEffect(() => {
if (!settedFile) return;
setFiles([settedFile]);
}, [settedFile]);
const filePreviewTest = (file) => {
switch (type) {
case shareModalTypes.IMAGE:
return <img src={URL.createObjectURL(file)} />;
case shareModalTypes.VIDEO:
return <video src={URL.createObjectURL(file)} width='400' height='300' controls 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 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;
}
}
};
if (files.length) {
return (
<PreviewContainer>
{files.map((file) => filePreviewTest(file))}
<CloseButton onClick={() => onDeleteFileHandler()}>
<Close />
</CloseButton>
</PreviewContainer>
);
}
return (
<>
{isMobile ? (
<DragAndDropContainer onClick={() => mobileFileInputRef.current.click()}>
<input
accept={acceptedMimeTypes(type)}
ref={mobileFileInputRef}
onChange={(e) => onDropAccepted(e.target.files)}
type='file'
hidden
/>
<p>Arrastra el archivo aqui, o haga click para seleccionar</p>
{recomendationText}
</DragAndDropContainer>
) : (
<DragAndDropContainer {...getRootProps()}>
<input {...getInputProps()} />
<p>Arrastra el archivo aqui, o haga click para seleccionar</p>
{recomendationText}
</DragAndDropContainer>
)}
{errors.map((error, index) => (
<FormErrorFeedback key={index}>{error}</FormErrorFeedback>
))}
</>
);
};
const areEqual = (prevProps, nextProps) => {
return prevProps.settedFile === nextProps.settedFile;
};
export default React.memo(DropzoneComponent, areEqual);