import { useState, Dispatch, SetStateAction } from "react"; import { Box, ButtonBase, Skeleton, Typography, useTheme } from "@mui/material"; import { enqueueSnackbar } from "notistack"; import { sendAnswer, sendFile } from "@api/quizRelase"; import { useRootContainerSize } from "@contexts/RootContainerWidthContext"; import { useQuizViewStore } from "@stores/quizView"; import { ACCEPT_SEND_FILE_TYPES_MAP, MAX_FILE_SIZE, UPLOAD_FILE_DESCRIPTIONS_MAP, } from "@/components/ViewPublicationPage/tools/fileUpload"; import Info from "@icons/Info"; import UploadIcon from "@icons/UploadIcon"; import type { QuizQuestionFile } from "@model/questionTypes/file"; import { useQuizStore } from "@/stores/useQuizStore"; import { useTranslation } from "react-i18next"; export type ModalWarningType = "errorType" | "errorSize" | "picture" | "video" | "audio" | "document" | null; type UploadFileProps = { currentQuestion: QuizQuestionFile; setModalWarningType: Dispatch>; isSending: boolean; setIsSending: Dispatch>; onFileUpload: (file: File) => Promise; isUploading: boolean; }; export const UploadFile = ({ currentQuestion, setModalWarningType, isSending, setIsSending, onFileUpload, isUploading, }: UploadFileProps) => { const { quizId, preview } = useQuizStore(); const [isDropzoneHighlighted, setIsDropzoneHighlighted] = useState(false); const theme = useTheme(); const { t } = useTranslation(); const answers = useQuizViewStore((state) => state.answers); const { updateAnswer } = useQuizViewStore((state) => state); const isMobile = useRootContainerSize() < 500; const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer as string; const handleFileChange = async (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (!file) return; const fileType = file.type.split("/")[0]; const fileExtension = file.name.split(".").pop()?.toLowerCase(); if (!ACCEPT_SEND_FILE_TYPES_MAP[currentQuestion.content.type].includes(`.${fileExtension}`)) { setModalWarningType("errorType"); return; } if (file.size > 50 * 1024 * 1024) { setModalWarningType("errorSize"); return; } setIsSending(true); try { await onFileUpload(file); } finally { setIsSending(false); } }; const onDrop = async (event: React.DragEvent) => { event.preventDefault(); setIsDropzoneHighlighted(false); const file = event.dataTransfer.files[0]; if (!file) return; const fileType = file.type.split("/")[0]; const fileExtension = file.name.split(".").pop()?.toLowerCase(); if (!ACCEPT_SEND_FILE_TYPES_MAP[currentQuestion.content.type].includes(`.${fileExtension}`)) { setModalWarningType("errorType"); return; } if (file.size > 50 * 1024 * 1024) { setModalWarningType("errorSize"); return; } setIsSending(true); try { await onFileUpload(file); } finally { setIsSending(false); } }; return ( {isSending ? ( ) : ( setIsDropzoneHighlighted(true)} onDragLeave={() => setIsDropzoneHighlighted(false)} onDragOver={(event) => event.preventDefault()} onDrop={onDrop} > {isUploading ? t("Uploading...") : t("Drop file here or click to upload")} )} setModalWarningType(currentQuestion.content.type)} /> ); };