feat: ConfirmLeaveModal

This commit is contained in:
IlyaDoronin 2023-12-26 15:57:44 +03:00
parent 78ddb2e746
commit f44950333b
6 changed files with 433 additions and 232 deletions

@ -1,14 +1,18 @@
import IconPlus from "@icons/IconPlus"; import { useEffect, useRef, useState } from "react";
import Info from "@icons/Info"; // import { useBlocker } from "react-router-dom";
import Plus from "@icons/Plus"; import {
import ArrowLeft from "@icons/questionsPage/arrowLeft"; Box,
import { Box, Button, Typography, Paper, Modal, TextField } from "@mui/material"; Button,
Typography,
Paper,
Modal,
TextField,
} from "@mui/material";
import { incrementCurrentStep } from "@root/quizes/actions"; import { incrementCurrentStep } from "@root/quizes/actions";
import CustomWrapper from "@ui_kit/CustomWrapper"; import CustomWrapper from "@ui_kit/CustomWrapper";
import { DescriptionForm } from "./DescriptionForm/DescriptionForm"; import { DescriptionForm } from "./DescriptionForm/DescriptionForm";
import { ResultListForm } from "./ResultListForm"; import { ResultListForm } from "./ResultListForm";
import { SettingForm } from "./SettingForm"; import { SettingForm } from "./SettingForm";
import { useEffect, useRef, useState } from "react";
import { WhenCard } from "./cards/WhenCard"; import { WhenCard } from "./cards/WhenCard";
import { ResultCard, checkEmptyData } from "./cards/ResultCard"; import { ResultCard, checkEmptyData } from "./cards/ResultCard";
import { EmailSettingsCard } from "./cards/EmailSettingsCard"; import { EmailSettingsCard } from "./cards/EmailSettingsCard";
@ -17,15 +21,27 @@ import { useQuestionsStore } from "@root/questions/store";
import { deleteQuestion } from "@root/questions/actions"; import { deleteQuestion } from "@root/questions/actions";
import { QuizQuestionResult } from "@model/questionTypes/result"; import { QuizQuestionResult } from "@model/questionTypes/result";
import IconPlus from "@icons/IconPlus";
import Info from "@icons/Info";
import Plus from "@icons/Plus";
import ArrowLeft from "@icons/questionsPage/arrowLeft";
export const ResultSettings = () => { export const ResultSettings = () => {
const { questions } = useQuestionsStore(); const { questions } = useQuestionsStore();
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
const results = useQuestionsStore().questions.filter((q): q is QuizQuestionResult => q.type === "result"); const results = useQuestionsStore().questions.filter(
(q): q is QuizQuestionResult => q.type === "result"
);
const [quizExpand, setQuizExpand] = useState(true); const [quizExpand, setQuizExpand] = useState(true);
const [resultContract, setResultContract] = useState(true); const [resultContract, setResultContract] = useState(true);
const [triggerExit, setTriggerExit] = useState<{
follow: boolean;
path: string;
}>({ follow: false, path: "" });
const [openNotificationModal, setOpenNotificationModal] =
useState<boolean>(true);
const isReadyToLeaveRef = useRef(true); const isReadyToLeaveRef = useRef(true);
// const blocker = useBlocker(false);
console.log('quiz ', quiz)
useEffect( useEffect(
function calcIsReadyToLeave() { function calcIsReadyToLeave() {
@ -42,11 +58,29 @@ console.log('quiz ', quiz)
useEffect(() => { useEffect(() => {
return () => { return () => {
if (isReadyToLeaveRef.current === false) alert("Пожалуйста, проверьте, что вы заполнили все результаты"); if (!isReadyToLeaveRef.current && window.location.pathname !== "/edit") {
setOpenNotificationModal(true);
}
}; };
}, []); }, []);
const cnsl = results.filter(q=> q.content.usage) const cnsl = results.filter((q) => q.content.usage);
const shouldBlock = true; // Replace this
// useEffect(() => {
// if (shouldBlock) {
// blocker.proceed?.()
// }
// }, [shouldBlock]);
const leavePage = (leave: boolean) => {
if (leave) {
console.log("ливаем");
}
setOpenNotificationModal(false);
};
return ( return (
<Box sx={{ maxWidth: "796px" }}> <Box sx={{ maxWidth: "796px" }}>
@ -81,9 +115,13 @@ console.log('quiz ', quiz)
</Box> </Box>
<WhenCard quizExpand={quizExpand} /> <WhenCard quizExpand={quizExpand} />
{quiz.config.resultInfo.when === "email" && <EmailSettingsCard quizExpand={quizExpand} />} {quiz.config.resultInfo.when === "email" && (
<EmailSettingsCard quizExpand={quizExpand} />
)}
<Box sx={{ display: "flex", alignItems: "center", mb: "15px", mt: "15px" }}> <Box
sx={{ display: "flex", alignItems: "center", mb: "15px", mt: "15px" }}
>
<Typography variant="p1" sx={{ color: "#4D4D4D", fontSize: "14px" }}> <Typography variant="p1" sx={{ color: "#4D4D4D", fontSize: "14px" }}>
Создайте результат Создайте результат
</Typography> </Typography>
@ -109,7 +147,11 @@ console.log('quiz ', quiz)
</Box> </Box>
{cnsl.map((resultQuestion) => ( {cnsl.map((resultQuestion) => (
<ResultCard resultContract={resultContract} resultData={resultQuestion} key={resultQuestion.id} /> <ResultCard
resultContract={resultContract}
resultData={resultQuestion}
key={resultQuestion.id}
/>
))} ))}
<Modal <Modal
open={false} open={false}

@ -0,0 +1,72 @@
import { Box, Button, Modal, Typography } from "@mui/material";
import { useUiTools } from "@root/uiTools/store";
type ConfirmLeaveModalProps = {
open: boolean;
follow: () => void;
cancel: () => void;
};
export const ConfirmLeaveModal = ({
open,
follow,
cancel,
}: ConfirmLeaveModalProps) => (
<Modal open={open} onClose={cancel}>
<Box
sx={{
outline: "none",
position: "absolute",
overflow: "hidden",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
maxWidth: "620px",
width: "100%",
bgcolor: "background.paper",
borderRadius: "12px",
boxShadow: 24,
p: 0,
}}
>
<Box
sx={{
boxSizing: "border-box",
background: "#F2F3F7",
height: "70px",
padding: "0 25px",
display: "flex",
alignItems: "center",
}}
>
<Typography component="span">
Пожалуйста, проверьте, что вы заполнили все результаты
</Typography>
</Box>
<Box
sx={{
display: "flex",
justifyContent: "end",
gap: "10px",
margin: "20px",
}}
>
<Button
variant="contained"
sx={{ width: "100%", maxWidth: "130px" }}
onClick={cancel}
>
Остаться
</Button>
<Button
variant="contained"
sx={{ width: "100%", maxWidth: "130px" }}
onClick={follow}
>
Покинуть
</Button>
</Box>
</Box>
</Modal>
);

@ -16,7 +16,13 @@ import {
useMediaQuery, useMediaQuery,
useTheme, useTheme,
} from "@mui/material"; } from "@mui/material";
import { decrementCurrentStep, resetEditConfig, setQuizes, updateQuiz } from "@root/quizes/actions"; import {
decrementCurrentStep,
resetEditConfig,
setQuizes,
updateQuiz,
setCurrentStep,
} from "@root/quizes/actions";
import { useCurrentQuiz } from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";
import { useQuizStore } from "@root/quizes/store"; import { useQuizStore } from "@root/quizes/store";
import CustomAvatar from "@ui_kit/Header/Avatar"; import CustomAvatar from "@ui_kit/Header/Avatar";
@ -32,8 +38,17 @@ import { Link, useNavigate } from "react-router-dom";
import useSWR from "swr"; import useSWR from "swr";
import { useDebouncedCallback } from "use-debounce"; import { useDebouncedCallback } from "use-debounce";
import { SidebarMobile } from "./Sidebar/SidebarMobile"; import { SidebarMobile } from "./Sidebar/SidebarMobile";
import { cleanQuestions, createResult, setQuestions } from "@root/questions/actions"; import {
import { updateOpenBranchingPanel, updateCanCreatePublic, updateModalInfoWhyCantCreate } from "@root/uiTools/actions"; cleanQuestions,
createResult,
setQuestions,
} from "@root/questions/actions";
import {
updateOpenBranchingPanel,
updateCanCreatePublic,
updateModalInfoWhyCantCreate,
setShowConfirmLeaveModal,
} from "@root/uiTools/actions";
import { BranchingPanel } from "../Questions/BranchingPanel"; import { BranchingPanel } from "../Questions/BranchingPanel";
import { useQuestionsStore } from "@root/questions/store"; import { useQuestionsStore } from "@root/questions/store";
import { useQuizes } from "@root/quizes/hooks"; import { useQuizes } from "@root/quizes/hooks";
@ -46,41 +61,55 @@ import { clearAuthToken } from "@frontend/kitui";
import { logout } from "@api/auth"; import { logout } from "@api/auth";
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
import { ModalInfoWhyCantCreate } from "./ModalInfoWhyCantCreate"; import { ModalInfoWhyCantCreate } from "./ModalInfoWhyCantCreate";
import { checkQuestionHint } from "@utils/checkQuestionHint"; import { ConfirmLeaveModal } from "./ConfirmLeaveModal";
import { type } from "os"; import { checkQuestionHint } from "@utils/checkQuestionHint";
export default function EditPage() { export default function EditPage() {
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
const { editQuizId } = useQuizStore(); const { editQuizId } = useQuizStore();
const { questions } = useQuestionsStore(); const { questions } = useQuestionsStore();
console.log(quiz) console.log(quiz);
useEffect(() => { useEffect(() => {
const getData = async () => { const getData = async () => {
const quizes = await quizApi.getList(); const quizes = await quizApi.getList();
setQuizes(quizes); setQuizes(quizes);
const questions = await questionApi.getList({ quiz_id: editQuizId }); if (editQuizId) {
setQuestions(questions); const questions = await questionApi.getList({ quiz_id: editQuizId });
setQuestions(questions);
}
//Всегда должен существовать хоть 1 резулт - "line" //Всегда должен существовать хоть 1 резулт - "line"
console.log(questions) console.log(questions);
if (!questions?.find(q=>q.type === "result" && q.content.includes(':"line"') || q.content.includes(":'line'"))) createResult(quiz?.backendId, "line") if (
!questions?.find(
(q) =>
(q.type === "result" && q.content.includes(':"line"')) ||
q.content.includes(":'line'")
)
)
createResult(quiz?.backendId, "line");
}; };
getData(); getData();
}, []); }, []);
const { openBranchingPanel, whyCantCreatePublic, canCreatePublic } = useUiTools(); const {
openBranchingPanel,
whyCantCreatePublic,
canCreatePublic,
showConfirmLeaveModal,
} = useUiTools();
const theme = useTheme(); const theme = useTheme();
const navigate = useNavigate(); const navigate = useNavigate();
const currentStep = useQuizStore((state) => state.currentStep); const currentStep = useQuizStore((state) => state.currentStep);
const isTablet = useMediaQuery(theme.breakpoints.down(1000)); const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(660)); const isMobile = useMediaQuery(theme.breakpoints.down(660));
const [mobileSidebar, setMobileSidebar] = useState<boolean>(false); const [mobileSidebar, setMobileSidebar] = useState<boolean>(false);
const [nextStep, setNextStep] = useState<number>(0);
const quizConfig = quiz?.config; const quizConfig = quiz?.config;
const disableTest = quiz === undefined ? true : (quiz.config.type === null) const disableTest = quiz === undefined ? true : quiz.config.type === null;
useEffect(() => { useEffect(() => {
if (editQuizId === null) navigate("/list"); if (editQuizId === null) navigate("/list");
@ -95,27 +124,26 @@ export default function EditPage() {
[] []
); );
const updateQuestionHint = useDebouncedCallback((questions: AnyTypedQuizQuestion[]) => { const updateQuestionHint = useDebouncedCallback(
(questions: AnyTypedQuizQuestion[]) => {
const problems = checkQuestionHint(questions) const problems = checkQuestionHint(questions);
useUiTools.setState({ whyCantCreatePublic: problems }) useUiTools.setState({ whyCantCreatePublic: problems });
if (Object.keys(problems).length > 0) { if (Object.keys(problems).length > 0) {
updateQuiz(quiz?.id, (state) => { state.status = "stop" }) updateQuiz(quiz?.id, (state) => {
updateCanCreatePublic(false) state.status = "stop";
} else { });
updateCanCreatePublic(true) updateCanCreatePublic(false);
} } else {
updateCanCreatePublic(true);
}
}, 600); },
600
);
useEffect(() => { useEffect(() => {
updateQuestionHint(questions) updateQuestionHint(questions);
}, [questions]); }, [questions]);
async function handleLogoutClick() { async function handleLogoutClick() {
const [, logoutError] = await logout(); const [, logoutError] = await logout();
@ -127,7 +155,11 @@ export default function EditPage() {
clearUserData(); clearUserData();
navigate("/"); navigate("/");
} }
console.log(questions)
const followNewPage = () => {
setShowConfirmLeaveModal(false);
setCurrentStep(nextStep);
};
if (!quizConfig) return <></>; if (!quizConfig) return <></>;
return ( return (
@ -258,7 +290,7 @@ export default function EditPage() {
display: isMobile ? "block" : "flex", display: isMobile ? "block" : "flex",
}} }}
> >
{isMobile ? <SidebarMobile open={mobileSidebar} /> : <Sidebar />} {isMobile ? <SidebarMobile open={mobileSidebar} /> : <Sidebar setNextStep={setNextStep} />}
<Box <Box
sx={{ sx={{
background: theme.palette.background.default, background: theme.palette.background.default,
@ -297,68 +329,79 @@ export default function EditPage() {
background: "#FFF", background: "#FFF",
}} }}
> >
{[1].includes(currentStep) && !openBranchingPanel && quizConfig.type !== "form" && ( {[1].includes(currentStep) &&
<Box !openBranchingPanel &&
sx={{ quizConfig.type !== "form" && (
display: "flex", <Box
alignItems: "center",
gap: "15px",
padding: "18px",
background: "#fff",
borderRadius: "12px",
boxShadow: "0px 10px 30px #e7e7e7",
}}
>
<Switch
checked={openBranchingPanel}
onChange={(e) => updateOpenBranchingPanel(e.target.checked)}
sx={{ sx={{
width: 50, display: "flex",
height: 30, alignItems: "center",
padding: 0, gap: "15px",
"& .MuiSwitch-switchBase": { padding: "18px",
padding: 0, background: "#fff",
margin: "2px", borderRadius: "12px",
transitionDuration: "300ms", boxShadow: "0px 10px 30px #e7e7e7",
"&.Mui-checked": {
transform: "translateX(20px)",
color: theme.palette.brightPurple.main,
"& + .MuiSwitch-track": {
backgroundColor: "#E8DCF9",
opacity: 1,
border: 0,
},
"&.Mui-disabled + .MuiSwitch-track": { opacity: 0.5 },
},
"&.Mui-disabled .MuiSwitch-thumb": {
color: theme.palette.mode === "light" ? theme.palette.grey[100] : theme.palette.grey[600],
},
"&.Mui-disabled + .MuiSwitch-track": {
opacity: theme.palette.mode === "light" ? 0.7 : 0.3,
},
},
"& .MuiSwitch-thumb": {
boxSizing: "border-box",
width: 25,
height: 25,
},
"& .MuiSwitch-track": {
borderRadius: 13,
backgroundColor: theme.palette.mode === "light" ? "#E9E9EA" : "#39393D",
opacity: 1,
transition: theme.transitions.create(["background-color"], {
duration: 500,
}),
},
}} }}
/> >
<Box> <Switch
<Typography sx={{ fontWeight: "bold", color: "#4D4D4D" }}>Логика ветвления</Typography> checked={openBranchingPanel}
onChange={(e) => updateOpenBranchingPanel(e.target.checked)}
sx={{
width: 50,
height: 30,
padding: 0,
"& .MuiSwitch-switchBase": {
padding: 0,
margin: "2px",
transitionDuration: "300ms",
"&.Mui-checked": {
transform: "translateX(20px)",
color: theme.palette.brightPurple.main,
"& + .MuiSwitch-track": {
backgroundColor: "#E8DCF9",
opacity: 1,
border: 0,
},
"&.Mui-disabled + .MuiSwitch-track": { opacity: 0.5 },
},
"&.Mui-disabled .MuiSwitch-thumb": {
color:
theme.palette.mode === "light"
? theme.palette.grey[100]
: theme.palette.grey[600],
},
"&.Mui-disabled + .MuiSwitch-track": {
opacity: theme.palette.mode === "light" ? 0.7 : 0.3,
},
},
"& .MuiSwitch-thumb": {
boxSizing: "border-box",
width: 25,
height: 25,
},
"& .MuiSwitch-track": {
borderRadius: 13,
backgroundColor:
theme.palette.mode === "light" ? "#E9E9EA" : "#39393D",
opacity: 1,
transition: theme.transitions.create(
["background-color"],
{
duration: 500,
}
),
},
}}
/>
<Box>
<Typography sx={{ fontWeight: "bold", color: "#4D4D4D" }}>
Логика ветвления
</Typography>
</Box>
</Box> </Box>
</Box> )}
)}
{!canCreatePublic && quiz.config.type !== "form" ? {!canCreatePublic && quiz.config.type !== "form" ? (
<Button <Button
variant="contained" variant="contained"
// disabled // disabled
@ -368,12 +411,21 @@ export default function EditPage() {
height: "34px", height: "34px",
minWidth: "130px", minWidth: "130px",
}} }}
onClick={() => Object.keys(whyCantCreatePublic).length === 0 ? () => { } : updateModalInfoWhyCantCreate(true)} onClick={() =>
Object.keys(whyCantCreatePublic).length === 0
? () => {}
: updateModalInfoWhyCantCreate(true)
}
> >
Тестовый просмотр Тестовый просмотр
</Button> </Button>
: ) : (
<a href={`/view`} target="_blank" rel="noreferrer" style={{ textDecoration: "none" }}> <a
href={`/view`}
target="_blank"
rel="noreferrer"
style={{ textDecoration: "none" }}
>
<Button <Button
variant="contained" variant="contained"
sx={{ sx={{
@ -386,7 +438,7 @@ export default function EditPage() {
Тестовый просмотр Тестовый просмотр
</Button> </Button>
</a> </a>
} )}
<Button <Button
variant="outlined" variant="outlined"
@ -395,31 +447,48 @@ export default function EditPage() {
lineHeight: "18px", lineHeight: "18px",
height: "34px", height: "34px",
border: `1px solid ${theme.palette.brightPurple.main}`, border: `1px solid ${theme.palette.brightPurple.main}`,
backgroundColor: quiz?.status === "start" ? theme.palette.brightPurple.main : "transparent", backgroundColor:
color: quiz?.status === "start" ? "#FFFFFF" : theme.palette.brightPurple.main, quiz?.status === "start"
? theme.palette.brightPurple.main
: "transparent",
color:
quiz?.status === "start"
? "#FFFFFF"
: theme.palette.brightPurple.main,
}} }}
onClick={ onClick={
Object.keys(whyCantCreatePublic).length === 0 ? Object.keys(whyCantCreatePublic).length === 0
() => updateQuiz(quiz?.id, (state) => { ? () =>
state.status = quiz?.status === "start" ? "stop" : "start"; updateQuiz(quiz?.id, (state) => {
}) state.status =
: quiz?.status === "start" ? "stop" : "start";
() => updateModalInfoWhyCantCreate(true) })
: () => updateModalInfoWhyCantCreate(true)
} }
> >
{quiz?.status === "start" ? "Стоп" : "Старт"} {quiz?.status === "start" ? "Стоп" : "Старт"}
</Button> </Button>
{quiz?.status === "start" && <Box {quiz?.status === "start" && (
component={Link} <Box
sx={{ component={Link}
color: "#7e2aea", sx={{
fontSize: "14px" color: "#7e2aea",
}} fontSize: "14px",
target="_blank" to={"https://hbpn.link/" + quiz.qid}>https://hbpn.link/{quiz.qid} }}
</Box>} target="_blank"
to={"https://hbpn.link/" + quiz.qid}
>
https://hbpn.link/{quiz.qid}
</Box>
)}
</Box> </Box>
</Box > </Box>
<ModalInfoWhyCantCreate /> <ModalInfoWhyCantCreate />
<ConfirmLeaveModal
open={showConfirmLeaveModal}
follow={followNewPage}
cancel={() => setShowConfirmLeaveModal(false)}
/>
</> </>
); );
} }

@ -38,3 +38,4 @@ export const updateCanCreatePublic = (can: boolean) => useUiTools.setState({ can
export const updateModalInfoWhyCantCreate = (can: boolean) => useUiTools.setState({ openModalInfoWhyCantCreate: can }); export const updateModalInfoWhyCantCreate = (can: boolean) => useUiTools.setState({ openModalInfoWhyCantCreate: can });
export const updateDeleteId = (deleteNodeId: string | null = null) => useUiTools.setState({ deleteNodeId }); export const updateDeleteId = (deleteNodeId: string | null = null) => useUiTools.setState({ deleteNodeId });
export const setShowConfirmLeaveModal = (showConfirmLeaveModal: boolean) => useUiTools.setState({ showConfirmLeaveModal });

@ -10,8 +10,10 @@ export type UiTools = {
canCreatePublic: boolean; canCreatePublic: boolean;
whyCantCreatePublic: Record<string, WhyCantCreatePublic>//ид вопроса и список претензий к нему whyCantCreatePublic: Record<string, WhyCantCreatePublic>//ид вопроса и список претензий к нему
openModalInfoWhyCantCreate: boolean; openModalInfoWhyCantCreate: boolean;
deleteNodeId: string | null; deleteNodeId: string | null;
showConfirmLeaveModal: boolean;
}; };
export type WhyCantCreatePublic = { export type WhyCantCreatePublic = {
name: string; name: string;
problems: string[] problems: string[]
@ -27,7 +29,8 @@ const initialState: UiTools = {
canCreatePublic: false, canCreatePublic: false,
whyCantCreatePublic: {}, whyCantCreatePublic: {},
openModalInfoWhyCantCreate: false, openModalInfoWhyCantCreate: false,
deleteNodeId: null, deleteNodeId: null,
showConfirmLeaveModal: false,
}; };
export const useUiTools = create<UiTools>()( export const useUiTools = create<UiTools>()(

@ -4,118 +4,132 @@ import PencilCircleIcon from "@icons/PencilCircleIcon";
import PuzzlePieceIcon from "@icons/PuzzlePieceIcon"; import PuzzlePieceIcon from "@icons/PuzzlePieceIcon";
import TagIcon from "@icons/TagIcon"; import TagIcon from "@icons/TagIcon";
import { quizSetupSteps } from "@model/quizSettings"; import { quizSetupSteps } from "@model/quizSettings";
import { import { Box, IconButton, List, Typography, useTheme } from "@mui/material";
Box,
IconButton,
List,
Typography,
useTheme
} from "@mui/material";
import { setCurrentStep } from "@root/quizes/actions"; import { setCurrentStep } from "@root/quizes/actions";
import { useQuizStore } from "@root/quizes/store"; import { useQuizStore } from "@root/quizes/store";
import { useState } from "react"; import { useState } from "react";
import MenuItem from "./MenuItem"; import MenuItem from "./MenuItem";
import {useCurrentQuiz} from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";
import { setShowConfirmLeaveModal } from "@root/uiTools/actions";
const quizSettingsMenuItems = [ const quizSettingsMenuItems = [
[TagIcon, "Дополнения"], [TagIcon, "Дополнения"],
[PencilCircleIcon, "Дизайн"], [PencilCircleIcon, "Дизайн"],
[PuzzlePieceIcon, "Интеграции"], [PuzzlePieceIcon, "Интеграции"],
[GearIcon, "Настройки"], [GearIcon, "Настройки"],
] as const; ] as const;
export default function Sidebar() { type SidebarProps = {
const theme = useTheme(); setNextStep: (step: number) => void;
const [isMenuCollapsed, setIsMenuCollapsed] = useState(false); };
const currentStep = useQuizStore(state => state.currentStep);
const quiz = useCurrentQuiz();
export default function Sidebar({ setNextStep }: SidebarProps) {
const theme = useTheme();
const [isMenuCollapsed, setIsMenuCollapsed] = useState(false);
const currentStep = useQuizStore((state) => state.currentStep);
const quiz = useCurrentQuiz();
const handleMenuCollapseToggle = () => setIsMenuCollapsed((prev) => !prev); const handleMenuCollapseToggle = () => setIsMenuCollapsed((prev) => !prev);
return ( const changePage = (index: number) => {
<Box if (currentStep === 2) {
setNextStep(index);
setShowConfirmLeaveModal(true);
return;
}
setCurrentStep(index);
};
return (
<Box
sx={{
backgroundColor: theme.palette.lightPurple.main,
minWidth: isMenuCollapsed ? "80px" : "230px",
width: isMenuCollapsed ? "80px" : "230px",
height: "calc(100vh - 80px)",
display: "flex",
flexDirection: "column",
py: "19px",
transitionProperty: "width, min-width",
transitionDuration: "200ms",
overflow: "hidden",
whiteSpace: "nowrap",
boxSizing: "border-box",
zIndex: 1,
}}
>
<Box
sx={{
display: "flex",
pl: isMenuCollapsed ? undefined : "16px",
pr: isMenuCollapsed ? undefined : "8px",
mb: isMenuCollapsed ? "5px" : undefined,
alignItems: "center",
justifyContent: isMenuCollapsed ? "center" : undefined,
}}
>
{!isMenuCollapsed && (
<Typography
sx={{ sx={{
backgroundColor: theme.palette.lightPurple.main, fontSize: "14px",
minWidth: isMenuCollapsed ? "80px" : "230px", lineHeight: "20px",
width: isMenuCollapsed ? "80px" : "230px", fontWeight: 500,
height: "calc(100vh - 80px)", color: theme.palette.grey2.main,
display: "flex",
flexDirection: "column",
py: "19px",
transitionProperty: "width, min-width",
transitionDuration: "200ms",
overflow: "hidden",
whiteSpace: "nowrap",
boxSizing: "border-box",
zIndex: 1
}} }}
>
Создание квиза
</Typography>
)}
<IconButton
onClick={handleMenuCollapseToggle}
sx={{ ml: isMenuCollapsed ? undefined : "auto" }}
> >
<Box <CollapseMenuIcon
sx={{ height="16px"
display: "flex", width="16px"
pl: isMenuCollapsed ? undefined : "16px", color={theme.palette.grey2.main}
pr: isMenuCollapsed ? undefined : "8px", transform={isMenuCollapsed ? "rotate(180deg)" : ""}
mb: isMenuCollapsed ? "5px" : undefined, />
alignItems: "center", </IconButton>
justifyContent: isMenuCollapsed ? "center" : undefined, </Box>
}} <List disablePadding>
> {quizSetupSteps.map((menuItem, index) => {
{!isMenuCollapsed && ( const Icon = menuItem.sidebarIcon;
<Typography
sx={{ return (
fontSize: "14px", <MenuItem
lineHeight: "20px", onClick={() => changePage(index)}
fontWeight: 500, key={index}
color: theme.palette.grey2.main, text={menuItem.sidebarText}
}} isCollapsed={isMenuCollapsed}
> isActive={currentStep === index}
Создание квиза disabled={
</Typography> index === 0
)} ? false
<IconButton : quiz === undefined
onClick={handleMenuCollapseToggle} ? true
sx={{ ml: isMenuCollapsed ? undefined : "auto" }} : quiz?.config.type === null
> }
<CollapseMenuIcon icon={
height="16px" <Icon
width="16px" color={
color={theme.palette.grey2.main} currentStep === index
transform={isMenuCollapsed ? "rotate(180deg)" : ""} ? theme.palette.brightPurple.main
/> : isMenuCollapsed
</IconButton> ? "white"
</Box> : theme.palette.grey2.main
<List disablePadding> }
{quizSetupSteps.map((menuItem, index) => { height={isMenuCollapsed ? "35px" : "24px"}
const Icon = menuItem.sidebarIcon; width={isMenuCollapsed ? "35px" : "24px"}
/>
return ( }
<MenuItem />
onClick={() => setCurrentStep(index)} );
key={index} })}
text={menuItem.sidebarText} </List>
isCollapsed={isMenuCollapsed} {/* {!isMenuCollapsed && (
isActive={currentStep === index}
disabled={index===0 ? false : quiz===undefined ? true : (quiz?.config.type === null)}
icon={
<Icon
color={
currentStep === index
? theme.palette.brightPurple.main
: isMenuCollapsed
? "white"
: theme.palette.grey2.main
}
height={isMenuCollapsed ? "35px" : "24px"}
width={isMenuCollapsed ? "35px" : "24px"}
/>
}
/>
);
})}
</List>
{/* {!isMenuCollapsed && (
<Typography <Typography
sx={{ sx={{
px: "16px", px: "16px",
@ -130,8 +144,8 @@ export default function Sidebar() {
Настройки квиза Настройки квиза
</Typography> </Typography>
)} */} )} */}
<List disablePadding> <List disablePadding>
{/* {quizSettingsMenuItems.map((menuItem, index) => { {/* {quizSettingsMenuItems.map((menuItem, index) => {
const Icon = menuItem[0]; const Icon = menuItem[0];
const totalIndex = index + quizSetupSteps.length; const totalIndex = index + quizSetupSteps.length;
const isActive = currentStep === totalIndex + 1; const isActive = currentStep === totalIndex + 1;
@ -159,7 +173,7 @@ export default function Sidebar() {
/> />
); );
})} */} })} */}
</List> </List>
</Box> </Box>
); );
} }