3719 |
stevensc |
1 |
import React, { useState } from 'react';
|
|
|
2 |
import { useDropzone } from 'react-dropzone';
|
|
|
3 |
import { Typography } from '@mui/material';
|
|
|
4 |
import Delete from '@mui/icons-material/Delete';
|
|
|
5 |
import { DragAndDropContainer, PreviewContainer, CloseButton } from './FilePicker.styles';
|
|
|
6 |
|
|
|
7 |
const FILE_TYPES = {
|
|
|
8 |
image: 'image/jpeg, image/png, image/jpg',
|
|
|
9 |
file: 'application/pdf, application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
|
10 |
video: 'video/mp4, video/mpeg, video/webm, video/quicktime',
|
|
|
11 |
audio: 'audio/mpeg, audio/mp3, audio/wav, audio/ogg',
|
|
|
12 |
all: 'image/jpeg, image/png, image/jpg, application/pdf, application/vnd.openxmlformats-officedocument.presentationml.presentation, video/mp4, video/mpeg, video/webm, video/quicktime, audio/mpeg, audio/mp3, audio/wav, audio/ogg'
|
|
|
13 |
};
|
|
|
14 |
|
|
|
15 |
export function FilePicker({
|
|
|
16 |
type = 'image',
|
|
|
17 |
multiple = false,
|
|
|
18 |
maxFiles = 1,
|
|
|
19 |
description = 'Arrastra el archivo aqui, o haga click para seleccionar',
|
|
|
20 |
onChange = () => {}
|
|
|
21 |
}) {
|
|
|
22 |
const [files, setFiles] = useState([]);
|
|
|
23 |
const [errors, setErrors] = useState([]);
|
|
|
24 |
|
|
|
25 |
const { getRootProps, getInputProps } = useDropzone({
|
|
|
26 |
accept: FILE_TYPES[type] ?? FILE_TYPES.image,
|
|
|
27 |
multiple,
|
|
|
28 |
maxFiles,
|
|
|
29 |
onDropAccepted: (files) => {
|
|
|
30 |
setFiles(files);
|
|
|
31 |
onChange(multiple ? files : files[0]);
|
|
|
32 |
},
|
|
|
33 |
onDropRejected: (rejections) => {
|
|
|
34 |
if (rejections.length === 0) return;
|
|
|
35 |
const errors = rejections.map((rejection) => rejection.errors[0].message);
|
|
|
36 |
setErrors(errors);
|
|
|
37 |
}
|
|
|
38 |
});
|
|
|
39 |
|
|
|
40 |
const removeFile = () => {
|
|
|
41 |
setFiles([]);
|
|
|
42 |
setErrors([]);
|
|
|
43 |
};
|
|
|
44 |
|
|
|
45 |
const filePreviewTest = (preview) => {
|
|
|
46 |
const src = URL.createObjectURL(preview);
|
|
|
47 |
const fileType = preview.type.split('/')[0];
|
|
|
48 |
|
|
|
49 |
switch (fileType) {
|
|
|
50 |
case 'image':
|
|
|
51 |
return <img src={src} alt={preview.name} />;
|
|
|
52 |
case 'video':
|
|
|
53 |
return <video src={src} width='400' height='300' controls muted />;
|
|
|
54 |
case 'application':
|
|
|
55 |
return <object data={src} type='application/pdf' width='400' height='200' />;
|
|
|
56 |
case 'audio':
|
|
|
57 |
return <audio src={src} controls muted />;
|
|
|
58 |
default:
|
|
|
59 |
return <img src={src} alt={preview.name} />;
|
|
|
60 |
}
|
|
|
61 |
};
|
|
|
62 |
|
|
|
63 |
if (files.length > 0) {
|
|
|
64 |
return (
|
|
|
65 |
<PreviewContainer>
|
|
|
66 |
{files.map((file) => filePreviewTest(file))}
|
|
|
67 |
<CloseButton onClick={removeFile}>
|
|
|
68 |
<Delete />
|
|
|
69 |
</CloseButton>
|
|
|
70 |
</PreviewContainer>
|
|
|
71 |
);
|
|
|
72 |
}
|
|
|
73 |
|
|
|
74 |
return (
|
|
|
75 |
<>
|
|
|
76 |
<DragAndDropContainer {...getRootProps()}>
|
|
|
77 |
<input {...getInputProps()} />
|
|
|
78 |
<p>{description}</p>
|
|
|
79 |
</DragAndDropContainer>
|
|
|
80 |
|
|
|
81 |
{errors.map((error, index) => (
|
|
|
82 |
<Typography key={index} variant='caption' color='red'>
|
|
|
83 |
{error}
|
|
|
84 |
</Typography>
|
|
|
85 |
))}
|
|
|
86 |
</>
|
|
|
87 |
);
|
|
|
88 |
}
|