feat: ConfirmLeaveModal
This commit is contained in:
parent
78ddb2e746
commit
f44950333b
@ -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}
|
||||||
|
|||||||
72
src/pages/startPage/ConfirmLeaveModal/index.tsx
Normal file
72
src/pages/startPage/ConfirmLeaveModal/index.tsx
Normal file
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user