Merge branch 'some-fix' into view-answers-fixes
This commit is contained in:
commit
a5897a38b7
31
src/App.tsx
31
src/App.tsx
@ -19,6 +19,7 @@ import EditPage from "./pages/startPage/EditPage";
|
||||
import { clearAuthToken, getMessageFromFetchError, useUserFetcher } from "@frontend/kitui";
|
||||
import { clearUserData, setUser, useUserStore } from "@root/user";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import PrivateRoute from "@ui_kit/PrivateRoute";
|
||||
|
||||
|
||||
dayjs.locale("ru");
|
||||
@ -34,8 +35,8 @@ const routeslink = [
|
||||
|
||||
export default function App() {
|
||||
const userId = useUserStore((state) => state.userId);
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useUserFetcher({
|
||||
url: `https://hub.pena.digital/user/${userId}`,
|
||||
@ -50,8 +51,8 @@ export default function App() {
|
||||
}
|
||||
},
|
||||
});
|
||||
if (location.state?.redirectTo)
|
||||
return <Navigate to={location.state.redirectTo} replace state={{ backgroundLocation: location }} />
|
||||
if (location.state?.redirectTo)
|
||||
return <Navigate to={location.state.redirectTo} replace state={{ backgroundLocation: location }} />;
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -62,19 +63,19 @@ export default function App() {
|
||||
<Route path="/signup" element={<SignupDialog />} />
|
||||
</Routes>
|
||||
)}
|
||||
|
||||
<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 />} />
|
||||
<Route path="/signin" element={<Navigate to="/" replace state={{ redirectTo: "/signin" }} />} />
|
||||
<Route path="/signup" element={<Navigate to="/" replace state={{ redirectTo: "/signup" }} />} />
|
||||
<Route element={<PrivateRoute />}>
|
||||
{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="/view" element={<ViewPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
@ -77,7 +77,7 @@ export const AnswerItem = ({
|
||||
placeholder={"Добавьте ответ"}
|
||||
multiline={largeCheck}
|
||||
onChange={({ target }) => {
|
||||
setQuestionVariantAnswer(target.value);
|
||||
setQuestionVariantAnswer(target.value || " ");
|
||||
}}
|
||||
onKeyDown={(event: KeyboardEvent<HTMLInputElement>) => {
|
||||
if (event.code === "Enter" && !largeCheck) {
|
||||
@ -124,7 +124,7 @@ export const AnswerItem = ({
|
||||
style={{ margin: "10px" }}
|
||||
placeholder="Подсказка для этого ответа"
|
||||
value={variant.hints}
|
||||
onChange={e => setQuestionVariantAnswer(e.target.value)}
|
||||
onChange={e => setQuestionVariantAnswer(e.target.value || " ")}
|
||||
onKeyDown={(
|
||||
event: KeyboardEvent<HTMLTextAreaElement>
|
||||
) => event.stopPropagation()}
|
||||
|
@ -7,7 +7,8 @@ import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||
import { updateRootContentId } from "@root/quizes/actions"
|
||||
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"
|
||||
import { useQuestionsStore } from "@root/questions/store";
|
||||
import { deleteQuestion, updateQuestion, updateOpenedModalSettingsId, getQuestionByContentId, clearRuleForAll } from "@root/questions/actions";
|
||||
import { deleteQuestion, updateQuestion, getQuestionByContentId, clearRuleForAll } from "@root/questions/actions";
|
||||
import { updateOpenedModalSettingsId, } from "@root/uiTools/actions";
|
||||
import { cleardragQuestionContentId } from "@root/uiTools/actions";
|
||||
import { withErrorBoundary } from "react-error-boundary";
|
||||
|
||||
@ -660,6 +661,7 @@ let gearsPopper = null
|
||||
gearElement.style.zIndex = "1"
|
||||
gearsContainer.current?.appendChild(gearElement);
|
||||
gearElement.addEventListener("mouseup", (e) => {
|
||||
console.log("up")
|
||||
updateOpenedModalSettingsId(item.id())
|
||||
});
|
||||
|
||||
@ -811,7 +813,7 @@ let gearsPopper = null
|
||||
}}
|
||||
autoungrabify={true}
|
||||
/>
|
||||
<button onClick={() => {
|
||||
{/* <button onClick={() => {
|
||||
console.log("NODES____________________________")
|
||||
cyRef.current?.elements().forEach((ele: any) => {
|
||||
console.log(ele.data())
|
||||
@ -820,7 +822,7 @@ let gearsPopper = null
|
||||
<button onClick={() => {
|
||||
console.log("ELEMENTS____________________________")
|
||||
console.log(questions)
|
||||
}}>elements</button>
|
||||
}}>elements</button> */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Box } from "@mui/material"
|
||||
import { useEffect, useRef, useLayoutEffect } from "react";
|
||||
import { deleteQuestion, clearRuleForAll, updateQuestion, updateOpenedModalSettingsId } from "@root/questions/actions"
|
||||
import { deleteQuestion, clearRuleForAll, updateQuestion } from "@root/questions/actions"
|
||||
import { updateOpenedModalSettingsId } from "@root/uiTools/actions"
|
||||
import { updateRootContentId } from "@root/quizes/actions"
|
||||
import { useCurrentQuiz } from "@root/quizes/hooks"
|
||||
import { useQuestionsStore } from "@root/questions/store"
|
||||
|
@ -22,8 +22,8 @@ import InfoIcon from "@icons/Info";
|
||||
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
|
||||
|
||||
import { TypeSwitch, BlockRule } from "./Settings";
|
||||
import { getQuestionById, getQuestionByContentId, updateOpenedModalSettingsId, updateQuestion } from "@root/questions/actions";
|
||||
import { useQuestionsStore } from "@root/questions/store";
|
||||
import { getQuestionById, getQuestionByContentId, updateQuestion } from "@root/questions/actions";
|
||||
import { updateOpenedModalSettingsId } from "@root/uiTools/actions";
|
||||
import { useUiTools } from "@root/uiTools/store";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
|
||||
@ -166,7 +166,7 @@ export default function BranchingQuestions() {
|
||||
|
||||
onClick={() => {
|
||||
let mutate = JSON.parse(JSON.stringify(parentQuestion))
|
||||
mutate.content.rule.default = targetQuestion.id
|
||||
mutate.content.rule.default = parentQuestion.content.rule.default === targetQuestion.content.id ? "" : targetQuestion.content.id
|
||||
setParentQuestion(mutate)
|
||||
}}
|
||||
/>} label="Следующий вопрос по-умолчанию" />
|
||||
|
@ -25,9 +25,10 @@ export const BranchingQuestionsModal = ({
|
||||
};
|
||||
|
||||
const typedQuestions: AnyTypedQuizQuestion[] = questions.filter(
|
||||
(question) => question.type && !question.content.rule.parentId
|
||||
(question) => question.type && !question.content.rule.parentId && question.type !== "result"
|
||||
) as AnyTypedQuizQuestion[];
|
||||
|
||||
if (typedQuestions.length === 0) return <></>
|
||||
return (
|
||||
<Modal open={openedModalQuestions} onClose={handleClose}>
|
||||
<Box
|
||||
|
@ -23,7 +23,7 @@ import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared";
|
||||
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { useQuestionsStore } from "@root/questions/store";
|
||||
import { updateOpenedModalSettingsId } from "@root/questions/actions";
|
||||
import { updateOpenedModalSettingsId } from "@root/uiTools/actions";
|
||||
import { updateRootContentId } from "@root/quizes/actions";
|
||||
import { useUiTools } from "@root/uiTools/store";
|
||||
|
||||
@ -88,7 +88,7 @@ export default function ButtonsOptions({
|
||||
title: "Ветвление",
|
||||
value: "branching",
|
||||
myFunc: (question) => {
|
||||
updateOpenBranchingPanel(true);
|
||||
// updateOpenBranchingPanel(true);
|
||||
updateDesireToOpenABranchingModal(question.content.id);
|
||||
}
|
||||
},
|
||||
|
@ -191,7 +191,7 @@ export default function ButtonsOptionsAndPict({
|
||||
onMouseEnter={() => setButtonHover("branching")}
|
||||
onMouseLeave={() => setButtonHover("")}
|
||||
onClick={() => {
|
||||
updateOpenBranchingPanel(true);
|
||||
// updateOpenBranchingPanel(true);
|
||||
updateDesireToOpenABranchingModal(question.content.id);
|
||||
}}
|
||||
sx={{
|
||||
|
@ -125,7 +125,7 @@ export default function SettingsData({ question }: SettingsDataProps) {
|
||||
<CustomTextField
|
||||
placeholder={"Развёрнутое описание вопроса"}
|
||||
text={question.content.innerName}
|
||||
onChange={({ target }) => setInnerName(target.value)}
|
||||
onChange={({ target }) => setInnerName(target.value || " ")}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -102,7 +102,7 @@ export default function QuestionsPageCard({ question, draggableProps, isDragging
|
||||
<TextField
|
||||
defaultValue={question.title}
|
||||
placeholder={"Заголовок вопроса"}
|
||||
onChange={({ target }: { target: HTMLInputElement; }) => setTitle(target.value)}
|
||||
onChange={({ target }: { target: HTMLInputElement; }) => setTitle(target.value || " ")}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<Box>
|
||||
|
@ -184,7 +184,7 @@ export default function SettingDropDown({ question }: SettingDropDownProps) {
|
||||
<CustomTextField
|
||||
placeholder={"Развёрнутое описание вопроса"}
|
||||
text={question.content.innerName}
|
||||
onChange={({ target }) => debounced(target.value)}
|
||||
onChange={({ target }) => debounced(target.value || " ")}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -3,10 +3,13 @@ import { reorderQuestions } from "@root/questions/actions";
|
||||
import type { DropResult } from "react-beautiful-dnd";
|
||||
import { DragDropContext, Droppable } from "react-beautiful-dnd";
|
||||
import FormDraggableListItem from "./FormDraggableListItem";
|
||||
import { useQuestions } from "@root/questions/hooks";
|
||||
|
||||
|
||||
export const FormDraggableList = () => {
|
||||
|
||||
const { questions } = useQuestions()
|
||||
|
||||
const onDragEnd = ({ destination, source }: DropResult) => {
|
||||
if (destination) reorderQuestions(source.index, destination.index);
|
||||
};
|
||||
@ -16,7 +19,7 @@ export const FormDraggableList = () => {
|
||||
<Droppable droppableId="droppable-list">
|
||||
{(provided) => (
|
||||
<Box ref={provided.innerRef} {...provided.droppableProps}>
|
||||
{questions.map((question, index) => (
|
||||
{questions?.map((question, index) => (
|
||||
<FormDraggableListItem
|
||||
key={question.id}
|
||||
question={question}
|
||||
|
@ -99,7 +99,7 @@ export const UploadVideoModal = ({
|
||||
<CustomTextField
|
||||
placeholder={"http://example.com"}
|
||||
text={video}
|
||||
onChange={({ target }) => onUpload(target.value)}
|
||||
onChange={({ target }) => onUpload(target.value || " ")}
|
||||
/>
|
||||
</Box>
|
||||
) : (
|
||||
@ -114,7 +114,7 @@ export const UploadVideoModal = ({
|
||||
<input
|
||||
onChange={({ target }) => {
|
||||
if (target.files?.length) {
|
||||
onUpload(URL.createObjectURL(target.files[0]));
|
||||
onUpload(URL.createObjectURL(target.files[0] || " "));
|
||||
}
|
||||
}}
|
||||
hidden
|
||||
|
@ -82,7 +82,7 @@ export default function ResponseSettings({ question }: Props) {
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<CustomCheckbox
|
||||
{/* <CustomCheckbox
|
||||
sx={{ mr: isMobile ? "0px" : "16px" }}
|
||||
label={'Вариант "свой ответ"'}
|
||||
checked={question.content.own}
|
||||
@ -93,7 +93,7 @@ export default function ResponseSettings({ question }: Props) {
|
||||
question.content.own = target.checked;
|
||||
});
|
||||
}}
|
||||
/>
|
||||
/> */}
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
@ -168,7 +168,7 @@ export default function ResponseSettings({ question }: Props) {
|
||||
sx={{ mr: isMobile ? "0px" : "16px" }}
|
||||
placeholder={"Развёрнутое описание вопроса"}
|
||||
text={question.content.innerName}
|
||||
onChange={({ target }) => updateQuestionInnerName(target.value)}
|
||||
onChange={({ target }) => updateQuestionInnerName(target.value || " ")}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -62,7 +62,7 @@ export default function HelpQuestions({ question }: HelpQuestionsProps) {
|
||||
<CustomTextField
|
||||
placeholder={"Текст консультанта"}
|
||||
text={question.content.hint.text}
|
||||
onChange={({ target }) => updateQuestionHint(target.value)}
|
||||
onChange={({ target }) => updateQuestionHint(target.value || " ")}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
|
@ -144,7 +144,7 @@ export const StartPageViewPublication = ({setVisualStartPage}:Props) => {
|
||||
padding: "10px 15px",
|
||||
width: quiz.config.startpageType === "standard" ? "100%" : "auto"
|
||||
}}
|
||||
onClick={() => setVisualStartPage(false)}
|
||||
onClick={() => setVisualStartPage(true)}
|
||||
>
|
||||
{quiz.config.startpage.button.trim() ? quiz.config.startpage.button : "Пройти тест"}
|
||||
</Button>
|
||||
|
@ -25,17 +25,17 @@ export const ViewPage = () => {
|
||||
|
||||
useEffect(() => {
|
||||
const getData = async () => {
|
||||
const quizes = await quizApi.getList()
|
||||
setQuizes(quizes)
|
||||
const quizes = await quizApi.getList()
|
||||
setQuizes(quizes)
|
||||
|
||||
const questions = await questionApi.getList({ quiz_id: editQuizId })
|
||||
setQuestions(questions)
|
||||
const questions = await questionApi.getList({ quiz_id: editQuizId })
|
||||
setQuestions(questions)
|
||||
}
|
||||
getData()
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
setVisualStartPage(quiz?.config.noStartPage)
|
||||
}, [questions])
|
||||
}, [questions])
|
||||
|
||||
|
||||
const [visualStartPage, setVisualStartPage] = useState<boolean>();
|
||||
@ -56,8 +56,8 @@ useEffect(() => {
|
||||
if (visualStartPage === undefined) return <></>
|
||||
return (
|
||||
<Box>
|
||||
{visualStartPage ? (
|
||||
<StartPageViewPublication setVisualStartPage={setVisualStartPage}/>
|
||||
{!visualStartPage ? (
|
||||
<StartPageViewPublication setVisualStartPage={setVisualStartPage} />
|
||||
) : (
|
||||
<Question questions={filteredQuestions} />
|
||||
)}
|
||||
|
@ -156,7 +156,7 @@ export default function QuizCard({
|
||||
anchorOrigin={{ vertical: "top", horizontal: "right" }}
|
||||
>
|
||||
<Box onClick={() => setSubMenuOpen(false)}>
|
||||
<Button
|
||||
{/* <Button
|
||||
sx={{
|
||||
display: "block",
|
||||
width: "100%",
|
||||
@ -165,7 +165,7 @@ export default function QuizCard({
|
||||
onClick={()=>{}}
|
||||
>
|
||||
Копировать
|
||||
</Button>
|
||||
</Button> */}
|
||||
<Button
|
||||
sx={{
|
||||
display: "block",
|
||||
|
@ -146,7 +146,7 @@ export const deleteQuestionWithTimeout = (questionId: string, deleteFn: (questio
|
||||
const question = state.questions.find(q => q.id === questionId);
|
||||
if (!question) return;
|
||||
if (question.type === null || question.type === "result") {
|
||||
deleteFn(questionId);
|
||||
queueMicrotask(() => deleteFn(questionId));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -479,7 +479,6 @@ export const getQuestionByContentId = (questionContentId: string | null) => {
|
||||
}) || null;
|
||||
};
|
||||
|
||||
export const updateOpenedModalSettingsId = (id?: string) => useUiTools.setState({ openedModalSettingsId: id ? id : null });
|
||||
|
||||
|
||||
export const clearRuleForAll = () => {
|
||||
|
@ -28,4 +28,7 @@ export const clearDesireToOpenABranchingModal = () => {
|
||||
|
||||
export const updateEditSomeQuestion = (contentId?: string) => {
|
||||
useUiTools.setState({ editSomeQuestion: contentId === undefined ? null : contentId });
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
export const updateOpenedModalSettingsId = (id?: string) => useUiTools.setState({ openedModalSettingsId: id ? id : null });
|
9
src/ui_kit/PrivateRoute.tsx
Normal file
9
src/ui_kit/PrivateRoute.tsx
Normal file
@ -0,0 +1,9 @@
|
||||
import { useUserStore } from "@root/user";
|
||||
import { Navigate, Outlet } from "react-router-dom"
|
||||
|
||||
|
||||
export default function PrivateRoute() {
|
||||
const user = useUserStore(state => state.user)
|
||||
|
||||
return user ? <Outlet /> : <Navigate to="/" replace />
|
||||
}
|
Loading…
Reference in New Issue
Block a user