diff --git a/interface/src/components/upload/DragNdrop.tsx b/interface/src/components/upload/DragNdrop.tsx index e2cfa2abc..1449f5e6c 100644 --- a/interface/src/components/upload/DragNdrop.tsx +++ b/interface/src/components/upload/DragNdrop.tsx @@ -1,16 +1,59 @@ // Code inspired by Prince Azubuike from https://medium.com/@dprincecoder/creating-a-drag-and-drop-file-upload-component-in-react-a-step-by-step-guide-4d93b6cc21e0 -import { type ChangeEvent, useRef, useState } from 'react'; +import { + type ChangeEvent, + type DragEvent, + type MouseEvent, + useRef, + useState +} from 'react'; import CancelIcon from '@mui/icons-material/Cancel'; import CloudUploadIcon from '@mui/icons-material/CloudUpload'; import UploadIcon from '@mui/icons-material/Upload'; -import { Box, Button } from '@mui/material'; +import { Box, Button, Typography, styled } from '@mui/material'; import { useI18nContext } from 'i18n/i18n-react'; -import './dragNdrop.css'; +const DocumentUploader = styled(Box)<{ active?: boolean }>(({ theme, active }) => ({ + border: `2px dashed ${active ? '#6dc24b' : '#4282fe'}`, + backgroundColor: '#2e3339', + padding: theme.spacing(1.25), + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + position: 'relative', + borderRadius: theme.spacing(1), + cursor: 'pointer', + minHeight: '120px', + transition: 'border-color 0.2s ease-in-out' +})); -const DragNdrop = ({ text, onFileSelected }) => { +const UploadInfo = styled(Box)({ + display: 'flex', + alignItems: 'center' +}); + +const FileInfo = styled(Box)({ + display: 'flex', + flexDirection: 'column', + width: '100%', + justifyContent: 'space-between', + alignItems: 'center' +}); + +const FileName = styled(Typography)(({ theme }) => ({ + fontSize: '14px', + color: '#6dc24b', + margin: theme.spacing(1, 0) +})); + +interface DragNdropProps { + text: string; + onFileSelected: (file: File) => void; +} + +const DragNdrop = ({ text, onFileSelected }: DragNdropProps) => { const [file, setFile] = useState(); const [dragged, setDragged] = useState(false); const inputRef = useRef(null); @@ -28,14 +71,17 @@ const DragNdrop = ({ text, onFileSelected }) => { }; const handleFileChange = (e: ChangeEvent) => { - if (!e.target.files) { + if (!e.target.files || e.target.files.length === 0) { return; } - checkFileExtension(e.target.files[0]); + const selectedFile = e.target.files[0]; + if (selectedFile) { + checkFileExtension(selectedFile); + } e.target.value = ''; // this is to allow the same file to be selected again }; - const handleDrop = (event) => { + const handleDrop = (event: DragEvent) => { event.preventDefault(); const droppedFiles = event.dataTransfer.files; if (droppedFiles.length > 0) { @@ -43,38 +89,40 @@ const DragNdrop = ({ text, onFileSelected }) => { } }; - const handleRemoveFile = (event) => { + const handleRemoveFile = (event: MouseEvent) => { event.stopPropagation(); setFile(undefined); setDragged(false); }; - const handleUploadClick = (event) => { + const handleUploadClick = (event: MouseEvent) => { event.stopPropagation(); - onFileSelected(file); + if (file) { + onFileSelected(file); + } }; const handleBrowseClick = () => { inputRef.current?.click(); }; - const handleDragOver = (event) => { + const handleDragOver = (event: DragEvent) => { event.preventDefault(); // prevent file from being opened setDragged(true); }; return ( -
setDragged(false)} onClick={handleBrowseClick} > -
+ -

{text}

-
+ {text} + { {file && ( <> -
-

{file.name}

-
+ + {file.name} +
+ ); }; diff --git a/interface/src/components/upload/dragNdrop.css b/interface/src/components/upload/dragNdrop.css deleted file mode 100644 index f239b9831..000000000 --- a/interface/src/components/upload/dragNdrop.css +++ /dev/null @@ -1,33 +0,0 @@ -.document-uploader { - border: 2px dashed #4282fe; - background-color: #2e3339; - padding: 10px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - position: relative; - border-radius: 8px; - cursor: pointer; - - &.active { - border-color: #6dc24b; - } - - .upload-info { - display: flex; - align-items: center; - } - - .file-info { - display: flex; - flex-direction: column; - width: 100%; - justify-content: space-between; - align-items: center; - p { - font-size: 14px; - color: #6dc24b; - } - } -}