Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3670 | Rev 3697 | 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 { Box, IconButton, styled, Typography } from '@mui/material';
import Delete from '@mui/icons-material/Delete';

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',
  audio: 'audio/mpeg, audio/mp3, audio/wav, audio/ogg'
};

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 [previews, setPreviews] = useState([]);

  const onDrop = useCallback((acceptedFiles, fileRejections) => {
    const previews = acceptedFiles.map((file) => URL.createObjectURL(file));
    const files = multiple ? acceptedFiles : acceptedFiles[0];
    setPreviews(previews);
    onChange(files);
    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 = () => {
    setPreviews([]);
    setErrors([]);
  };

  const filePreviewTest = (preview) => {
    switch (type) {
      case 'image':
        return <img src={preview} />;
      case 'video':
        return <video src={preview} width='400' height='300' controls muted />;
      case 'file':
        return <object data={preview} type='application/pdf' width='400' height='200' />;
      case 'audio':
        return <audio src={preview} controls muted />;
      default:
        break;
    }
  };

  useEffect(() => {
    if (defaultFiles) setPreviews(defaultFiles);
  }, [defaultFiles]);

  if (previews.length) {
    return (
      <PreviewContainer>
        {previews.map((preview) => filePreviewTest(preview))}
        <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>
      ))}
    </>
  );
}