remove quiz id from url when editing

This commit is contained in:
nflnkr 2023-11-14 16:37:20 +03:00
parent 28d8cc8320
commit ac0104620c
7 changed files with 24 additions and 28 deletions

@ -56,7 +56,7 @@ export default function App() {
{routeslink.map((e, i) => ( {routeslink.map((e, i) => (
<Route key={i} path={e.path} element={<Main page={e.page} header={e.header} sidebar={e.sidebar} />} /> <Route key={i} path={e.path} element={<Main page={e.page} header={e.header} sidebar={e.sidebar} />} />
))} ))}
<Route path="setting/:quizId" element={<StartPage />} /> <Route path="settings" element={<StartPage />} />
<Route path="crop" element={<ImageCrop />} /> <Route path="crop" element={<ImageCrop />} />
<Route path="/" element={<Landing />} /> <Route path="/" element={<Landing />} />
<Route path="/signin" element={<SigninDialog />} /> <Route path="/signin" element={<SigninDialog />} />

@ -11,7 +11,7 @@ import {
useMediaQuery, useMediaQuery,
useTheme, useTheme,
} from "@mui/material"; } from "@mui/material";
import { deleteQuiz } from "@root/quizes/actions"; import { deleteQuiz, setEditQuizId } from "@root/quizes/actions";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
@ -33,7 +33,8 @@ export default function QuizCard({
const navigate = useNavigate(); const navigate = useNavigate();
function handleEditClick() { function handleEditClick() {
navigate(`/setting/${quiz.id}`); setEditQuizId(quiz.id);
navigate("/settings");
} }
return ( return (

@ -1,6 +1,5 @@
import { Box, Button } from "@mui/material"; import { Box, Button } from "@mui/material";
import CreationCard from "@ui_kit/CreationCard"; import CreationCard from "@ui_kit/CreationCard";
import { useNavigate } from "react-router-dom";
import quizCreationImage1 from "../../assets/quiz-creation-1.png"; import quizCreationImage1 from "../../assets/quiz-creation-1.png";
import quizCreationImage2 from "../../assets/quiz-creation-2.png"; import quizCreationImage2 from "../../assets/quiz-creation-2.png";
import { setQuizType } from "@root/quizes/actions"; import { setQuizType } from "@root/quizes/actions";
@ -8,7 +7,6 @@ import { useCurrentQuiz } from "@root/quizes/hooks";
export default function StepOne() { export default function StepOne() {
const navigate = useNavigate();
const { quiz } = useCurrentQuiz(); const { quiz } = useCurrentQuiz();
const config = quiz?.config; const config = quiz?.config;
@ -34,7 +32,7 @@ export default function StepOne() {
variant="text" variant="text"
data-cy="create-quiz-card" data-cy="create-quiz-card"
onClick={() => { onClick={() => {
setQuizType(quiz.id, "quiz", navigate); setQuizType(quiz.id, "quiz");
}} }}
> >
<CreationCard <CreationCard
@ -51,7 +49,7 @@ export default function StepOne() {
<Button <Button
variant="text" variant="text"
onClick={() => { onClick={() => {
setQuizType(quiz.id, "form", navigate); setQuizType(quiz.id, "form");
}} }}
> >
<CreationCard <CreationCard

@ -7,7 +7,6 @@ import {
} from "@mui/material"; } from "@mui/material";
import { setQuizStartpageType } from "@root/quizes/actions"; import { setQuizStartpageType } from "@root/quizes/actions";
import { useCurrentQuiz } from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";
import { useNavigate } from "react-router-dom";
import cardImage1 from "../../assets/card-1.png"; import cardImage1 from "../../assets/card-1.png";
import cardImage2 from "../../assets/card-2.png"; import cardImage2 from "../../assets/card-2.png";
import cardImage3 from "../../assets/card-3.png"; import cardImage3 from "../../assets/card-3.png";
@ -15,7 +14,6 @@ import CardWithImage from "./CardWithImage";
export default function Steptwo() { export default function Steptwo() {
const navigate = useNavigate();
const theme = useTheme(); const theme = useTheme();
const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1300)); const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1300));
const { quiz } = useCurrentQuiz(); const { quiz } = useCurrentQuiz();
@ -47,7 +45,7 @@ export default function Steptwo() {
variant="text" variant="text"
data-cy="select-quiz-layout-standard" data-cy="select-quiz-layout-standard"
onClick={() => { onClick={() => {
setQuizStartpageType(quiz.id, "standard", navigate); setQuizStartpageType(quiz.id, "standard");
}} }}
> >
<CardWithImage <CardWithImage
@ -63,7 +61,7 @@ export default function Steptwo() {
<Button <Button
variant="text" variant="text"
onClick={() => { onClick={() => {
setQuizStartpageType(quiz.id, "expanded", navigate); setQuizStartpageType(quiz.id, "expanded");
}} }}
> >
<CardWithImage <CardWithImage
@ -79,7 +77,7 @@ export default function Steptwo() {
<Button <Button
variant="text" variant="text"
onClick={() => { onClick={() => {
setQuizStartpageType(quiz.id, "centered", navigate); setQuizStartpageType(quiz.id, "centered");
}} }}
> >
<CardWithImage <CardWithImage

@ -10,6 +10,10 @@ import { QuizStore, useQuizStore } from "./store";
import { isAxiosCanceledError } from "../../utils/isAxiosCanceledError"; import { isAxiosCanceledError } from "../../utils/isAxiosCanceledError";
export const setEditQuizId = (quizId: number | null) => setProducedState(state => {
state.editQuizId = quizId;
});
export const setQuizes = (quizes: RawQuiz[] | null) => setProducedState(state => { export const setQuizes = (quizes: RawQuiz[] | null) => setProducedState(state => {
state.quizById = {}; state.quizById = {};
if (quizes === null) return; if (quizes === null) return;
@ -98,7 +102,8 @@ export const createQuiz = async (navigate: NavigateFunction) => {
}); });
setQuiz(rawQuizToQuiz(quiz)); setQuiz(rawQuizToQuiz(quiz));
navigate(`/setting/${quiz.id}`); setEditQuizId(quiz.id);
navigate("/settings");
} catch (error) { } catch (error) {
devlog("Error creating quiz", error); devlog("Error creating quiz", error);
@ -123,29 +128,25 @@ export const deleteQuiz = async (quizId: number) => {
export const setQuizType = ( export const setQuizType = (
quizId: number, quizId: number,
quizType: QuizConfig["type"], quizType: QuizConfig["type"],
navigate: NavigateFunction,
) => { ) => {
updateQuizWithFnOptimistic( updateQuizWithFnOptimistic(
quizId, quizId,
quiz => { quiz => {
quiz.config.type = quizType; quiz.config.type = quizType;
}, },
navigate,
); );
incrementCurrentStep(); incrementCurrentStep();
}; };
export const setQuizStartpageType = ( export const setQuizStartpageType = (
quizId: number | undefined, quizId: number | null,
startpageType: QuizConfig["startpageType"], startpageType: QuizConfig["startpageType"],
navigate: NavigateFunction,
) => { ) => {
updateQuizWithFnOptimistic( updateQuizWithFnOptimistic(
quizId, quizId,
quiz => { quiz => {
quiz.config.startpageType = startpageType; quiz.config.startpageType = startpageType;
}, },
navigate,
); );
incrementCurrentStep(); incrementCurrentStep();
}; };
@ -154,9 +155,8 @@ let savedOriginalQuiz: Quiz | null = null;
let controller: AbortController | null = null; let controller: AbortController | null = null;
export const updateQuizWithFnOptimistic = async ( export const updateQuizWithFnOptimistic = async (
quizId: number | undefined, quizId: number | null,
updateFn: (quiz: Quiz) => void, updateFn: (quiz: Quiz) => void,
navigate: NavigateFunction,
rollbackOnError = true, rollbackOnError = true,
) => { ) => {
if (!quizId) return; if (!quizId) return;
@ -176,7 +176,6 @@ export const updateQuizWithFnOptimistic = async (
// await new Promise((resolve, reject) => setTimeout(reject, 2000, new Error("Api rejected"))); // await new Promise((resolve, reject) => setTimeout(reject, 2000, new Error("Api rejected")));
setQuizField(quiz.id, "id", newId); setQuizField(quiz.id, "id", newId);
navigate(`/setting/${newId}`, { replace: true });
controller = null; controller = null;
savedOriginalQuiz = null; savedOriginalQuiz = null;

@ -1,8 +1,7 @@
import { Quiz } from "@model/quiz/quiz"; import { Quiz } from "@model/quiz/quiz";
import { useNavigate, useParams } from "react-router-dom";
import { useQuizStore } from "./store";
import { useCallback } from "react"; import { useCallback } from "react";
import { updateQuizWithFnOptimistic } from "./actions"; import { updateQuizWithFnOptimistic } from "./actions";
import { useQuizStore } from "./store";
export function useQuizArray(): Quiz[] { export function useQuizArray(): Quiz[] {
@ -12,13 +11,12 @@ export function useQuizArray(): Quiz[] {
} }
export function useCurrentQuiz() { export function useCurrentQuiz() {
const navigate = useNavigate(); const quizId = useQuizStore(state => state.editQuizId);
const quizId = parseInt(useParams().quizId ?? ""); const quiz = useQuizStore(state => state.quizById[quizId ?? -1]);
const quiz = useQuizStore(state => state.quizById[quizId]);
const updateQuiz = useCallback((updateFn: (quiz: Quiz) => void) => { const updateQuiz = useCallback((updateFn: (quiz: Quiz) => void) => {
updateQuizWithFnOptimistic(quizId, updateFn, navigate); updateQuizWithFnOptimistic(quizId, updateFn);
}, [navigate, quizId]); }, [quizId]);
return { quiz, updateQuiz }; return { quiz, updateQuiz };
} }

@ -6,11 +6,13 @@ import { devtools } from "zustand/middleware";
export type QuizStore = { export type QuizStore = {
quizById: Record<number, Quiz | undefined>; quizById: Record<number, Quiz | undefined>;
editQuizId: number | null;
currentStep: QuizSetupStep; currentStep: QuizSetupStep;
}; };
const initialState: QuizStore = { const initialState: QuizStore = {
quizById: {}, quizById: {},
editQuizId: null,
currentStep: 1, currentStep: 1,
}; };