Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3658 | Rev 3669 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
3476 stevensc 1
import React, { useCallback, useEffect, useState } from 'react';
2
import { useDropzone } from 'react-dropzone';
3
import { IconButton, styled, Typography } from '@mui/material';
4
import { Delete } from '@mui/icons-material';
5
 
6
const DragAndDropContainer = styled('div')`
7
  display: flex;
8
  flex-direction: column;
9
  align-items: center;
10
  padding: 2rem 0;
11
  border: 2px dashed #eee;
12
  border-radius: 2;
13
  background-color: #fafafa;
14
  color: #bdbdbd;
15
  outline: none;
16
  transition: border 0.24s ease-in-out;
17
  text-align: center;
18
  cursor: pointer;
19
`;
20
 
21
const PreviewContainer = styled('div')`
22
  display: flex;
23
  position: relative;
24
  justify-content: center;
25
 
26
  img,
27
  video,
28
  object {
29
    width: 80%;
30
    max-height: 200px;
31
    max-width: 350px;
32
    object-fit: contain;
33
    display: block;
34
    margin: 0 auto;
35
  }
36
`;
37
 
38
const CloseButton = styled(IconButton)`
39
  position: absolute;
40
  background-color: #000;
41
  color: #fff;
42
  right: 1rem;
43
  svg {
44
    font-size: 1rem;
45
  }
46
`;
47
 
48
const FILE_TYPES = {
49
  image: 'image/jpeg, image/png, image/jpg',
50
  file: 'application/pdf, application/vnd.openxmlformats-officedocument.presentationml.presentation',
3639 stevensc 51
  video: 'video/mp4, video/mpeg, video/webm, video/quicktime',
52
  all: 'image/jpeg, image/png, image/jpg, application/pdf, application/vnd.openxmlformats-officedocument.presentationml.presentation, video/mp4, video/mpeg, video/webm, video/quicktime'
3476 stevensc 53
};
54
 
55
export function FilePicker({
56
  type = 'image',
57
  multiple = false,
58
  maxFiles = 1,
59
  description = 'Arrastra el archivo aqui, o haga click para seleccionar',
60
  defaultFiles = null,
61
  onChange = () => {}
62
}) {
63
  const [errors, setErrors] = useState([]);
64
  const [files, setFiles] = useState([]);
65
 
66
  const onDrop = useCallback((acceptedFiles, fileRejections) => {
3666 stevensc 67
    if (multiple) {
68
      onChange(acceptedFiles);
69
    } else {
70
      onChange(acceptedFiles[0]);
71
    }
3642 stevensc 72
    setFiles(acceptedFiles);
3476 stevensc 73
    if (fileRejections.length > 0) {
74
      setErrors(fileRejections.map((file) => file.errors[0].message));
75
    } else {
76
      setErrors([]);
77
    }
78
  }, []);
79
 
80
  const { getRootProps, getInputProps } = useDropzone({
81
    accept: FILE_TYPES[type] ?? FILE_TYPES.image,
82
    multiple,
83
    maxFiles,
84
    onDrop
85
  });
86
 
87
  const removeFile = () => {
88
    setFiles([]);
89
    setErrors([]);
90
  };
91
 
92
  const filePreviewTest = (file) => {
3642 stevensc 93
    const preview = URL.createObjectURL(file);
94
    const type = file.type.split('/')[0];
3641 stevensc 95
 
3642 stevensc 96
    switch (type) {
3476 stevensc 97
      case 'image':
3642 stevensc 98
        return <img src={preview} />;
3476 stevensc 99
      case 'video':
3642 stevensc 100
        return <video src={preview} width='400' height='300' controls muted />;
3658 stevensc 101
      case 'application':
102
        return <object data={preview} type={file.type} width='400' height='200' />;
3476 stevensc 103
      case 'file':
3642 stevensc 104
        return <object data={preview} type={file.type} width='400' height='200' />;
3639 stevensc 105
      case 'audio':
3642 stevensc 106
        return <audio src={preview} controls muted />;
3639 stevensc 107
 
3476 stevensc 108
      default:
109
        break;
110
    }
111
  };
112
 
113
  useEffect(() => {
114
    if (defaultFiles) setFiles(defaultFiles);
115
  }, [defaultFiles]);
116
 
117
  if (files.length) {
118
    return (
119
      <PreviewContainer>
120
        {files.map((file) => filePreviewTest(file))}
121
        <CloseButton onClick={removeFile}>
122
          <Delete />
123
        </CloseButton>
124
      </PreviewContainer>
125
    );
126
  }
127
 
128
  return (
129
    <>
130
      <DragAndDropContainer {...getRootProps()}>
131
        <input {...getInputProps()} />
132
        <p>{description}</p>
133
      </DragAndDropContainer>
134
 
135
      {errors.map((error, index) => (
136
        <Typography key={index} variant='caption' color='red'>
137
          {error}
138
        </Typography>
139
      ))}
140
    </>
141
  );
142
}