From 7c0044678098cfa161e09e4881bc5ad76d8164d4 Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Fri, 29 Dec 2023 16:32:57 +0300 Subject: [PATCH] feat: DesignPage --- src/App.tsx | 2 + src/pages/startPage/DesignPage.tsx | 161 ++++++++++++++++ src/pages/startPage/EditPage.tsx | 153 +-------------- src/pages/startPage/Header.tsx | 175 ++++++++++++++++++ src/pages/startPage/Sidebar/SidebarMobile.tsx | 158 ++++++++-------- .../startPage/Sidebar/SidebarModal/index.tsx | 49 +++++ src/ui_kit/Sidebar.tsx | 13 +- 7 files changed, 487 insertions(+), 224 deletions(-) create mode 100644 src/pages/startPage/DesignPage.tsx create mode 100644 src/pages/startPage/Header.tsx create mode 100644 src/pages/startPage/Sidebar/SidebarModal/index.tsx diff --git a/src/App.tsx b/src/App.tsx index 783f38cb..79a3a345 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,6 +5,7 @@ import "dayjs/locale/ru"; import SigninDialog from "./pages/auth/Signin"; import SignupDialog from "./pages/auth/Signup"; import { ViewPage } from "./pages/ViewPublicationPage"; +import { DesignPage } from "./pages/startPage/DesignPage"; import { Route, Routes, useLocation, useNavigate, Navigate } from "react-router-dom"; import "./index.css"; import ContactFormPage from "./pages/ContactFormPage/ContactFormPage"; @@ -139,6 +140,7 @@ export default function App() { } /> } /> } /> + } /> diff --git a/src/pages/startPage/DesignPage.tsx b/src/pages/startPage/DesignPage.tsx new file mode 100644 index 00000000..beea210f --- /dev/null +++ b/src/pages/startPage/DesignPage.tsx @@ -0,0 +1,161 @@ +import { quizApi } from "@api/quiz"; +import { Box, useMediaQuery, useTheme } from "@mui/material"; +import { + resetEditConfig, + setQuizes, + updateQuiz, + setCurrentStep, +} from "@root/quizes/actions"; +import { useCurrentQuiz } from "@root/quizes/hooks"; +import { useQuizStore } from "@root/quizes/store"; +import Sidebar from "@ui_kit/Sidebar"; +import { enqueueSnackbar } from "notistack"; +import { useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { useDebouncedCallback } from "use-debounce"; +import { SidebarMobile } from "./Sidebar/SidebarMobile"; +import { + cleanQuestions, + createResult, + setQuestions, +} from "@root/questions/actions"; +import { + updateCanCreatePublic, + updateModalInfoWhyCantCreate, + setShowConfirmLeaveModal, + updateSomeWorkBackend, +} from "@root/uiTools/actions"; +import { useQuestionsStore } from "@root/questions/store"; +import { questionApi } from "@api/question"; +import { useUiTools } from "@root/uiTools/store"; + +import { clearUserData } from "@root/user"; +import { clearAuthToken } from "@frontend/kitui"; +import { logout } from "@api/auth"; +import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; +import { ModalInfoWhyCantCreate } from "./ModalInfoWhyCantCreate"; +import { ConfirmLeaveModal } from "./ConfirmLeaveModal"; +import { checkQuestionHint } from "@utils/checkQuestionHint"; +import { Header } from "./Header"; + +export const DesignPage = () => { + const quiz = useCurrentQuiz(); + const { editQuizId } = useQuizStore(); + const { questions } = useQuestionsStore(); + + useEffect(() => { + const getData = async () => { + const quizes = await quizApi.getList(); + setQuizes(quizes); + + if (editQuizId) { + const questions = await questionApi.getList({ quiz_id: editQuizId }); + setQuestions(questions); + //Всегда должен существовать хоть 1 резулт - "line" + // console.log("сейчас будем ворошиться в этих квешенах ", questions); + + if ( + !questions?.find( + (q) => + (q.type === "result" && q.content.includes(':"line"')) || + q.content.includes(":'line'") + ) + ) { + createResult(quiz?.backendId, "line"); + console.log("Я не нашёл линейный резулт и собираюсь создать новый"); + } + } + }; + getData(); + }, []); + + const { showConfirmLeaveModal } = useUiTools(); + const theme = useTheme(); + const navigate = useNavigate(); + const currentStep = useQuizStore((state) => state.currentStep); + const isMobile = useMediaQuery(theme.breakpoints.down(660)); + const [mobileSidebar, setMobileSidebar] = useState(false); + const [nextStep, setNextStep] = useState(0); + const quizConfig = quiz?.config; + const [openBranchingPage, setOpenBranchingPage] = useState(false); + + useEffect( + () => () => { + resetEditConfig(); + cleanQuestions(); + updateModalInfoWhyCantCreate(false); + updateSomeWorkBackend(false); + }, + [] + ); + + const updateQuestionHint = useDebouncedCallback( + (questions: AnyTypedQuizQuestion[]) => { + const problems = checkQuestionHint(questions, quiz); + useUiTools.setState({ whyCantCreatePublic: problems }); + if (Object.keys(problems).length > 0) { + updateQuiz(quiz?.id, (state) => { + state.status = "stop"; + }); + updateCanCreatePublic(false); + } else { + updateCanCreatePublic(true); + } + }, + 600 + ); + + useEffect(() => { + updateQuestionHint(questions); + }, [questions]); + + async function handleLogoutClick() { + const [, logoutError] = await logout(); + + if (logoutError) { + return enqueueSnackbar(logoutError); + } + + clearAuthToken(); + clearUserData(); + navigate("/"); + } + + const followNewPage = () => { + setShowConfirmLeaveModal(false); + setCurrentStep(nextStep); + }; + + if (!quizConfig) return <>; + + const changePage = (index: number) => { + if (currentStep === 2) { + setNextStep(index); + setShowConfirmLeaveModal(true); + + return; + } + + setCurrentStep(index); + }; + + return ( + <> +
+ + {isMobile ? ( + + ) : ( + + )} + Страница дизайна + + + setShowConfirmLeaveModal(false)} + /> + + ); +}; diff --git a/src/pages/startPage/EditPage.tsx b/src/pages/startPage/EditPage.tsx index 5e478f92..86c00650 100755 --- a/src/pages/startPage/EditPage.tsx +++ b/src/pages/startPage/EditPage.tsx @@ -3,7 +3,6 @@ import { LogoutButton } from "@ui_kit/LogoutButton"; import BackArrowIcon from "@icons/BackArrowIcon"; import { Burger } from "@icons/Burger"; import EyeIcon from "@icons/EyeIcon"; -import { PenaLogoIcon } from "@icons/PenaLogoIcon"; import VisibilityIcon from "@mui/icons-material/Visibility"; import { @@ -19,7 +18,6 @@ import { useTheme, } from "@mui/material"; import { - decrementCurrentStep, resetEditConfig, setQuizes, updateQuiz, @@ -29,15 +27,12 @@ import { useCurrentQuiz } from "@root/quizes/hooks"; import { useQuizStore } from "@root/quizes/store"; import CustomAvatar from "@ui_kit/Header/Avatar"; import NavMenuItem from "@ui_kit/Header/NavMenuItem"; -import PenaLogo from "@ui_kit/PenaLogo"; import Sidebar from "@ui_kit/Sidebar"; import Stepper from "@ui_kit/Stepper"; import SwitchStepPages from "@ui_kit/switchStepPages"; -import { isAxiosError } from "axios"; import { enqueueSnackbar } from "notistack"; -import React, { useEffect, useLayoutEffect, useState } from "react"; +import { useEffect, useState } from "react"; import { Link, useNavigate } from "react-router-dom"; -import useSWR from "swr"; import { useDebouncedCallback } from "use-debounce"; import { SidebarMobile } from "./Sidebar/SidebarMobile"; import { @@ -52,9 +47,8 @@ import { setShowConfirmLeaveModal, updateSomeWorkBackend, } from "@root/uiTools/actions"; -import { BranchingPanel } from "../Questions/BranchingPanel"; +import { Header } from "./Header"; import { useQuestionsStore } from "@root/questions/store"; -import { useQuizes } from "@root/quizes/hooks"; import { questionApi } from "@api/question"; import { useUiTools } from "@root/uiTools/store"; @@ -71,14 +65,11 @@ import { toggleQuizPreview } from "@root/quizPreview"; import { LinkSimple } from "@icons/LinkSimple"; import { BackButtonIcon } from "@icons/BackButtonIcon"; -let init: () => void; export default function EditPage() { const quiz = useCurrentQuiz(); const { editQuizId } = useQuizStore(); const { questions } = useQuestionsStore(); - console.log("quiz ", quiz); - console.log(questions); useEffect(() => { const getData = async () => { const quizes = await quizApi.getList(); @@ -165,18 +156,6 @@ export default function EditPage() { updateQuestionHint(questions); }, [questions]); - async function handleLogoutClick() { - const [, logoutError] = await logout(); - - if (logoutError) { - return enqueueSnackbar(logoutError); - } - - clearAuthToken(); - clearUserData(); - navigate("/"); - } - const followNewPage = () => { setShowConfirmLeaveModal(false); setCurrentStep(nextStep); @@ -221,133 +200,7 @@ export default function EditPage() { return ( <> - {/*хедер*/} - - - {isMobile ? : } - - - - - - - - - - updateQuiz(quiz.id, (quiz) => { - quiz.name = e.target.value; - }) - } - fullWidth - id="project-name" - placeholder="Название проекта окно" - sx={{ - width: "270px", - "& .MuiInputBase-root": { - height: "34px", - borderRadius: "8px", - p: 0, - }, - }} - inputProps={{ - sx: { - height: "20px", - borderRadius: "8px", - fontSize: "16px", - lineHeight: "20px", - p: "7px", - color: "black", - "&::placeholder": { - opacity: 1, - }, - }, - }} - /> - - - {isTablet ? ( - - {isMobile ? ( - setMobileSidebar(!mobileSidebar)} - style={{ fontSize: "30px", color: "white", cursor: "pointer" }} - /> - ) : ( - - - - )} - - ) : ( - <> - - - - - - - - - - - - - )} - - +
{ + const quiz = useCurrentQuiz(); + const theme = useTheme(); + const navigate = useNavigate(); + const isTablet = useMediaQuery(theme.breakpoints.down(1000)); + const isMobile = useMediaQuery(theme.breakpoints.down(660)); + const [mobileSidebar, setMobileSidebar] = useState(false); + + async function handleLogoutClick() { + const [, logoutError] = await logout(); + + if (logoutError) { + return enqueueSnackbar(logoutError); + } + + clearAuthToken(); + clearUserData(); + navigate("/"); + } + + return ( + + + {isMobile ? : } + + + + + + + + + + updateQuiz(quiz.id, (quiz) => { + quiz.name = e.target.value; + }) + } + fullWidth + id="project-name" + placeholder="Название проекта окно" + sx={{ + width: "270px", + "& .MuiInputBase-root": { + height: "34px", + borderRadius: "8px", + p: 0, + }, + }} + inputProps={{ + sx: { + height: "20px", + borderRadius: "8px", + fontSize: "16px", + lineHeight: "20px", + p: "7px", + color: "black", + "&::placeholder": { + opacity: 1, + }, + }, + }} + /> + + + {isTablet ? ( + + {isMobile ? ( + setMobileSidebar(!mobileSidebar)} + style={{ fontSize: "30px", color: "white", cursor: "pointer" }} + /> + ) : ( + + + + )} + + ) : ( + <> + + + + + + + + + + + + + )} + + ); +}; diff --git a/src/pages/startPage/Sidebar/SidebarMobile.tsx b/src/pages/startPage/Sidebar/SidebarMobile.tsx index 548799a7..49d20b15 100644 --- a/src/pages/startPage/Sidebar/SidebarMobile.tsx +++ b/src/pages/startPage/Sidebar/SidebarMobile.tsx @@ -1,7 +1,10 @@ -import BackArrowIcon from "@icons/BackArrowIcon"; -import { People } from "@mui/icons-material"; +import { FC, useState } from "react"; import { Box, Typography } from "@mui/material"; -import { FC } from "react"; +import { People } from "@mui/icons-material"; + +import { SidebarModal } from "./SidebarModal"; + +import BackArrowIcon from "@icons/BackArrowIcon"; import { ChartLineUp } from "./icons/ChartLineUp"; import { ReturnTime } from "./icons/ReturnTime"; import { Question } from "./icons/Question"; @@ -26,90 +29,99 @@ const quizSetupSteps = [ { sidebarIcon: }, ] as const; -export const SidebarMobile: FC = ({ open, changePage }) => ( - - - +export const SidebarMobile: FC = ({ open, changePage }) => { + const [openModal, setOpenModal] = useState(false); - - - - Название - - - Название проекта - - - - - + const onClose = () => { + setOpenModal(false); + }; + + return ( - {quizSetupSteps.map(({ sidebarIcon }, index) => ( + + + + + + + Название + + + Название проекта + + + + + + + {quizSetupSteps.map(({ sidebarIcon }, index) => ( + changePage(index)} + sx={{ + cursor: "pointer", + width: "44px", + height: "44px", + background: "#262835", + display: "flex", + justifyContent: "center", + alignItems: "center", + borderRadius: "8px", + }} + > + {sidebarIcon} + + ))} changePage(index)} + onClick={() => setOpenModal(true)} sx={{ - cursor: "pointer", - width: "44px", + px: "10px", + width: "70px", height: "44px", background: "#262835", display: "flex", - justifyContent: "center", + justifyContent: "space-between", alignItems: "center", borderRadius: "8px", + border: "1px solid #FFFFFF66", + marginLeft: "28px", }} > - {sidebarIcon} + + - ))} - - - - + - -); + ); +}; diff --git a/src/pages/startPage/Sidebar/SidebarModal/index.tsx b/src/pages/startPage/Sidebar/SidebarModal/index.tsx new file mode 100644 index 00000000..042ec773 --- /dev/null +++ b/src/pages/startPage/Sidebar/SidebarModal/index.tsx @@ -0,0 +1,49 @@ +import { Box, Button, Modal, Typography } from "@mui/material"; + +type SidebarModalProps = { + open: boolean; + onClose: () => void; +}; +export const SidebarModal = ({ open, onClose }: SidebarModalProps) => { + return ( + + + + меню + + + + + ); +}; diff --git a/src/ui_kit/Sidebar.tsx b/src/ui_kit/Sidebar.tsx index d21b3242..6529546a 100755 --- a/src/ui_kit/Sidebar.tsx +++ b/src/ui_kit/Sidebar.tsx @@ -9,6 +9,7 @@ import { useQuizStore } from "@root/quizes/store"; import { useState } from "react"; import MenuItem from "./MenuItem"; import { useCurrentQuiz } from "@root/quizes/hooks"; +import { useLocation, useNavigate } from "react-router-dom"; const quizSettingsMenuItems = [ [TagIcon, "Дополнения"], @@ -26,6 +27,16 @@ export default function Sidebar({ changePage }: SidebarProps) { const [isMenuCollapsed, setIsMenuCollapsed] = useState(false); const currentStep = useQuizStore((state) => state.currentStep); const quiz = useCurrentQuiz(); + const { pathname } = useLocation(); + const navigate = useNavigate(); + + const changeMenuItem = (index: number) => { + if (!pathname.startsWith("/edit")) { + navigate("/edit"); + } + + changePage(index); + }; const handleMenuCollapseToggle = () => setIsMenuCollapsed((prev) => !prev); @@ -87,7 +98,7 @@ export default function Sidebar({ changePage }: SidebarProps) { return ( changePage(index)} + onClick={() => changeMenuItem(index)} key={index} text={menuItem.sidebarText} isCollapsed={isMenuCollapsed}