// drag/drop 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 { Link } from 'react-router'; import { toast } from 'react-toastify'; import CancelIcon from '@mui/icons-material/Cancel'; import CloudUploadIcon from '@mui/icons-material/CloudUpload'; import UploadIcon from '@mui/icons-material/Upload'; import WarningIcon from '@mui/icons-material/Warning'; import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography, styled } from '@mui/material'; import { callAction } from 'api/app'; import { dialogStyle } from '@/CustomTheme'; import { useRequest } from 'alova/client'; 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 [showUpgradeDialog, setShowUpgradeDialog] = useState(false); const [upgradeImportantMessageType, setUpgradeImportantMessageType] = useState(0); const { send: checkUpgradeImportantMessages } = useRequest( (version: string) => callAction({ action: 'upgradeImportantMessages', param: version }), { immediate: false } ) .onSuccess((event) => { const upgradeImportantMessageType_n = ( event.data as { upgradeImportantMessageType: number } ).upgradeImportantMessageType; setUpgradeImportantMessageType(upgradeImportantMessageType_n); if (upgradeImportantMessageType_n === 0) { onFileSelected(file); } }) .onError((error) => { toast.error(String(error.error?.message || 'An error occurred')); }); 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(); void checkUpgradeImportantMessages(file?.name || ''); setShowUpgradeDialog(true); }; 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} {showUpgradeDialog && upgradeImportantMessageType > 0 && ( setShowUpgradeDialog(false)} >    {LL.UPGRADE_IMPORTANT_MESSAGES()} {upgradeImportantMessageType === 2 && LL.UPGRADE_IMPORTANT_MESSAGES_2()} {upgradeImportantMessageType === 1 && ( <> {LL.UPGRADE_IMPORTANT_MESSAGES_1()} {LL.DOWNLOAD_SYSTEM_BACKUP()} )}{' '} {LL.ONLINE_HELP()} )} )} ); }; export default DragNdrop;