mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
embed css
This commit is contained in:
@@ -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
|
// 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 CancelIcon from '@mui/icons-material/Cancel';
|
||||||
import CloudUploadIcon from '@mui/icons-material/CloudUpload';
|
import CloudUploadIcon from '@mui/icons-material/CloudUpload';
|
||||||
import UploadIcon from '@mui/icons-material/Upload';
|
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 { 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<File>();
|
const [file, setFile] = useState<File>();
|
||||||
const [dragged, setDragged] = useState(false);
|
const [dragged, setDragged] = useState(false);
|
||||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||||
@@ -28,14 +71,17 @@ const DragNdrop = ({ text, onFileSelected }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
|
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
if (!e.target.files) {
|
if (!e.target.files || e.target.files.length === 0) {
|
||||||
return;
|
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
|
e.target.value = ''; // this is to allow the same file to be selected again
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDrop = (event) => {
|
const handleDrop = (event: DragEvent<HTMLDivElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const droppedFiles = event.dataTransfer.files;
|
const droppedFiles = event.dataTransfer.files;
|
||||||
if (droppedFiles.length > 0) {
|
if (droppedFiles.length > 0) {
|
||||||
@@ -43,38 +89,40 @@ const DragNdrop = ({ text, onFileSelected }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRemoveFile = (event) => {
|
const handleRemoveFile = (event: MouseEvent<HTMLButtonElement>) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
setFile(undefined);
|
setFile(undefined);
|
||||||
setDragged(false);
|
setDragged(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUploadClick = (event) => {
|
const handleUploadClick = (event: MouseEvent<HTMLButtonElement>) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
onFileSelected(file);
|
if (file) {
|
||||||
|
onFileSelected(file);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBrowseClick = () => {
|
const handleBrowseClick = () => {
|
||||||
inputRef.current?.click();
|
inputRef.current?.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDragOver = (event) => {
|
const handleDragOver = (event: DragEvent<HTMLDivElement>) => {
|
||||||
event.preventDefault(); // prevent file from being opened
|
event.preventDefault(); // prevent file from being opened
|
||||||
setDragged(true);
|
setDragged(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<DocumentUploader
|
||||||
className={`document-uploader ${file || dragged ? 'active' : ''}`}
|
active={!!(file || dragged)}
|
||||||
onDrop={handleDrop}
|
onDrop={handleDrop}
|
||||||
onDragOver={handleDragOver}
|
onDragOver={handleDragOver}
|
||||||
onDragLeave={() => setDragged(false)}
|
onDragLeave={() => setDragged(false)}
|
||||||
onClick={handleBrowseClick}
|
onClick={handleBrowseClick}
|
||||||
>
|
>
|
||||||
<div className="upload-info">
|
<UploadInfo>
|
||||||
<CloudUploadIcon sx={{ marginRight: 4 }} color="primary" fontSize="large" />
|
<CloudUploadIcon sx={{ marginRight: 4 }} color="primary" fontSize="large" />
|
||||||
<p>{text}</p>
|
<Typography>{text}</Typography>
|
||||||
</div>
|
</UploadInfo>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
@@ -88,9 +136,9 @@ const DragNdrop = ({ text, onFileSelected }) => {
|
|||||||
|
|
||||||
{file && (
|
{file && (
|
||||||
<>
|
<>
|
||||||
<div className="file-info">
|
<FileInfo>
|
||||||
<p>{file.name}</p>
|
<FileName>{file.name}</FileName>
|
||||||
</div>
|
</FileInfo>
|
||||||
<Box>
|
<Box>
|
||||||
<Button
|
<Button
|
||||||
startIcon={<CancelIcon />}
|
startIcon={<CancelIcon />}
|
||||||
@@ -112,7 +160,7 @@ const DragNdrop = ({ text, onFileSelected }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</DocumentUploader>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user