frontPanel/src/ui_kit/QuizPreview/QuizPreview.tsx

132 lines
4.8 KiB
TypeScript
Raw Normal View History

2023-10-09 16:04:12 +00:00
import { PointsIcon } from "@icons/questionsPage/PointsIcon";
2023-10-05 11:41:54 +00:00
import { Box, IconButton } from "@mui/material";
2023-10-03 16:05:20 +00:00
import { toggleQuizPreview, useQuizPreviewStore } from "@root/quizPreview";
2023-10-05 11:41:54 +00:00
import { useLayoutEffect, useRef } from "react";
2023-10-03 16:05:20 +00:00
import { Rnd } from "react-rnd";
2023-10-09 12:33:45 +00:00
import QuizPreviewLayout from "./QuizPreviewLayout";
2023-10-03 16:05:20 +00:00
import ResizeIcon from "./ResizeIcon";
import VisibilityIcon from '@mui/icons-material/Visibility';
const DRAG_PARENT_MARGIN = 25;
const NAVBAR_HEIGHT = 81;
2023-10-05 11:41:54 +00:00
const DRAG_PARENT_BOTTOM_MARGIN = 65;
2023-10-03 16:05:20 +00:00
interface RndPositionAndSize {
x: number;
y: number;
width: string;
height: string;
}
export default function QuizPreview() {
const isPreviewShown = useQuizPreviewStore(state => state.isPreviewShown);
const rndParentRef = useRef<HTMLDivElement>(null);
const rndRef = useRef<Rnd | null>(null);
2023-10-09 12:33:45 +00:00
const rndPositionAndSizeRef = useRef<RndPositionAndSize>({ x: 0, y: 0, width: "340", height: "480" });
2023-10-03 16:05:20 +00:00
const isFirstShowRef = useRef<boolean>(true);
useLayoutEffect(function stickPreviewToBottomRight() {
const rnd = rndRef.current;
const rndSelfElement = rnd?.getSelfElement();
if (!rnd || !rndSelfElement || !rndParentRef.current || !isFirstShowRef.current) return;
const rndParentRect = rndParentRef.current.getBoundingClientRect();
const rndRect = rndSelfElement.getBoundingClientRect();
const x = rndParentRect.width - rndRect.width;
const y = rndParentRect.height - rndRect.height;
rnd.updatePosition({ x, y });
rndPositionAndSizeRef.current.x = x;
rndPositionAndSizeRef.current.y = y;
isFirstShowRef.current = false;
}, [isPreviewShown]);
return (
<Box
ref={rndParentRef}
2023-10-17 13:43:31 +00:00
data-cy="quiz-preview-container"
2023-10-03 16:05:20 +00:00
sx={{
position: "fixed",
top: NAVBAR_HEIGHT + DRAG_PARENT_MARGIN,
left: DRAG_PARENT_MARGIN,
bottom: DRAG_PARENT_BOTTOM_MARGIN,
right: DRAG_PARENT_MARGIN,
// backgroundColor: "rgba(0, 100, 0, 0.2)",
pointerEvents: "none",
2023-10-05 11:41:54 +00:00
zIndex: 100,
2023-10-03 16:05:20 +00:00
}}
>
{isPreviewShown &&
<Rnd
2023-10-09 12:33:45 +00:00
minHeight={300}
minWidth={340}
2023-10-03 16:05:20 +00:00
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;
}}
2023-10-05 11:41:54 +00:00
onDragStart={(e, d) => {
e.preventDefault();
}}
2023-10-03 16:05:20 +00:00
enableResizing={{
topLeft: isPreviewShown,
}}
resizeHandleComponent={{
topLeft: <ResizeIcon />
}}
2023-10-05 11:41:54 +00:00
resizeHandleStyles={{
topLeft: {
top: "-1px",
left: "-1px",
}
}}
2023-10-03 16:05:20 +00:00
style={{
pointerEvents: "auto",
}}
>
2023-10-09 12:33:45 +00:00
<QuizPreviewLayout />
2023-10-05 11:41:54 +00:00
<IconButton
className="quiz-preview-draghandle"
sx={{
position: "absolute",
bottom: -54,
right: 46,
cursor: "move",
}}
>
2023-10-09 16:04:12 +00:00
<PointsIcon style={{ color: "#4D4D4D", fontSize: "30px" }} />
2023-10-05 11:41:54 +00:00
</IconButton>
2023-10-03 16:05:20 +00:00
</Rnd>
}
<IconButton
onClick={toggleQuizPreview}
sx={{
position: "absolute",
2023-10-05 11:41:54 +00:00
right: 0,
bottom: -54,
pointerEvents: "auto",
2023-10-03 16:05:20 +00:00
}}
>
2023-10-05 11:41:54 +00:00
<VisibilityIcon sx={{ height: "30px", width: "30px" }} />
2023-10-03 16:05:20 +00:00
</IconButton>
</Box>
);
}