вопросы и квизы запрашиваются 1 раз перед работой, стартовая страница публикации отображается по условию настройки

This commit is contained in:
Nastya 2023-12-14 12:40:53 +03:00
parent d1a714903a
commit 0c704d3723
31 changed files with 308 additions and 230 deletions

@ -5,7 +5,7 @@ import "dayjs/locale/ru";
import SigninDialog from "./pages/auth/Signin"; import SigninDialog from "./pages/auth/Signin";
import SignupDialog from "./pages/auth/Signup"; import SignupDialog from "./pages/auth/Signup";
import { ViewPage } from "./pages/ViewPublicationPage"; import { ViewPage } from "./pages/ViewPublicationPage";
import { BrowserRouter, Route, Routes } from "react-router-dom"; import { BrowserRouter, Route, Routes, useLocation, useNavigate, Navigate } from "react-router-dom";
import "./index.css"; import "./index.css";
import ContactFormPage from "./pages/ContactFormPage/ContactFormPage"; import ContactFormPage from "./pages/ContactFormPage/ContactFormPage";
import InstallQuiz from "./pages/InstallQuiz/InstallQuiz"; import InstallQuiz from "./pages/InstallQuiz/InstallQuiz";
@ -34,6 +34,8 @@ const routeslink = [
export default function App() { export default function App() {
const userId = useUserStore((state) => state.userId); const userId = useUserStore((state) => state.userId);
const location = useLocation()
const navigate = useNavigate()
useUserFetcher({ useUserFetcher({
url: `https://hub.pena.digital/user/${userId}`, url: `https://hub.pena.digital/user/${userId}`,
@ -48,23 +50,31 @@ export default function App() {
} }
}, },
}); });
if (location.state?.redirectTo)
return <Navigate to={location.state.redirectTo} replace state={{ backgroundLocation: location }} />
return ( return (
<> <>
<ContactFormModal /> <ContactFormModal />
<BrowserRouter> {location.state?.backgroundLocation && (
<Routes> <Routes>
{routeslink.map((e, i) => (
<Route key={i} path={e.path} element={<Main page={e.page} header={e.header} sidebar={e.sidebar} />} />
))}
<Route path="edit" element={<EditPage />} />
<Route path="crop" element={<ImageCrop />} />
<Route path="/" element={<Landing />} />
<Route path="/signin" element={<SigninDialog />} /> <Route path="/signin" element={<SigninDialog />} />
<Route path="/signup" element={<SignupDialog />} /> <Route path="/signup" element={<SignupDialog />} />
<Route path="/view" element={<ViewPage />} />
</Routes> </Routes>
</BrowserRouter> )}
<Routes location={location.state?.backgroundLocation || location}>
{routeslink.map((e, i) => (
<Route key={i} path={e.path} element={<Main page={e.page} header={e.header} sidebar={e.sidebar} />} />
))}
<Route path="edit" element={<EditPage />} />
<Route path="crop" element={<ImageCrop />} />
<Route path="/" element={<Landing />} />
<Route path="/signin" element={<Navigate to="/" replace state={{ redirectTo: "/signin" }} />} />
<Route path="/signup" element={<Navigate to="/" replace state={{ redirectTo: "/signup" }} />} />/>
<Route path="/view" element={<ViewPage />} />
</Routes>
</> </>
); );
} }

@ -18,6 +18,7 @@ function createQuestion(body: CreateQuestionRequest) {
} }
async function getQuestionList(body?: Partial<GetQuestionListRequest>) { async function getQuestionList(body?: Partial<GetQuestionListRequest>) {
console.log("body" , body)
if (!body?.quiz_id) return null; if (!body?.quiz_id) return null;
const response = await makeRequest<GetQuestionListRequest, GetQuestionListResponse>({ const response = await makeRequest<GetQuestionListRequest, GetQuestionListResponse>({

@ -12,6 +12,8 @@ import { createRoot } from "react-dom/client";
import "./index.css"; import "./index.css";
import lightTheme from "./utils/themes/light"; import lightTheme from "./utils/themes/light";
import { SWRConfig } from "swr"; import { SWRConfig } from "swr";
import {BrowserRouter} from "react-router-dom";
dayjs.locale("ru"); dayjs.locale("ru");
@ -28,13 +30,16 @@ root.render(
<DndProvider backend={HTML5Backend}> <DndProvider backend={HTML5Backend}>
<LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale="ru" localeText={localeText}> <LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale="ru" localeText={localeText}>
<ThemeProvider theme={lightTheme}> <ThemeProvider theme={lightTheme}>
<SnackbarProvider <BrowserRouter>
preventDuplicate={true}
style={{ backgroundColor: lightTheme.palette.brightPurple.main }} <SnackbarProvider
> preventDuplicate={true}
<CssBaseline /> style={{ backgroundColor: lightTheme.palette.brightPurple.main }}
<App /> >
</SnackbarProvider> <CssBaseline />
<App />
</SnackbarProvider>
</BrowserRouter>
</ThemeProvider> </ThemeProvider>
</LocalizationProvider> </LocalizationProvider>
</DndProvider> </DndProvider>

@ -7,7 +7,7 @@ import QuizLogo from "./images/icons/QuizLogo";
import { useMediaQuery, useTheme } from "@mui/material"; import { useMediaQuery, useTheme } from "@mui/material";
import { setIsContactFormOpen } from "../../stores/contactForm"; import { setIsContactFormOpen } from "../../stores/contactForm";
import { useUserStore } from "@root/user"; import { useUserStore } from "@root/user";
import { useNavigate, Link, } from "react-router-dom"; import { useNavigate, Link, useLocation } from "react-router-dom";
const buttonMenu = ["Меню 1", "Меню 2", "Меню 3", "Меню 4", "Меню 5", "Меню 1", "Меню 2"]; const buttonMenu = ["Меню 1", "Меню 2", "Меню 3", "Меню 4", "Меню 5", "Меню 1", "Меню 2"];
@ -18,6 +18,7 @@ export default function Component() {
const [select, setSelect] = React.useState(0); const [select, setSelect] = React.useState(0);
const userId = useUserStore((state) => state.userId); const userId = useUserStore((state) => state.userId);
const navigate = useNavigate(); const navigate = useNavigate();
const location = useLocation()
const onClick = () => (userId ? navigate("/list") : navigate("/signin")); const onClick = () => (userId ? navigate("/list") : navigate("/signin"));

@ -9,7 +9,7 @@ import Blog from './Blog';
import HowItWorks from './HowItWorks'; import HowItWorks from './HowItWorks';
import BusinessPluses from './BusinessPluses'; import BusinessPluses from './BusinessPluses';
import HowToUse from './HowToUse'; import HowToUse from './HowToUse';
import WhatTheySay from './WhatTheySay';
import StartWithTemplates from './StartWithTemplates'; import StartWithTemplates from './StartWithTemplates';
import WhatTheFeatures from './WhatTheFeatures'; import WhatTheFeatures from './WhatTheFeatures';
import FullScreenDialog from "./headerMobileLanding"; import FullScreenDialog from "./headerMobileLanding";
@ -18,6 +18,7 @@ import Collaboration from "./Collaboration";
export default function Landing() { export default function Landing() {
const theme = useTheme(); const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(1000)); const isTablet = useMediaQuery(theme.breakpoints.down(1000));
return ( return (
<> <>
<CssBaseline /> <CssBaseline />

@ -7,7 +7,8 @@ import { useCurrentQuiz } from "@root/quizes/hooks";
import { updateRootContentId } from "@root/quizes/actions" import { updateRootContentId } from "@root/quizes/actions"
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared" import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"
import { useQuestionsStore } from "@root/questions/store"; import { useQuestionsStore } from "@root/questions/store";
import { deleteQuestion, cleardragQuestionContentId, updateQuestion, updateOpenedModalSettingsId, getQuestionByContentId, clearRuleForAll } from "@root/questions/actions"; import { deleteQuestion, updateQuestion, updateOpenedModalSettingsId, getQuestionByContentId, clearRuleForAll } from "@root/questions/actions";
import { cleardragQuestionContentId } from "@root/uiTools/actions";
import { withErrorBoundary } from "react-error-boundary"; import { withErrorBoundary } from "react-error-boundary";
import { storeToNodes } from "./helper"; import { storeToNodes } from "./helper";
@ -22,6 +23,7 @@ import type {
ElementDefinition, ElementDefinition,
} from "cytoscape"; } from "cytoscape";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
import { useUiTools } from "@root/uiTools/store";
type PopperItem = { type PopperItem = {
id: () => string; id: () => string;
@ -121,7 +123,7 @@ function CsComponent({
}: Props) { }: Props) {
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
const { dragQuestionContentId, desireToOpenABranchingModal } = useQuestionsStore() const { dragQuestionContentId, desireToOpenABranchingModal } = useUiTools()
const trashQuestions = useQuestionsStore().questions const trashQuestions = useQuestionsStore().questions
const questions = trashQuestions.filter((question) => question.type !== "result" && question.type !== null) const questions = trashQuestions.filter((question) => question.type !== "result" && question.type !== null)
const [startCreate, setStartCreate] = useState(""); const [startCreate, setStartCreate] = useState("");
@ -145,9 +147,8 @@ function CsComponent({
}, [desireToOpenABranchingModal]) }, [desireToOpenABranchingModal])
useLayoutEffect(() => { useLayoutEffect(() => {
updateOpenedModalSettingsId() updateOpenedModalSettingsId()
console.log("first render CSComponent") // updateRootContentId(quiz.id, "")
// updateRootContentId(quiz.id, "") // clearRuleForAll()
// clearRuleForAll()
}, []) }, [])
useEffect(() => { useEffect(() => {
if (modalQuestionTargetContentId.length !== 0 && modalQuestionParentContentId.length !== 0) { if (modalQuestionTargetContentId.length !== 0 && modalQuestionParentContentId.length !== 0) {
@ -312,7 +313,6 @@ function CsComponent({
const clearDataAfterRemoveNode = ({ targetQuestionContentId, parentQuestionContentId }: { targetQuestionContentId: string, parentQuestionContentId: string }) => { const clearDataAfterRemoveNode = ({ targetQuestionContentId, parentQuestionContentId }: { targetQuestionContentId: string, parentQuestionContentId: string }) => {
console.log("target ", targetQuestionContentId, "parent ", parentQuestionContentId)
updateQuestion(targetQuestionContentId, question => { updateQuestion(targetQuestionContentId, question => {
@ -325,7 +325,6 @@ function CsComponent({
//чистим rule родителя //чистим rule родителя
const parentQuestion = getQuestionByContentId(parentQuestionContentId) const parentQuestion = getQuestionByContentId(parentQuestionContentId)
console.log(parentQuestion.content.rule.parentId)
const newRule = {} const newRule = {}
const newChildren = [...parentQuestion.content.rule.children] const newChildren = [...parentQuestion.content.rule.children]
newChildren.splice(parentQuestion.content.rule.children.indexOf(targetQuestionContentId), 1); newChildren.splice(parentQuestion.content.rule.children.indexOf(targetQuestionContentId), 1);
@ -639,7 +638,6 @@ function CsComponent({
}, },
}); });
let gearsPopper = null let gearsPopper = null
console.log('POPE', node.data())
if (node.data().root !== true) { if (node.data().root !== true) {
gearsPopper = node.popper({ gearsPopper = node.popper({
popper: { popper: {
@ -647,7 +645,6 @@ console.log('POPE', node.data())
modifiers: [{ name: "flip", options: { boundary: node } }], modifiers: [{ name: "flip", options: { boundary: node } }],
}, },
content: ([item]) => { content: ([item]) => {
console.log('PEPO', item.id())
const itemId = item.id(); const itemId = item.id();
const itemElement = gearsContainer.current?.querySelector( const itemElement = gearsContainer.current?.querySelector(
@ -678,7 +675,6 @@ console.log('POPE', node.data())
}; };
const onZoom = (event: AbstractEventObject) => { const onZoom = (event: AbstractEventObject) => {
console.log('ZOOOOM')
const zoom = event.cy.zoom(); const zoom = event.cy.zoom();
//update(); //update();

@ -5,6 +5,7 @@ import { updateRootContentId } from "@root/quizes/actions"
import { useCurrentQuiz } from "@root/quizes/hooks" import { useCurrentQuiz } from "@root/quizes/hooks"
import { useQuestionsStore } from "@root/questions/store" import { useQuestionsStore } from "@root/questions/store"
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
import { useUiTools } from "@root/uiTools/store";
interface Props { interface Props {
setOpenedModalQuestions: (open: boolean) => void; setOpenedModalQuestions: (open: boolean) => void;
@ -17,12 +18,13 @@ export const FirstNodeField = ({ setOpenedModalQuestions, modalQuestionTargetCon
useLayoutEffect(() => { useLayoutEffect(() => {
updateOpenedModalSettingsId() updateOpenedModalSettingsId()
console.log("first render firstComponent") console.log("first render firstComponent")
updateRootContentId(quiz.id, "") // updateRootContentId(quiz.id, "")
clearRuleForAll() // clearRuleForAll()
}, []) }, [])
const { dragQuestionContentId, questions } = useQuestionsStore() const { questions } = useQuestionsStore()
const { dragQuestionContentId } = useUiTools()
const Container = useRef<HTMLDivElement | null>(null); const Container = useRef<HTMLDivElement | null>(null);
const modalOpen = () => setOpenedModalQuestions(true) const modalOpen = () => setOpenedModalQuestions(true)

@ -1,15 +1,15 @@
import { Box } from "@mui/material"; import { Box } from "@mui/material";
import { FirstNodeField } from "./FirstNodeField"; import { FirstNodeField } from "./FirstNodeField";
import CsComponent from "./CsComponent"; import CsComponent from "./CsComponent";
import { useQuestionsStore } from "@root/questions/store"
import { useCurrentQuiz } from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";
import { useState } from "react"; import { useState } from "react";
import {BranchingQuestionsModal} from "../BranchingQuestionsModal" import {BranchingQuestionsModal} from "../BranchingQuestionsModal"
import { useUiTools } from "@root/uiTools/store";
export const BranchingMap = () => { export const BranchingMap = () => {
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
const { dragQuestionContentId } = useQuestionsStore() const { dragQuestionContentId } = useUiTools()
const [modalQuestionParentContentId, setModalQuestionParentContentId] = useState<string>("") const [modalQuestionParentContentId, setModalQuestionParentContentId] = useState<string>("")
const [modalQuestionTargetContentId, setModalQuestionTargetContentId] = useState<string>("") const [modalQuestionTargetContentId, setModalQuestionTargetContentId] = useState<string>("")
const [openedModalQuestions, setOpenedModalQuestions] = useState<boolean>(false) const [openedModalQuestions, setOpenedModalQuestions] = useState<boolean>(false)

@ -1,15 +1,16 @@
import {Box, Typography, Switch, useTheme, Button, useMediaQuery, SxProps, Theme} from "@mui/material"; import {Box, Typography, Switch, useTheme, Button, useMediaQuery, SxProps, Theme} from "@mui/material";
import { QuestionsList } from "./QuestionsList"; import { QuestionsList } from "./QuestionsList";
import { updateOpenBranchingPanel } from "@root/questions/actions"; import { updateOpenBranchingPanel } from "@root/uiTools/actions";
import {useQuestionsStore} from "@root/questions/store"; import {useQuestionsStore} from "@root/questions/store";
import {useRef} from "react"; import {useRef} from "react";
import { useUiTools } from "@root/uiTools/store";
export const BranchingPanel = (sx?: SxProps<Theme>) => { export const BranchingPanel = (sx?: SxProps<Theme>) => {
const theme = useTheme(); const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(660)); const isMobile = useMediaQuery(theme.breakpoints.down(660));
const {openBranchingPanel} = useQuestionsStore.getState() const {openBranchingPanel} = useUiTools()
const ref = useRef() const ref = useRef()
return ( return (
<Box sx={{ userSelect: "none", maxWidth: "350px", width: "100%" }}> <Box sx={{ userSelect: "none", maxWidth: "350px", width: "100%" }}>
@ -26,10 +27,10 @@ export const BranchingPanel = (sx?: SxProps<Theme>) => {
}} }}
> >
<Switch <Switch
clicked={openBranchingPanel} checked={openBranchingPanel}
onChange={(_, value) => { onChange={
updateOpenBranchingPanel(value) (e) => updateOpenBranchingPanel(e.target.checked)
}} }
sx={{ sx={{
width: 50, width: 50,
height: 30, height: 30,
@ -76,7 +77,7 @@ export const BranchingPanel = (sx?: SxProps<Theme>) => {
/> />
<Box> <Box>
<Typography ref={ref} sx={{ fontWeight: "bold", color: "#4D4D4D" }}> <Typography ref={ref} sx={{ fontWeight: "bold", color: "#4D4D4D" }}>
Логика ветвления Логика ветвления
</Typography> </Typography>
<Typography sx={{ color: "#4D4D4D", fontSize: "12px" }}> <Typography sx={{ color: "#4D4D4D", fontSize: "12px" }}>
Настройте связи между вопросами Настройте связи между вопросами

@ -11,7 +11,8 @@ import {
useMediaQuery, useMediaQuery,
useTheme, useTheme,
} from "@mui/material"; } from "@mui/material";
import { copyQuestion, deleteQuestion, updateOpenBranchingPanel, updateDesireToOpenABranchingModal, deleteQuestionWithTimeout, clearRuleForAll, updateQuestion, getQuestionByContentId } from "@root/questions/actions"; import { copyQuestion, deleteQuestion, deleteQuestionWithTimeout, clearRuleForAll, updateQuestion, getQuestionByContentId } from "@root/questions/actions";
import { updateOpenBranchingPanel, updateDesireToOpenABranchingModal, } from "@root/uiTools/actions";
import MiniButtonSetting from "@ui_kit/MiniButtonSetting"; import MiniButtonSetting from "@ui_kit/MiniButtonSetting";
import { CopyIcon } from "../../assets/icons/questionsPage/CopyIcon"; import { CopyIcon } from "../../assets/icons/questionsPage/CopyIcon";
import Branching from "../../assets/icons/questionsPage/branching"; import Branching from "../../assets/icons/questionsPage/branching";
@ -24,6 +25,7 @@ import { enqueueSnackbar } from "notistack";
import { useQuestionsStore } from "@root/questions/store"; import { useQuestionsStore } from "@root/questions/store";
import { updateOpenedModalSettingsId } from "@root/questions/actions"; import { updateOpenedModalSettingsId } from "@root/questions/actions";
import { updateRootContentId } from "@root/quizes/actions"; import { updateRootContentId } from "@root/quizes/actions";
import { useUiTools } from "@root/uiTools/store";
interface Props { interface Props {
switchState: string; switchState: string;
@ -41,7 +43,8 @@ export default function ButtonsOptions({
const isMobile = useMediaQuery(theme.breakpoints.down(790)); const isMobile = useMediaQuery(theme.breakpoints.down(790));
const isWrappMiniButtonSetting = useMediaQuery(theme.breakpoints.down(920)); const isWrappMiniButtonSetting = useMediaQuery(theme.breakpoints.down(920));
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
const { openBranchingPanel, questions } = useQuestionsStore.getState(); const { questions } = useQuestionsStore.getState();
const { openBranchingPanel } = useUiTools();
const openedModal = () => { const openedModal = () => {
updateOpenedModalSettingsId(question.id); updateOpenedModalSettingsId(question.id);

@ -23,7 +23,7 @@ import ImgIcon from "../../assets/icons/questionsPage/imgIcon";
import SettingIcon from "../../assets/icons/questionsPage/settingIcon"; import SettingIcon from "../../assets/icons/questionsPage/settingIcon";
import { QuizQuestionVariant } from "@model/questionTypes/variant"; import { QuizQuestionVariant } from "@model/questionTypes/variant";
import { updateOpenedModalSettingsId } from "@root/questions/actions"; import { updateOpenedModalSettingsId } from "@root/questions/actions";
import { updateOpenBranchingPanel, updateDesireToOpenABranchingModal } from "@root/questions/actions"; import { updateOpenBranchingPanel, updateDesireToOpenABranchingModal } from "@root/uiTools/actions";
import { useQuestionsStore } from "@root/questions/store"; import { useQuestionsStore } from "@root/questions/store";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
import { useCurrentQuiz } from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";

@ -3,8 +3,10 @@ import { Box, ListItem, Typography, useTheme } from "@mui/material";
import { memo, useEffect } from "react"; import { memo, useEffect } from "react";
import { Draggable } from "react-beautiful-dnd"; import { Draggable } from "react-beautiful-dnd";
import QuestionsPageCard from "./QuestionPageCard"; import QuestionsPageCard from "./QuestionPageCard";
import { cancelQuestionDeletion, updateEditSomeQuestion } from "@root/questions/actions"; import { cancelQuestionDeletion } from "@root/questions/actions";
import { updateEditSomeQuestion } from "@root/uiTools/actions";
import { useQuestionsStore } from "@root/questions/store"; import { useQuestionsStore } from "@root/questions/store";
import { useUiTools } from "@root/uiTools/store";
type Props = { type Props = {
@ -15,7 +17,7 @@ type Props = {
function DraggableListItem({ question, isDragging, index }: Props) { function DraggableListItem({ question, isDragging, index }: Props) {
const theme = useTheme(); const theme = useTheme();
const { editSomeQuestion } = useQuestionsStore(); const { editSomeQuestion } = useUiTools();
useEffect(() => { useEffect(() => {
if (editSomeQuestion !== null) { if (editSomeQuestion !== null) {

@ -6,13 +6,16 @@ import { DraggableList } from "./DraggableList";
import { SwitchBranchingPanel } from "./SwitchBranchingPanel"; import { SwitchBranchingPanel } from "./SwitchBranchingPanel";
import { BranchingMap } from "./BranchingMap"; import { BranchingMap } from "./BranchingMap";
import {useQuestionsStore} from "@root/questions/store"; import {useQuestionsStore} from "@root/questions/store";
import { useUiTools } from "@root/uiTools/store";
export const QuestionSwitchWindowTool = () => { export const QuestionSwitchWindowTool = () => {
const {openBranchingPanel, questions} = useQuestionsStore.getState() const {questions} = useQuestionsStore.getState()
const {openBranchingPanel} = useUiTools()
const theme = useTheme(); const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(600)); const isMobile = useMediaQuery(theme.breakpoints.down(600));
console.log("questions ", questions) console.log("questions ", questions)
console.log("rules ", questions.filter((q) => q.type !== null).map((q) => ({id: q.content.id, rule: q.content.rule})))
return ( return (
<Box sx={{ display: "flex", gap: "20px", flexWrap: "wrap", marginBottom: isMobile ? "20px" : undefined }}> <Box sx={{ display: "flex", gap: "20px", flexWrap: "wrap", marginBottom: isMobile ? "20px" : undefined }}>
<Box sx={{ flexBasis: "796px" }}> <Box sx={{ flexBasis: "796px" }}>

@ -17,12 +17,13 @@ import ArrowLeft from "../../assets/icons/questionsPage/arrowLeft";
import BranchingQuestions from "./BranchingModal/BranchingQuestionsModal" import BranchingQuestions from "./BranchingModal/BranchingQuestionsModal"
import { QuestionSwitchWindowTool } from "./QuestionSwitchWindowTool"; import { QuestionSwitchWindowTool } from "./QuestionSwitchWindowTool";
import { useQuestionsStore } from "@root/questions/store"; import { useQuestionsStore } from "@root/questions/store";
import { updateOpenBranchingPanel, updateEditSomeQuestion } from "@root/questions/actions"; import { updateOpenBranchingPanel, updateEditSomeQuestion } from "@root/uiTools/actions";
import { useUiTools } from "@root/uiTools/store";
export default function QuestionsPage() { export default function QuestionsPage() {
const theme = useTheme(); const theme = useTheme();
const { openedModalSettingsId, openBranchingPanel } = useQuestionsStore(); const { openedModalSettingsId, openBranchingPanel } = useUiTools();
const isMobile = false//useMediaQuery(theme.breakpoints.down(660)); const isMobile = false//useMediaQuery(theme.breakpoints.down(660));
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
useLayoutEffect(() => { useLayoutEffect(() => {

@ -2,11 +2,11 @@ import { useParams } from "react-router-dom";
import { Box, Button, IconButton, Typography } from "@mui/material"; import { Box, Button, IconButton, Typography } from "@mui/material";
import { ReactComponent as CheckedIcon } from "@icons/checked.svg"; import { ReactComponent as CheckedIcon } from "@icons/checked.svg";
import { useQuestionsStore } from "@root/questions/store"; import { useQuestionsStore } from "@root/questions/store";
import { updateDragQuestionContentId } from "@root/questions/actions";
import { useEffect } from "react"; import { useEffect } from "react";
import { AnyTypedQuizQuestion, UntypedQuizQuestion } from "@model/questionTypes/shared"; import { AnyTypedQuizQuestion, UntypedQuizQuestion } from "@model/questionTypes/shared";
import { Pencil } from "../../startPage/Sidebar/icons/Pencil"; import { Pencil } from "../../startPage/Sidebar/icons/Pencil";
import {updateOpenBranchingPanel, updateEditSomeQuestion} from "@root/questions/actions" import { updateOpenBranchingPanel, updateEditSomeQuestion, updateDragQuestionContentId } from "@root/uiTools/actions"
import { useUiTools } from "@root/uiTools/store";
const getItemStyle = (isDragging: any, draggableStyle: any) => ({ const getItemStyle = (isDragging: any, draggableStyle: any) => ({
@ -24,7 +24,7 @@ const getItemStyle = (isDragging: any, draggableStyle: any) => ({
type AnyQuestion = UntypedQuizQuestion | AnyTypedQuizQuestion type AnyQuestion = UntypedQuizQuestion | AnyTypedQuizQuestion
export const QuestionsList = () => { export const QuestionsList = () => {
const { desireToOpenABranchingModal } = useQuestionsStore() const { desireToOpenABranchingModal } = useUiTools()
const trashQuestions = useQuestionsStore().questions const trashQuestions = useQuestionsStore().questions
const questions = trashQuestions.filter((question) => question.type !== "result") const questions = trashQuestions.filter((question) => question.type !== "result")

@ -3,18 +3,21 @@
import {Box, Typography, Switch, useTheme, Button, useMediaQuery} from "@mui/material"; import {Box, Typography, Switch, useTheme, Button, useMediaQuery} from "@mui/material";
import { QuestionsList } from "./QuestionsList"; import { QuestionsList } from "./QuestionsList";
import { updateOpenBranchingPanel } from "@root/questions/actions"; import { updateOpenBranchingPanel } from "@root/uiTools/actions";
import {useQuestionsStore} from "@root/questions/store"; import {useQuestionsStore} from "@root/questions/store";
import {useRef} from "react"; import {useRef} from "react";
import { useUiTools } from "@root/uiTools/store";
export const SwitchBranchingPanel = () => { export const SwitchBranchingPanel = () => {
const theme = useTheme(); const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(660)); const isMobile = useMediaQuery(theme.breakpoints.down(660));
const {openBranchingPanel} = useQuestionsStore.getState() const isTablet = useMediaQuery(theme.breakpoints.down(1000));
console.log(openBranchingPanel)
const {openBranchingPanel} = useUiTools()
const ref = useRef() const ref = useRef()
return (
return ( !isTablet || openBranchingPanel ?
<Box sx={{ userSelect: "none", maxWidth: "350px", width: "100%" }}> <Box sx={{ userSelect: "none", maxWidth: "350px", width: "100%" }}>
<Box <Box
sx={{ sx={{
@ -29,8 +32,8 @@ export const SwitchBranchingPanel = () => {
> >
<Switch <Switch
checked={openBranchingPanel} checked={openBranchingPanel}
onChange={ onChange={
(e) => updateOpenBranchingPanel(e.target.checked) (e) => updateOpenBranchingPanel(e.target.checked)
} }
sx={{ sx={{
width: 50, width: 50,
@ -88,5 +91,7 @@ export const SwitchBranchingPanel = () => {
</Box> </Box>
{ openBranchingPanel && <QuestionsList /> } { openBranchingPanel && <QuestionsList /> }
</Box> </Box>
:
<></>
); );
}; };

@ -16,17 +16,14 @@ export const FirstEntry = () => {
const create = () => { const create = () => {
if (quiz?.config.haveRoot) { if (quiz?.config.haveRoot) {
console.log("createFrontResult")
questions questions
.filter((question:AnyTypedQuizQuestion) => { .filter((question:AnyTypedQuizQuestion) => {
console.log(question)
return question.type !== null && question.content.rule.parentId.length !== 0 && question.content.rule.children.length === 0 return question.type !== null && question.content.rule.parentId.length !== 0 && question.content.rule.children.length === 0
}) })
.forEach(question => { .forEach(question => {
createFrontResult(quiz.id, question.content.id) createFrontResult(quiz.id, question.content.id)
}) })
} else { } else {
console.log("createFrontResult")
createFrontResult(quiz.id, "line") createFrontResult(quiz.id, "line")
} }
} }

@ -21,7 +21,6 @@ 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")
console.log("опросник ", quiz)
const [quizExpand, setQuizExpand] = useState(true) const [quizExpand, setQuizExpand] = useState(true)
const [resultContract, setResultContract] = useState(true) const [resultContract, setResultContract] = useState(true)
const isReadyToLeaveRef = useRef(true); const isReadyToLeaveRef = useRef(true);

@ -19,11 +19,9 @@ interface Props {
} }
export const StartPageViewPublication = ({setVisualStartPage}:Props) => { export const StartPageViewPublication = ({setVisualStartPage}:Props) => {
console.log("startpage")
const theme = useTheme(); const theme = useTheme();
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
const { isMobileDevice } = useUADevice(); const { isMobileDevice } = useUADevice();
console.log(quiz)
if (!quiz) return null; if (!quiz) return null;

@ -10,28 +10,38 @@ import { quizApi } from "@api/quiz";
import { setQuizes } from "@root/quizes/actions"; import { setQuizes } from "@root/quizes/actions";
import { isAxiosError } from "axios"; import { isAxiosError } from "axios";
import { devlog } from "@frontend/kitui"; import { devlog } from "@frontend/kitui";
import { useQuizStore } from "@root/quizes/store";
import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared"; import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
import { useQuestionsStore } from "@root/questions/store";
import { setQuestions } from "@root/questions/actions";
import { questionApi } from "@api/question";
export const ViewPage = () => { export const ViewPage = () => {
useSWR("quizes", () => quizApi.getList(), {
onSuccess: setQuizes,
onError: error => {
const message = isAxiosError<string>(error) ? (error.response?.data ?? "") : "";
devlog("Error getting quiz list", error);
enqueueSnackbar(`Не удалось получить квизы. ${message}`);
},
});
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
console.log(quiz) const { editQuizId } = useQuizStore();
const { questions } = useQuestions(); const { questions } = useQuestionsStore();
const [visualStartPage, setVisualStartPage] = useState<boolean>(
!quiz?.config.noStartPage useEffect(() => {
); const getData = async () => {
const quizes = await quizApi.getList()
setQuizes(quizes)
const questions = await questionApi.getList({ quiz_id: editQuizId })
setQuestions(questions)
}
getData()
}, [])
useEffect(() => {
setVisualStartPage(quiz?.config.noStartPage)
}, [questions])
const [visualStartPage, setVisualStartPage] = useState<boolean>();
console.log("quiz ", quiz)
console.log("quiz.config ", quiz?.config)
console.log("quiz.config.noStartPage ", quiz?.config.noStartPage)
useEffect(() => { useEffect(() => {
const link = document.querySelector('link[rel="icon"]'); const link = document.querySelector('link[rel="icon"]');
@ -45,9 +55,11 @@ export const ViewPage = () => {
questions.filter(({ type }) => type) as AnyTypedQuizQuestion[] questions.filter(({ type }) => type) as AnyTypedQuizQuestion[]
).sort((previousItem, item) => previousItem.page - item.page); ).sort((previousItem, item) => previousItem.page - item.page);
console.log("visualStartPage ", visualStartPage)
if (visualStartPage === undefined) return <></>
return ( return (
<Box> <Box>
{visualStartPage ? ( {!visualStartPage ? (
<StartPageViewPublication setVisualStartPage={setVisualStartPage}/> <StartPageViewPublication setVisualStartPage={setVisualStartPage}/>
) : ( ) : (
<Question questions={filteredQuestions} /> <Question questions={filteredQuestions} />

@ -47,7 +47,6 @@ export const Number = ({ currentQuestion }: NumberProps) => {
const max = window.Number(currentQuestion.content.range.split("—")[1]); const max = window.Number(currentQuestion.content.range.split("—")[1]);
useEffect(() => { useEffect(() => {
console.log("ans", currentQuestion.content.start);
if (answer) { if (answer) {
setMinRange(answer.split("—")[0]); setMinRange(answer.split("—")[0]);
setMaxRange(answer.split("—")[1]); setMaxRange(answer.split("—")[1]);

@ -24,7 +24,7 @@ type RatingProps = {
const buttonRatingForm = [ const buttonRatingForm = [
{ {
name: "star", name: "star",
icon: (color: string) => <StarIconMini width={35} color={color} />, icon: (color: string) => <StarIconMini width={50} color={color} />,
}, },
{ {
name: "trophie", name: "trophie",

@ -1,14 +1,14 @@
import { login } from "@api/auth"; import { login } from "@api/auth";
import CloseIcon from "@mui/icons-material/Close"; import CloseIcon from "@mui/icons-material/Close";
import { import {
Box, Box,
Button, Button,
Dialog, Dialog,
IconButton, IconButton,
Link, Link,
Typography, Typography,
useMediaQuery, useMediaQuery,
useTheme, useTheme,
} from "@mui/material"; } from "@mui/material";
import { setUserId, useUserStore } from "@root/user"; import { setUserId, useUserStore } from "@root/user";
import InputTextfield from "@ui_kit/InputTextfield"; import InputTextfield from "@ui_kit/InputTextfield";
@ -17,7 +17,7 @@ import PasswordInput from "@ui_kit/passwordInput";
import { useFormik } from "formik"; import { useFormik } from "formik";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Link as RouterLink, useNavigate } from "react-router-dom"; import { Link as RouterLink, useNavigate, useLocation } from "react-router-dom";
import { object, string } from "yup"; import { object, string } from "yup";
interface Values { interface Values {
@ -43,6 +43,8 @@ export default function SigninDialog() {
const theme = useTheme(); const theme = useTheme();
const upMd = useMediaQuery(theme.breakpoints.up("md")); const upMd = useMediaQuery(theme.breakpoints.up("md"));
const navigate = useNavigate(); const navigate = useNavigate();
const location = useLocation();
const formik = useFormik<Values>({ const formik = useFormik<Values>({
initialValues, initialValues,
validationSchema, validationSchema,
@ -110,11 +112,11 @@ export default function SigninDialog() {
borderRadius: "12px", borderRadius: "12px",
boxShadow: "0px 15px 80px rgb(210 208 225 / 70%)", boxShadow: "0px 15px 80px rgb(210 208 225 / 70%)",
"& .MuiFormHelperText-root.Mui-error, & .MuiFormHelperText-root.Mui-error.MuiFormHelperText-filled": "& .MuiFormHelperText-root.Mui-error, & .MuiFormHelperText-root.Mui-error.MuiFormHelperText-filled":
{ {
position: "absolute", position: "absolute",
top: "46px", top: "46px",
margin: "0", margin: "0",
}, },
}} }}
> >
<IconButton <IconButton
@ -153,7 +155,7 @@ export default function SigninDialog() {
id="email" id="email"
label="Email" label="Email"
gap={upMd ? "10px" : "10px"} gap={upMd ? "10px" : "10px"}
/> />
<PasswordInput <PasswordInput
TextfieldProps={{ TextfieldProps={{
value: formik.values.password, value: formik.values.password,
@ -190,16 +192,17 @@ export default function SigninDialog() {
Войти Войти
</Button> </Button>
{/* <Link {/* <Link
component={RouterLink} component={RouterLink}
to="/" to="/"
href="#" href="#"
sx={{
color: "#4D4D4D", sx={{
mb: "15px", color: "#4D4D4D",
}} mb: "15px",
> }}
Забыли пароль? >
</Link> */} Забыли пароль?
</Link> */}
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",

@ -17,7 +17,7 @@ import PasswordInput from "@ui_kit/passwordInput";
import { useFormik } from "formik"; import { useFormik } from "formik";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Link as RouterLink, useNavigate } from "react-router-dom"; import {Link as RouterLink, useLocation, useNavigate} from "react-router-dom";
import { object, ref, string } from "yup"; import { object, ref, string } from "yup";
interface Values { interface Values {
@ -50,6 +50,8 @@ export default function SignupDialog() {
const user = useUserStore((state) => state.user); const user = useUserStore((state) => state.user);
const theme = useTheme(); const theme = useTheme();
const upMd = useMediaQuery(theme.breakpoints.up("md")); const upMd = useMediaQuery(theme.breakpoints.up("md"));
const location = useLocation()
const navigate = useNavigate(); const navigate = useNavigate();
const formik = useFormik<Values>({ const formik = useFormik<Values>({
initialValues, initialValues,
@ -220,6 +222,7 @@ export default function SignupDialog() {
<Link <Link
component={RouterLink} component={RouterLink}
to="/signin" to="/signin"
state={{ backgroundLocation: location.state.backgroundLocation }}
sx={{ sx={{
color: "#7E2AEA", color: "#7E2AEA",
mt: "auto", mt: "auto",

@ -29,36 +29,36 @@ import { useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import useSWR from "swr"; import useSWR from "swr";
import { SidebarMobile } from "./Sidebar/SidebarMobile"; import { SidebarMobile } from "./Sidebar/SidebarMobile";
import {cleanQuestions, updateOpenBranchingPanel} from "@root/questions/actions"; import { cleanQuestions } from "@root/questions/actions";
import {BranchingPanel} from "../Questions/BranchingPanel"; import { updateOpenBranchingPanel } from "@root/uiTools/actions";
import {setQuestions} from "@root/questions/actions"; import { BranchingPanel } from "../Questions/BranchingPanel";
import {useQuestionsStore} from "@root/questions/store"; import { setQuestions } from "@root/questions/actions";
import { useQuestions } from "@root/questions/hooks"; import { useQuestionsStore } from "@root/questions/store";
import { useQuizes } from "@root/quizes/hooks";
import { questionApi } from "@api/question"; import { questionApi } from "@api/question";
import { useUiTools } from "@root/uiTools/store";
export default function EditPage() { export default function EditPage() {
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
const { editQuizId } = useQuizStore();
console.log("get questions") useEffect(() => {
useSWR(["questions", quiz?.backendId], ([, id]) => questionApi.getList({ quiz_id: id }), { const getData = async () => {
onSuccess: setQuestions, const quizes = await quizApi.getList()
onError: error => { setQuizes(quizes)
const message = isAxiosError<string>(error) ? (error.response?.data ?? "") : "";
devlog("Error getting question list", error); const questions = await questionApi.getList({ quiz_id: editQuizId })
enqueueSnackbar(`Не удалось получить вопросы. ${message}`); setQuestions(questions)
} }
}); getData()
}, [])
const { openBranchingPanel } = useUiTools()
const {openBranchingPanel, questions} = useQuestionsStore.getState()
const theme = useTheme(); const theme = useTheme();
const navigate = useNavigate(); const navigate = useNavigate();
const editQuizId = useQuizStore(state => state.editQuizId);
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));
@ -74,6 +74,7 @@ export default function EditPage() {
cleanQuestions(); cleanQuestions();
}, []); }, []);
return ( return (
<> <>
{/*хедер*/} {/*хедер*/}
@ -237,7 +238,7 @@ export default function EditPage() {
</> </>
} }
</Box> </Box>
{isTablet && [1, 2, 3].includes(currentStep) && ( {isTablet &&
<Box <Box
sx={{ sx={{
position: "absolute", position: "absolute",
@ -251,72 +252,74 @@ export default function EditPage() {
background: "#FFF", background: "#FFF",
}} }}
> >
<Box {[1, 2].includes(currentStep) && !openBranchingPanel && (
sx={{ <Box
display: "flex",
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" }}> checked={openBranchingPanel}
Логика ветвления onChange={
</Typography> (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> )}
<Button <Button
variant="contained" variant="contained"
sx={{ sx={{
@ -328,7 +331,8 @@ export default function EditPage() {
Опубликовать Опубликовать
</Button> </Button>
</Box> </Box>
)} }
</Box> </Box>
</> </>
); );

@ -99,7 +99,6 @@ const updateQuestionOrders = () => {
const questions = useQuestionsStore.getState().questions.filter( const questions = useQuestionsStore.getState().questions.filter(
(question): question is AnyTypedQuizQuestion => question.type !== null && question.type !== "result" (question): question is AnyTypedQuizQuestion => question.type !== null && question.type !== "result"
); );
console.log(questions);
questions.forEach((question, index) => { questions.forEach((question, index) => {
updateQuestion(question.id, question => { updateQuestion(question.id, question => {
@ -386,13 +385,16 @@ export const createTypedQuestion = async (
}); });
export const deleteQuestion = async (questionId: string) => requestQueue.enqueue(async () => { export const deleteQuestion = async (questionId: string) => requestQueue.enqueue(async () => {
console.log("Я получил запрос на удаление. ИД - ", questionId)
const question = useQuestionsStore.getState().questions.find(q => q.id === questionId); const question = useQuestionsStore.getState().questions.find(q => q.id === questionId);
console.log("delete question ", question)
if (!question) return; if (!question) return;
if (question.type === null) { if (question.type === null) {
console.log("removeQuestion")
removeQuestion(questionId); removeQuestion(questionId);
return; return;
} }
@ -461,9 +463,7 @@ function setProducedState<A extends string | { type: unknown; }>(
}; };
export const cleardragQuestionContentId = () => {
useQuestionsStore.setState({ dragQuestionContentId: null });
};
export const getQuestionById = (questionId: string | null) => { export const getQuestionById = (questionId: string | null) => {
if (questionId === null) return null; if (questionId === null) return null;
@ -479,13 +479,10 @@ export const getQuestionByContentId = (questionContentId: string | null) => {
}; };
export const updateOpenedModalSettingsId = (id?: string) => useQuestionsStore.setState({ openedModalSettingsId: id ? id : null }); export const updateOpenedModalSettingsId = (id?: string) => useQuestionsStore.setState({ openedModalSettingsId: id ? id : null });
export const updateDragQuestionContentId = (contentId?: string) => {
useQuestionsStore.setState({ dragQuestionContentId: contentId ? contentId : null });
};
export const clearRuleForAll = () => { export const clearRuleForAll = () => {
const { questions } = useQuestionsStore.getState(); const { questions } = useQuestionsStore.getState();
console.log(questions)
questions.forEach(question => { questions.forEach(question => {
if (question.type !== null && (question.content.rule.main.length > 0 || question.content.rule.default.length > 0 || question.content.rule.parentId.length > 0)) { if (question.type !== null && (question.content.rule.main.length > 0 || question.content.rule.default.length > 0 || question.content.rule.parentId.length > 0)) {
updateQuestion(question.content.id, question => { updateQuestion(question.content.id, question => {
@ -497,23 +494,6 @@ export const clearRuleForAll = () => {
}); });
}; };
export const updateOpenBranchingPanel = (value: boolean) => useQuestionsStore.setState({ openBranchingPanel: value });
let UDTOABM: ReturnType<typeof setTimeout>;
export const updateDesireToOpenABranchingModal = (contentId: string) => {
useQuestionsStore.setState({ desireToOpenABranchingModal: contentId });
clearTimeout(UDTOABM);
UDTOABM = setTimeout(() => {
useQuestionsStore.setState({ desireToOpenABranchingModal: null });
}, 7000);
};
export const clearDesireToOpenABranchingModal = () => {
useQuestionsStore.setState({ desireToOpenABranchingModal: null });
};
export const updateEditSomeQuestion = (contentId?: string) => {
useQuestionsStore.setState({ editSomeQuestion: contentId === undefined ? null : contentId });
};
export const createFrontResult = (quizId: number, parentContentId?: string) => setProducedState(state => { export const createFrontResult = (quizId: number, parentContentId?: string) => setProducedState(state => {
const frontId = nanoid(); const frontId = nanoid();

@ -6,6 +6,7 @@ import useSWR from "swr";
import { setQuestions } from "./actions"; import { setQuestions } from "./actions";
import { useQuestionsStore } from "./store"; import { useQuestionsStore } from "./store";
import { useCurrentQuiz } from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";
import { useEffect } from "react";
export function useQuestions() { export function useQuestions() {

@ -5,20 +5,10 @@ import { devtools } from "zustand/middleware";
export type QuestionsStore = { export type QuestionsStore = {
questions: (AnyTypedQuizQuestion | UntypedQuizQuestion)[]; questions: (AnyTypedQuizQuestion | UntypedQuizQuestion)[];
openedModalSettingsId: string | null;
dragQuestionContentId: string | null;
openBranchingPanel: boolean;
desireToOpenABranchingModal: string | null;
editSomeQuestion: string | null;
}; };
const initialState: QuestionsStore = { const initialState: QuestionsStore = {
questions: [], questions: [],
openedModalSettingsId: null as null,
dragQuestionContentId: null,
openBranchingPanel: false,
desireToOpenABranchingModal: null as null,
editSomeQuestion: null as null,
}; };

@ -7,6 +7,7 @@ import { devlog } from "@frontend/kitui";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
export function useQuizes() { export function useQuizes() {
const { isLoading, error, isValidating } = useSWR("quizes", () => quizApi.getList(), { const { isLoading, error, isValidating } = useSWR("quizes", () => quizApi.getList(), {
onSuccess: setQuizes, onSuccess: setQuizes,
@ -25,10 +26,9 @@ export function useQuizes() {
} }
export function useCurrentQuiz() { export function useCurrentQuiz() {
const quizId = useQuizStore(state => state.editQuizId); const { quizes, editQuizId } = useQuizStore();
const { quizes } = useQuizes();
const quiz = quizes.find(q => q.backendId === quizId); const quiz = quizes.find(q => q.backendId === editQuizId);
return quiz; return quiz;
} }

@ -0,0 +1,31 @@
import { useUiTools } from "./store";
export const updateOpenBranchingPanel = (value: boolean) => useUiTools.setState({ openBranchingPanel: value });
export const cleardragQuestionContentId = () => {
useUiTools.setState({ dragQuestionContentId: null });
};
export const updateDragQuestionContentId = (contentId?: string) => {
useUiTools.setState({ dragQuestionContentId: contentId ? contentId : null });
};
let UDTOABM: ReturnType<typeof setTimeout>;
export const updateDesireToOpenABranchingModal = (contentId: string) => {
useUiTools.setState({ desireToOpenABranchingModal: contentId });
clearTimeout(UDTOABM);
UDTOABM = setTimeout(() => {
useUiTools.setState({ desireToOpenABranchingModal: null });
}, 7000);
};
export const clearDesireToOpenABranchingModal = () => {
useUiTools.setState({ desireToOpenABranchingModal: null });
};
export const updateEditSomeQuestion = (contentId?: string) => {
useUiTools.setState({ editSomeQuestion: contentId === undefined ? null : contentId });
};

@ -0,0 +1,30 @@
import { create } from "zustand";
import { devtools } from "zustand/middleware";
export type UiTools = {
openedModalSettingsId: string | null;
dragQuestionContentId: string | null;
openBranchingPanel: boolean;
desireToOpenABranchingModal: string | null;
editSomeQuestion: string | null;
};
const initialState: UiTools = {
openedModalSettingsId: null as null,
dragQuestionContentId: null,
openBranchingPanel: false,
desireToOpenABranchingModal: null as null,
editSomeQuestion: null as null,
};
export const useUiTools = create<UiTools>()(
devtools(
() => initialState,
{
name: "UiTools",
enabled: process.env.NODE_ENV === "development",
trace: process.env.NODE_ENV === "development",
}
)
);