frontPanel/src/ui_kit/QuizPreview/QuizPreview.tsx

154 lines
4.6 KiB
TypeScript
Raw Normal View History

2024-04-16 19:31:51 +00:00
import { QuizAnswerer } from "@frontend/squzanswerer";
2023-11-01 13:31:15 +00:00
import ResizeIcon from "@icons/ResizeIcon";
2024-04-16 19:31:51 +00:00
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
import { Box, ThemeProvider } from "@mui/material";
import { useQuestionsStore } from "@root/questions/store";
import { useQuizPreviewStore } from "@root/quizPreview";
2023-12-31 02:53:25 +00:00
import { useCurrentQuiz } from "@root/quizes/hooks";
2024-04-16 19:31:51 +00:00
import { themesPublication } from "@utils/themes/Publication/themePublication";
import { useLayoutEffect, useRef } from "react";
import { Rnd } from "react-rnd";
2023-10-03 16:05:20 +00:00
interface RndPositionAndSize {
2023-10-17 13:24:37 +00:00
x: number;
y: number;
width: string;
height: string;
2023-10-03 16:05:20 +00:00
}
export default function QuizPreview() {
2023-10-17 13:24:37 +00:00
const isPreviewShown = useQuizPreviewStore((state) => state.isPreviewShown);
const rndParentRef = useRef<HTMLDivElement>(null);
2023-12-31 02:53:25 +00:00
const quiz = useCurrentQuiz();
2024-04-16 19:31:51 +00:00
const questions = useQuestionsStore((state) => state.questions).filter(
(q): q is AnyTypedQuizQuestion => q.type !== null,
);
2023-10-17 13:24:37 +00:00
const rndRef = useRef<Rnd | null>(null);
const rndPositionAndSizeRef = useRef<RndPositionAndSize>({
x: 0,
y: 0,
width: "340",
height: "480",
});
const isFirstShowRef = useRef<boolean>(true);
2023-10-03 16:05:20 +00:00
2024-04-16 19:31:51 +00:00
if (!quiz) return null;
2023-10-17 13:24:37 +00:00
useLayoutEffect(
function stickPreviewToBottomRight() {
const rnd = rndRef.current;
const rndSelfElement = rnd?.getSelfElement();
2023-12-31 02:53:25 +00:00
if (
!rnd ||
!rndSelfElement ||
!rndParentRef.current ||
!isFirstShowRef.current
)
return;
2023-10-03 16:05:20 +00:00
2023-10-17 13:24:37 +00:00
const rndParentRect = rndParentRef.current.getBoundingClientRect();
const rndRect = rndSelfElement.getBoundingClientRect();
2023-10-03 16:05:20 +00:00
2023-10-17 13:24:37 +00:00
const x = rndParentRect.width - rndRect.width;
const y = rndParentRect.height - rndRect.height;
2023-10-03 16:05:20 +00:00
2023-10-17 13:24:37 +00:00
rnd.updatePosition({ x, y });
rndPositionAndSizeRef.current.x = x;
rndPositionAndSizeRef.current.y = y;
2023-10-03 16:05:20 +00:00
2023-10-17 13:24:37 +00:00
isFirstShowRef.current = false;
},
2023-12-31 02:53:25 +00:00
[isPreviewShown],
2023-10-17 13:24:37 +00:00
);
2023-10-03 16:05:20 +00:00
2023-10-17 13:24:37 +00:00
return (
2024-02-28 14:09:12 +00:00
<ThemeProvider
theme={themesPublication?.[quiz?.config.theme || "StandardTheme"]}
>
2023-12-31 02:53:25 +00:00
<Box
ref={rndParentRef}
data-cy="quiz-preview-container"
sx={{
position: "fixed",
2024-04-16 19:31:51 +00:00
top: 0,
left: 0,
2024-02-16 23:41:38 +00:00
bottom: 70,
right: 70,
2023-12-31 02:53:25 +00:00
pointerEvents: "none",
zIndex: 100,
}}
>
{isPreviewShown && (
<Rnd
minHeight={20}
minWidth={20}
bounds="parent"
ref={rndRef}
dragHandleClassName="quiz-preview-draghandle"
default={{
x: rndPositionAndSizeRef.current.x,
y: rndPositionAndSizeRef.current.y,
width: rndPositionAndSizeRef.current.width,
height: rndPositionAndSizeRef.current.height,
}}
onResizeStop={(e, direction, ref, delta, position) => {
rndPositionAndSizeRef.current.x = position.x;
rndPositionAndSizeRef.current.y = position.y;
rndPositionAndSizeRef.current.width = ref.style.width;
rndPositionAndSizeRef.current.height = ref.style.height;
}}
onDragStop={(e, d) => {
rndPositionAndSizeRef.current.x = d.x;
rndPositionAndSizeRef.current.y = d.y;
}}
onDragStart={(e, d) => {
2024-01-07 16:17:25 +00:00
e.preventDefault();
2023-12-31 02:53:25 +00:00
}}
enableResizing={{
topLeft: isPreviewShown,
}}
resizeHandleComponent={{
topLeft: <ResizeIcon />,
}}
resizeHandleStyles={{
topLeft: {
top: "-1px",
left: "-1px",
},
}}
style={{
overflow: "hidden",
pointerEvents: "auto",
boxShadow: "0px 5px 10px 2px rgba(34, 60, 80, 0.2)",
2024-04-16 19:31:51 +00:00
backgroundColor: "white",
2023-12-31 02:53:25 +00:00
}}
2024-01-07 16:17:25 +00:00
cancel=".cancel"
>
2024-04-16 19:31:51 +00:00
<QuizAnswerer
className="quiz-preview-draghandle"
quizSettings={{
cnt: questions.length,
questions,
recentlyCompleted: false,
settings: {
fp: quiz.fingerprinting,
delay: 0,
due: quiz.due_to,
lim: quiz.limit,
name: quiz.name,
pausable: quiz.pausable,
rep: quiz.repeatable,
cfg: quiz.config,
},
show_badge: true,
}}
quizId={quiz.qid}
preview
/>
2023-12-31 02:53:25 +00:00
</Rnd>
)}
</Box>
</ThemeProvider>
2023-10-17 13:24:37 +00:00
);
2023-10-03 16:05:20 +00:00
}