// 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, 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, Typography, styled } from '@mui/material'; import { useI18nContext } from 'i18n/i18n-react'; 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 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); const { LL } = useI18nContext(); const checkFileExtension = (file: File) => { const validExtensions = ['.json', '.bin', '.md5']; const fileName = file.name; const fileExtension = fileName.substring(fileName.lastIndexOf('.')); if (validExtensions.includes(fileExtension)) { setFile(file); } else { alert('Invalid file type'); } }; const handleFileChange = (e: ChangeEvent) => { if (!e.target.files || e.target.files.length === 0) { return; } 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: DragEvent) => { event.preventDefault(); const droppedFiles = event.dataTransfer.files; if (droppedFiles.length > 0) { checkFileExtension(droppedFiles[0] as File); } }; const handleRemoveFile = (event: MouseEvent) => { event.stopPropagation(); setFile(undefined); setDragged(false); }; const handleUploadClick = (event: MouseEvent) => { event.stopPropagation(); if (file) { onFileSelected(file); } }; const handleBrowseClick = () => { inputRef.current?.click(); }; const handleDragOver = (event: DragEvent) => { event.preventDefault(); // prevent file from being opened setDragged(true); }; return ( setDragged(false)} onClick={handleBrowseClick} > {text} {file && ( <> {file.name} )} ); }; export default DragNdrop;