69 lines
2.2 KiB
TypeScript
69 lines
2.2 KiB
TypeScript
import { useEffect, useRef, useState } from "react";
|
|
import QuizDialog from "../shared/QuizDialog";
|
|
import { useQuizCompletionStatus } from "../shared/useQuizCompletionStatus";
|
|
import { useMediaQuery } from "@mui/material";
|
|
import { PopupWidgetComponentProps } from "@/model/widget/popup";
|
|
|
|
|
|
const WIDGET_DEFAULT_WIDTH = "600px";
|
|
const WIDGET_DEFAULT_HEIGHT = "80%";
|
|
|
|
export default function QuizPopup({
|
|
quizId,
|
|
dialogDimensions,
|
|
autoShowQuizTime = null,
|
|
hideOnMobile = false,
|
|
openOnLeaveAttempt = false,
|
|
}: PopupWidgetComponentProps) {
|
|
const initialIsQuizShown = (autoShowQuizTime !== null || openOnLeaveAttempt) ? false : true;
|
|
|
|
const [isQuizShown, setIsQuizShown] = useState<boolean>(initialIsQuizShown);
|
|
const isQuizCompleted = useQuizCompletionStatus(quizId);
|
|
const isMobile = useMediaQuery("(max-width: 600px)");
|
|
const preventOpenOnLeaveAttemptRef = useRef<boolean>(false);
|
|
|
|
useEffect(function setAutoShowQuizTimer() {
|
|
if (autoShowQuizTime === null || openOnLeaveAttempt) return;
|
|
|
|
const timeout = setTimeout(() => {
|
|
setIsQuizShown(true);
|
|
}, autoShowQuizTime * 1000);
|
|
|
|
return () => {
|
|
clearTimeout(timeout);
|
|
};
|
|
}, [autoShowQuizTime, openOnLeaveAttempt]);
|
|
|
|
useEffect(function attachLeaveListener() {
|
|
if (!openOnLeaveAttempt) return;
|
|
|
|
const handleMouseLeave = () => {
|
|
if (!preventOpenOnLeaveAttemptRef.current) {
|
|
preventOpenOnLeaveAttemptRef.current = true;
|
|
setIsQuizShown(true);
|
|
}
|
|
};
|
|
|
|
document.addEventListener("mouseleave", handleMouseLeave);
|
|
|
|
return () => {
|
|
document.removeEventListener("mouseleave", handleMouseLeave);
|
|
};
|
|
}, [openOnLeaveAttempt]);
|
|
|
|
if (isQuizCompleted) return null;
|
|
if (hideOnMobile && isMobile) return null;
|
|
|
|
return (
|
|
<QuizDialog
|
|
open={isQuizShown}
|
|
quizId={quizId}
|
|
onClose={() => setIsQuizShown(false)}
|
|
paperSx={{
|
|
width: dialogDimensions?.width ?? WIDGET_DEFAULT_WIDTH,
|
|
height: dialogDimensions?.height ?? WIDGET_DEFAULT_HEIGHT,
|
|
}}
|
|
/>
|
|
);
|
|
}
|