Rev 3640 | 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>))}</>);}