frontPanel/src/pages/startPage/dropZone.tsx
2023-12-01 21:05:59 +03:00

126 lines
3.8 KiB
TypeScript

import UploadIcon from "@icons/UploadIcon";
import { Quiz } from "@model/quiz/quiz";
import {
Box,
ButtonBase,
SxProps,
Theme,
Typography,
useTheme,
} from "@mui/material";
import { uploadQuizImage } from "@root/quizes/actions";
import { useCurrentQuiz } from "@root/quizes/hooks";
import { enqueueSnackbar } from "notistack";
import { useState } from "react";
interface Props {
text?: string;
sx?: SxProps<Theme>;
heightImg: string;
widthImg?: string;
onImageUpload: (quiz: Quiz, url: string) => void;
imageUrl: string | null;
}
//Научи функцию принимать данные для валидации
export const DropZone = ({ text, sx, heightImg, widthImg, onImageUpload, imageUrl }: Props) => {
const theme = useTheme();
const quiz = useCurrentQuiz();
const [ready, setReady] = useState(false);
if (!quiz) return null; // TODO throw and catch with error boundary
const imgHC = async (imgInp: HTMLInputElement) => {
if (!quiz) return;
const file = imgInp.files?.[0];
if (!file) return;
if (file.size > 5 * 2 ** 20) return enqueueSnackbar("Размер картинки слишком велик");
uploadQuizImage(quiz.id, file, onImageUpload);
};
const dragenterHC = () => {
setReady(true);
};
const dragexitHC = () => {
setReady(false);
};
const dropHC = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
setReady(false);
const file = event.dataTransfer.files[0];
if (file.size < 5 * 2 ** 20) return enqueueSnackbar("Размер картинки слишком велик");
uploadQuizImage(quiz.id, file, onImageUpload);
};
const dragOverHC = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
};
return (
<ButtonBase component="label" sx={{ justifyContent: "flex-start" }}>
<input
onChange={(event) => imgHC(event.target)}
hidden
accept="image/*"
multiple
type="file"
/>
<Box
onDragEnter={dragenterHC}
onDragExit={dragexitHC}
onDrop={dropHC}
onDragOver={dragOverHC}
sx={{
width: "100%",
height: "120px",
position: "relative",
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: theme.palette.background.default,
border: `1px solid ${ready ? "red" : theme.palette.grey2.main}`,
borderRadius: "8px",
opacity: imageUrl ? "0.5" : 1,
...sx,
}}
>
<UploadIcon />
<Typography
sx={{
position: "absolute",
right: "10px",
bottom: "10px",
color: theme.palette.orange.main,
fontSize: "16px",
lineHeight: "19px",
textDecoration: "underline",
}}
>
{text}
</Typography>
{imageUrl && (
<img
height={heightImg}
width={widthImg}
src={imageUrl}
style={{
position: "absolute",
zIndex: "-1",
objectFit: "revert-layer",
}}
alt="img"
/>
)}
</Box>
</ButtonBase>
);
};