Rev 3639 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useCallback, useEffect, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import { IconButton, styled, Typography } from '@mui/material';
import { Delete } from '@mui/icons-material';
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 FILE_TYPES = {
image: 'image/jpeg, image/png, image/jpg',
file: 'application/pdf, application/vnd.openxmlformats-officedocument.presentationml.presentation',
video: 'video/mp4, video/mpeg, video/webm, video/quicktime'
};
export function FilePicker({
type = 'image',
multiple = false,
maxFiles = 1,
description = 'Arrastra el archivo aqui, o haga click para seleccionar',
defaultFiles = null,
onChange = () => {}
}) {
const [errors, setErrors] = useState([]);
const [files, setFiles] = useState([]);
const onDrop = useCallback((acceptedFiles, fileRejections) => {
onChange(acceptedFiles);
setFiles(
acceptedFiles.map((file) => Object.assign(file, { preview: URL.createObjectURL(file) }))
);
if (fileRejections.length > 0) {
setErrors(fileRejections.map((file) => file.errors[0].message));
} else {
setErrors([]);
}
}, []);
const { getRootProps, getInputProps } = useDropzone({
accept: FILE_TYPES[type] ?? FILE_TYPES.image,
multiple,
maxFiles,
onDrop
});
const removeFile = () => {
setFiles([]);
setErrors([]);
};
const filePreviewTest = (file) => {
switch (type) {
case 'image':
return <img src={file.preview} />;
case 'video':
return <video src={file.preview} width='400' height='300' controls muted />;
case 'file':
switch (file.type) {
case 'application/pdf':
return <object data={file.preview} type='application/pdf' width='400' height='200' />;
default:
break;
}
break;
default:
break;
}
};
useEffect(() => {
if (defaultFiles) setFiles(defaultFiles);
}, [defaultFiles]);
if (files.length) {
return (
<PreviewContainer>
{files.map((file) => filePreviewTest(file))}
<CloseButton onClick={removeFile}>
<Delete />
</CloseButton>
</PreviewContainer>
);
}
return (
<>
<DragAndDropContainer {...getRootProps()}>
<input {...getInputProps()} />
<p>{description}</p>
</DragAndDropContainer>
{errors.map((error, index) => (
<Typography key={index} variant='caption' color='red'>
{error}
</Typography>
))}
</>
);
}