Proyectos de Subversion LeadersLinked - SPA

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
3476 stevensc 1
import React, { useState, useCallback, useEffect, useRef } from 'react';
2
import { useDropzone } from 'react-dropzone';
3
import { IconButton, styled } from '@mui/material';
3694 stevensc 4
import Close from '@mui/icons-material/Close';
5 stevensc 5
 
3476 stevensc 6
import { useMobile } from '@hooks';
7
import { shareModalTypes } from '@app/redux/share-modal/shareModal.types';
1607 stevensc 8
 
3476 stevensc 9
import FormErrorFeedback from '../UI/form/FormErrorFeedback';
5 stevensc 10
 
1607 stevensc 11
const DragAndDropContainer = styled('div')`
5 stevensc 12
  display: flex;
13
  flex-direction: column;
14
  align-items: center;
15
  padding: 2rem 0;
16
  border: 2px dashed #eee;
17
  border-radius: 2;
18
  background-color: #fafafa;
19
  color: #bdbdbd;
20
  outline: none;
21
  transition: border 0.24s ease-in-out;
2340 stevensc 22
  text-align: center;
5 stevensc 23
  cursor: pointer;
3476 stevensc 24
`;
5 stevensc 25
 
1607 stevensc 26
const PreviewContainer = styled('div')`
5 stevensc 27
  display: flex;
28
  position: relative;
29
  justify-content: center;
30
 
725 stevensc 31
  img,
32
  video,
33
  object {
394 stevensc 34
    width: 80%;
5 stevensc 35
    max-height: 200px;
36
    max-width: 350px;
37
    object-fit: contain;
394 stevensc 38
    display: block;
39
    margin: 0 auto;
5 stevensc 40
  }
3476 stevensc 41
`;
5 stevensc 42
 
43
const CloseButton = styled(IconButton)`
44
  position: absolute;
1607 stevensc 45
  background-color: #000;
5 stevensc 46
  color: #fff;
1607 stevensc 47
  right: 1rem;
1608 stevensc 48
  svg {
49
    font-size: 1rem;
5 stevensc 50
  }
3476 stevensc 51
`;
5 stevensc 52
 
3476 stevensc 53
const DropzoneComponent = ({ type, onUploaded, settedFile, recomendationText }) => {
54
  const [errors, setErrors] = useState([]);
55
  const [files, setFiles] = useState([]);
56
  const mobileFileInputRef = useRef();
57
  const isMobile = useMobile();
5 stevensc 58
 
403 stevensc 59
  const acceptedMimeTypes = (type = '') => {
373 stevensc 60
    switch (type) {
5 stevensc 61
      case shareModalTypes.IMAGE:
3476 stevensc 62
        return 'image/jpeg, image/png, image/jpg';
5 stevensc 63
      case shareModalTypes.FILE:
3476 stevensc 64
        return 'application/pdf, application/vnd.openxmlformats-officedocument.presentationml.presentation';
5 stevensc 65
      case shareModalTypes.VIDEO:
3476 stevensc 66
        return 'video/mp4, video/mpeg, video/webm, video/quicktime';
5 stevensc 67
      case shareModalTypes.CHAT:
3476 stevensc 68
        return 'video/mp4, video/mpeg, video/webm, application/pdf, image/jpeg, image/png, image/jpg';
397 stevensc 69
 
5 stevensc 70
      default:
3476 stevensc 71
        return null;
5 stevensc 72
    }
3476 stevensc 73
  };
5 stevensc 74
 
75
  const onDropRejected = useCallback((rejectedFiles) => {
725 stevensc 76
    rejectedFiles.forEach((fileRejection) => {
5 stevensc 77
      switch (fileRejection.errors[0].code) {
403 stevensc 78
        case 'too-many-files':
3476 stevensc 79
          setErrors([...errors, 'solo puedes agregar 1 archivo']);
80
          break;
403 stevensc 81
        case 'file-invalid-type':
3476 stevensc 82
          setErrors([...errors, 'por favor seleccione un archivo valido']);
83
          break;
5 stevensc 84
        default:
3476 stevensc 85
          setErrors(errors);
86
          break;
5 stevensc 87
      }
3476 stevensc 88
    });
89
  }, []);
5 stevensc 90
 
1634 stevensc 91
  const onDropAccepted = useCallback((acceptedFiles) => {
3476 stevensc 92
    onUploaded(acceptedFiles[0]);
93
    setFiles(acceptedFiles.map((file) => file));
94
  }, []);
1634 stevensc 95
 
361 stevensc 96
  const { getRootProps, getInputProps } = useDropzone({
3278 stevensc 97
    accept: acceptedMimeTypes(type),
5 stevensc 98
    multiple: false,
1634 stevensc 99
    onDrop: onDropAccepted,
5 stevensc 100
    onDropRejected,
101
    onDropAccepted: () => {
3476 stevensc 102
      setErrors([]);
5 stevensc 103
    },
403 stevensc 104
    maxFiles: 1
3476 stevensc 105
  });
5 stevensc 106
 
403 stevensc 107
  const onDeleteFileHandler = () => {
3476 stevensc 108
    setFiles([]);
109
    onUploaded('');
110
  };
5 stevensc 111
 
112
  useEffect(() => {
3476 stevensc 113
    if (!settedFile) return;
114
    setFiles([settedFile]);
115
  }, [settedFile]);
5 stevensc 116
 
117
  const filePreviewTest = (file) => {
3278 stevensc 118
    switch (type) {
5 stevensc 119
      case shareModalTypes.IMAGE:
3476 stevensc 120
        return <img src={URL.createObjectURL(file)} />;
5 stevensc 121
      case shareModalTypes.VIDEO:
3476 stevensc 122
        return <video src={URL.createObjectURL(file)} width='400' height='300' controls muted />;
5 stevensc 123
      case shareModalTypes.CHAT:
124
        switch (file.type) {
403 stevensc 125
          case 'video/mp4':
126
          case 'video/mpeg':
127
          case 'video/webm':
5 stevensc 128
            return (
3476 stevensc 129
              <video src={URL.createObjectURL(file)} width='400' height='300' controls muted />
130
            );
403 stevensc 131
          case 'image/jpeg':
132
          case 'image/png':
133
          case 'image/jpg':
3476 stevensc 134
            return <img src={URL.createObjectURL(file)} />;
403 stevensc 135
          case 'application/pdf':
5 stevensc 136
            return (
137
              <object
138
                data={URL.createObjectURL(file)}
725 stevensc 139
                type='application/pdf'
140
                width='400'
141
                height='200'
5 stevensc 142
              />
3476 stevensc 143
            );
5 stevensc 144
          default:
3476 stevensc 145
            break;
5 stevensc 146
        }
3476 stevensc 147
        break;
5 stevensc 148
      case shareModalTypes.FILE:
149
        switch (file.type) {
403 stevensc 150
          case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
5 stevensc 151
            return (
152
              <iframe
153
                src={`https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(
154
                  file
155
                )}`}
725 stevensc 156
                width='100%'
157
                height='600px'
5 stevensc 158
              />
3476 stevensc 159
            );
403 stevensc 160
          case 'application/pdf':
3476 stevensc 161
            return <object data={URL.createObjectURL(file)} type='application/pdf' />;
5 stevensc 162
          default:
3476 stevensc 163
            break;
5 stevensc 164
        }
165
    }
3476 stevensc 166
  };
5 stevensc 167
 
1634 stevensc 168
  if (files.length) {
169
    return (
170
      <PreviewContainer>
171
        {files.map((file) => filePreviewTest(file))}
172
        <CloseButton onClick={() => onDeleteFileHandler()}>
173
          <Close />
174
        </CloseButton>
175
      </PreviewContainer>
3476 stevensc 176
    );
1634 stevensc 177
  }
178
 
5 stevensc 179
  return (
180
    <>
2342 stevensc 181
      {isMobile ? (
3476 stevensc 182
        <DragAndDropContainer onClick={() => mobileFileInputRef.current.click()}>
2342 stevensc 183
          <input
3278 stevensc 184
            accept={acceptedMimeTypes(type)}
2342 stevensc 185
            ref={mobileFileInputRef}
186
            onChange={(e) => onDropAccepted(e.target.files)}
187
            type='file'
188
            hidden
189
          />
190
          <p>Arrastra el archivo aqui, o haga click para seleccionar</p>
191
          {recomendationText}
192
        </DragAndDropContainer>
193
      ) : (
194
        <DragAndDropContainer {...getRootProps()}>
195
          <input {...getInputProps()} />
196
          <p>Arrastra el archivo aqui, o haga click para seleccionar</p>
197
          {recomendationText}
198
        </DragAndDropContainer>
199
      )}
1634 stevensc 200
 
5 stevensc 201
      {errors.map((error, index) => (
202
        <FormErrorFeedback key={index}>{error}</FormErrorFeedback>
203
      ))}
204
    </>
3476 stevensc 205
  );
206
};
5 stevensc 207
 
1634 stevensc 208
const areEqual = (prevProps, nextProps) => {
3476 stevensc 209
  return prevProps.settedFile === nextProps.settedFile;
210
};
1634 stevensc 211
 
3476 stevensc 212
export default React.memo(DropzoneComponent, areEqual);