fix startpage preview layout types

This commit is contained in:
nflnkr 2023-12-11 19:54:35 +03:00
parent 6482598841
commit e58df2173e
5 changed files with 228 additions and 102 deletions

@ -64,11 +64,11 @@ export default function StartPageSettings() {
const [mobileVersion, setMobileVersion] = useState(false);
if (!quiz) return null; // TODO throw and catch with error boundary
const MobileVersionHC = (bool: boolean) => {
setMobileVersion(bool);
};
const designType = quiz?.config?.startpageType;
const favIconDropZoneElement = (
@ -475,36 +475,37 @@ export default function StartPageSettings() {
>
Расположение элементов
</Typography>
<Box
sx={{
display: "flex",
gap: "10px",
}}
>
<SelectableIconButton
onClick={() => updateQuiz(quiz.id, quiz => {
quiz.config.startpage.position = "left";
})}
isActive={quiz.config.startpage.position === "left"}
Icon={AlignLeftIcon}
/>
<SelectableIconButton
onClick={() => updateQuiz(quiz.id, quiz => {
quiz.config.startpage.position = "center";
})}
isActive={quiz.config.startpage.position === "center"}
Icon={AlignCenterIcon}
sx={{ display: designType === "centered" ? "flex" : "none" }}
/>
<SelectableIconButton
onClick={() => updateQuiz(quiz.id, quiz => {
quiz.config.startpage.position = "right";
})}
isActive={quiz.config.startpage.position === "right"}
Icon={AlignRightIcon}
/>
</Box>
{designType !== "centered" &&
<Box
sx={{
display: "flex",
gap: "10px",
}}
>
<SelectableIconButton
onClick={() => updateQuiz(quiz.id, quiz => {
quiz.config.startpage.position = "left";
})}
isActive={quiz.config.startpage.position === "left"}
Icon={AlignLeftIcon}
/>
<SelectableIconButton
onClick={() => updateQuiz(quiz.id, quiz => {
quiz.config.startpage.position = "center";
})}
isActive={quiz.config.startpage.position === "center"}
Icon={AlignCenterIcon}
sx={{ display: designType === "standard" ? "none" : "flex" }}
/>
<SelectableIconButton
onClick={() => updateQuiz(quiz.id, quiz => {
quiz.config.startpage.position = "right";
})}
isActive={quiz.config.startpage.position === "right"}
Icon={AlignRightIcon}
/>
</Box>
}
{(isTablet || !isSmallMonitor) && (
<>
<Box

@ -1,6 +1,8 @@
import {
Box,
Button,
ButtonBase,
Link,
Paper,
Typography,
useMediaQuery,
@ -8,51 +10,53 @@ import {
} from "@mui/material";
import { useCurrentQuiz } from "@root/quizes/hooks";
import YoutubeEmbedIframe from "./YoutubeEmbedIframe";
import { QuizStartpageAlignType, QuizStartpageType } from "@model/quizSettings";
import { notReachable } from "../../utils/notReachable";
import { useUADevice } from "../../utils/hooks/useUADevice";
export default function QuizPreviewLayout() {
const theme = useTheme();
const quiz = useCurrentQuiz();
const isTablet = useMediaQuery(theme.breakpoints.down(630));
const { isMobileDevice } = useUADevice();
if (!quiz) return null;
const isMediaFileExist =
(quiz.config.startpage.background.type === "image" &&
quiz.config.startpage.background.desktop) ||
(quiz.config.startpage.background.type === "video" &&
quiz.config.startpage.background.video);
const handleCopyNumber = () => {
navigator.clipboard.writeText(quiz.config.info.phonenumber);
};
const background = quiz.config.startpage.background.type === "image"
? quiz.config.startpage.background.desktop
? (
<img
src={quiz.config.startpage.background.desktop}
alt=""
style={{
width: "100%",
height: "100%",
objectFit: "cover",
}}
/>
)
: null
: quiz.config.startpage.background.type === "video"
? quiz.config.startpage.background.video
? (
<YoutubeEmbedIframe videoUrl={quiz.config.startpage.background.video} />
)
: null
: null;
return (
<Paper className="quiz-preview-draghandle" sx={{ height: "100%" }}>
<Box
sx={{
display: "flex",
flexDirection:
quiz.config.startpage.position === "left"
? "row"
: "row-reverse",
flexGrow: 1,
height: "100%",
"&::-webkit-scrollbar": { width: 0 },
}}
>
<Box
sx={{
width: isMediaFileExist && !isTablet ? "40%" : "100%",
padding: "16px",
<QuizPreviewLayoutByType
quizHeaderBlock={<>
<Box sx={{
display: "flex",
flexDirection: "column",
alignItems: isMediaFileExist && !isTablet ? "flex-start" : "center",
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "20px",
}}
>
alignItems: "center",
gap: "20px",
}}>
{quiz.config.startpage.logo && (
<img
src={quiz.config.startpage.logo}
@ -68,15 +72,17 @@ export default function QuizPreviewLayout() {
{quiz.config.info.orgname}
</Typography>
</Box>
<Box
sx={{
flexGrow: 1,
display: "flex",
gap: "10px",
flexDirection: "column",
justifyContent: "center",
}}
>
</>}
quizMainBlock={<>
<Box sx={{
display: "flex",
gap: "10px",
flexDirection: "column",
justifyContent: "center",
alignItems: (quiz.config.startpageType === "expanded" && quiz.config.startpage.position === "center")
? "center"
: "start",
}}>
<Typography sx={{ fontWeight: "bold" }}>{quiz.name}</Typography>
<Typography sx={{ fontSize: "12px" }}>
{quiz.config.startpage.description}
@ -89,42 +95,146 @@ export default function QuizPreviewLayout() {
padding: "10px 15px",
}}
>
{quiz.config.startpage.button ? quiz.config.startpage.button : "Пройти тест"}
{quiz.config.startpage.button.trim() ? quiz.config.startpage.button : "Пройти тест"}
</Button>
</Box>
</Box>
<Box>
<Typography
sx={{ fontSize: "16px", color: theme.palette.brightPurple.main }}
>
{quiz.config.info.phonenumber}
</Typography>
{quiz.config.info.clickable ? (
isMobileDevice ? (
<Link href={`tel:${quiz.config.info.phonenumber}`}>
<Typography sx={{ fontSize: "16px", color: theme.palette.brightPurple.main }}>
{quiz.config.info.phonenumber}
</Typography>
</Link>
) : (
<ButtonBase onClick={handleCopyNumber}>
<Typography sx={{ fontSize: "16px", color: theme.palette.brightPurple.main }}>
{quiz.config.info.phonenumber}
</Typography>
</ButtonBase>
)
) : (
<Typography sx={{ fontSize: "16px", color: theme.palette.brightPurple.main }}>
{quiz.config.info.phonenumber}
</Typography>
)}
<Typography sx={{ fontSize: "12px" }}>
{quiz.config.info.law}
</Typography>
</Box>
</Box>
{!isTablet && isMediaFileExist && (
<Box sx={{ width: "60%" }}>
{quiz.config.startpage.background.type === "image" &&
quiz.config.startpage.background.desktop && (
<img
src={quiz.config.startpage.background.desktop}
alt=""
style={{
width: "100%",
height: "100%",
objectFit: "cover",
}}
/>
)}
{quiz.config.startpage.background.type === "video" &&
quiz.config.startpage.background.video && (
<YoutubeEmbedIframe videoUrl={quiz.config.startpage.background.video} />
)}
</Box>
)}
</Box>
</>}
backgroundBlock={background}
startpageType={quiz.config.startpageType}
alignType={quiz.config.startpage.position}
/>
</Paper>
);
}
function QuizPreviewLayoutByType({ quizHeaderBlock, quizMainBlock, backgroundBlock, startpageType, alignType }: {
quizHeaderBlock: JSX.Element;
quizMainBlock: JSX.Element;
backgroundBlock: JSX.Element | null;
startpageType: QuizStartpageType;
alignType: QuizStartpageAlignType;
}) {
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(630));
switch (startpageType) {
case null:
case "standard": {
return (
<Box sx={{
display: "flex",
flexDirection: alignType === "left" ? "row" : "row-reverse",
flexGrow: 1,
height: "100%",
"&::-webkit-scrollbar": { width: 0 },
}}>
<Box sx={{
width: !isTablet ? "40%" : "100%",
padding: "16px",
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
alignItems: !isTablet ? "flex-start" : "center",
}}>
{quizHeaderBlock}
{quizMainBlock}
</Box>
<Box sx={{
width: "60%",
}}>
{backgroundBlock}
</Box>
</Box>
);
}
case "expanded": {
return (
<Box sx={{
position: "relative",
display: "flex",
justifyContent: startpageAlignTypeToJustifyContent[alignType],
flexGrow: 1,
height: "100%",
"&::-webkit-scrollbar": { width: 0 },
}}>
<Box sx={{
width: "40%",
position: "relative",
padding: "16px",
zIndex: 2,
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
alignItems: alignType === "center" ? "center" : "start",
}}>
{quizHeaderBlock}
{quizMainBlock}
</Box>
<Box sx={{
position: "absolute",
left: 0,
top: 0,
height: "100%",
width: "100%",
zIndex: 1,
}}>
{backgroundBlock}
</Box>
</Box>
);
}
case "centered": {
return (
<Box sx={{
padding: "16px",
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
alignItems: "center",
height: "100%",
"&::-webkit-scrollbar": { width: 0 },
}}>
{quizHeaderBlock}
{backgroundBlock &&
<Box>
{backgroundBlock}
</Box>
}
{quizMainBlock}
</Box>
);
}
default: notReachable(startpageType);
}
}
const startpageAlignTypeToJustifyContent: Record<QuizStartpageAlignType, "start" | "center" | "end"> = {
left: "start",
center: "center",
right: "end",
};

@ -17,6 +17,7 @@ export default function YoutubeEmbedIframe({ videoUrl }: Props) {
<Box sx={{
width: "100%",
height: "100%",
pointerEvents: "none",
"& iframe": {
width: "100%",
height: "100%",

@ -107,6 +107,7 @@ export const StartPagePreview = () => {
topLeft: {
top: "-1px",
left: "-1px",
zIndex: 100,
},
}}
style={{

@ -0,0 +1,13 @@
import { useEffect, useState } from "react";
export function useUADevice(): { isMobileDevice: boolean; } {
const [isMobileDevice, setIsMobileDevice] = useState<boolean>(false);
useEffect(() => {
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
setIsMobileDevice(isMobile);
}, [navigator.userAgent]);
return { isMobileDevice };
}