refactor store & hooks
This commit is contained in:
parent
a3b2adf0c6
commit
213075706b
@ -42,7 +42,7 @@ export default function StartPage() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const quiz = useCurrentQuiz();
|
const { quiz } = useCurrentQuiz();
|
||||||
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));
|
||||||
|
|||||||
@ -9,10 +9,10 @@ import { useCurrentQuiz } from "@root/quizes/hooks";
|
|||||||
|
|
||||||
export default function StepOne() {
|
export default function StepOne() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const quiz = useCurrentQuiz();
|
const { quiz } = useCurrentQuiz();
|
||||||
const config = quiz?.config;
|
const config = quiz?.config;
|
||||||
|
|
||||||
if (!config) return null;
|
if (!config) return null; // TODO throw and catch with error boundary
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@ -51,7 +51,7 @@ export default function StepOne() {
|
|||||||
<Button
|
<Button
|
||||||
variant="text"
|
variant="text"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setQuizType(quiz.id,"form", navigate);
|
setQuizType(quiz.id, "form", navigate);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CreationCard
|
<CreationCard
|
||||||
|
|||||||
@ -18,11 +18,11 @@ export default function Steptwo() {
|
|||||||
const navigate = useNavigate();
|
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();
|
||||||
|
|
||||||
const config = quiz?.config;
|
const config = quiz?.config;
|
||||||
|
|
||||||
if (!config) return null;
|
if (!config) return null; // TODO throw and catch with error boundary
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ mt: "60px" }}>
|
<Box sx={{ mt: "60px" }}>
|
||||||
|
|||||||
@ -42,7 +42,13 @@ export const setQuizField = <T extends keyof Quiz>(
|
|||||||
const quiz = state.quizById[quizId];
|
const quiz = state.quizById[quizId];
|
||||||
if (!quiz) return;
|
if (!quiz) return;
|
||||||
|
|
||||||
|
const oldId = quiz.id;
|
||||||
quiz[field] = value;
|
quiz[field] = value;
|
||||||
|
|
||||||
|
if (field === "id") {
|
||||||
|
delete state.quizById[oldId];
|
||||||
|
state.quizById[value as number] = quiz;
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
type: "setQuizField",
|
type: "setQuizField",
|
||||||
quizId,
|
quizId,
|
||||||
@ -68,12 +74,16 @@ export const incrementCurrentStep = () => setProducedState(state => {
|
|||||||
state.currentStep = Math.min(
|
state.currentStep = Math.min(
|
||||||
maxQuizSetupSteps, state.currentStep + 1
|
maxQuizSetupSteps, state.currentStep + 1
|
||||||
) as QuizSetupStep;
|
) as QuizSetupStep;
|
||||||
|
}, {
|
||||||
|
type: "incrementCurrentStep",
|
||||||
});
|
});
|
||||||
|
|
||||||
export const decrementCurrentStep = () => setProducedState(state => {
|
export const decrementCurrentStep = () => setProducedState(state => {
|
||||||
state.currentStep = Math.max(
|
state.currentStep = Math.max(
|
||||||
1, state.currentStep - 1
|
1, state.currentStep - 1
|
||||||
) as QuizSetupStep;
|
) as QuizSetupStep;
|
||||||
|
}, {
|
||||||
|
type: "decrementCurrentStep",
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setCurrentStep = (step: number) => setProducedState(state => {
|
export const setCurrentStep = (step: number) => setProducedState(state => {
|
||||||
@ -126,7 +136,7 @@ export const setQuizType = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const setQuizStartpageType = (
|
export const setQuizStartpageType = (
|
||||||
quizId: number,
|
quizId: number | undefined,
|
||||||
startpageType: QuizConfig["startpageType"],
|
startpageType: QuizConfig["startpageType"],
|
||||||
navigate: NavigateFunction,
|
navigate: NavigateFunction,
|
||||||
) => {
|
) => {
|
||||||
@ -144,11 +154,13 @@ 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,
|
quizId: number | undefined,
|
||||||
updateFn: (quiz: Quiz) => void,
|
updateFn: (quiz: Quiz) => void,
|
||||||
navigate: NavigateFunction,
|
navigate: NavigateFunction,
|
||||||
rollbackOnError = true,
|
rollbackOnError = true,
|
||||||
) => {
|
) => {
|
||||||
|
if (!quizId) return;
|
||||||
|
|
||||||
const quiz = useQuizStore.getState().quizById[quizId] ?? null;
|
const quiz = useQuizStore.getState().quizById[quizId] ?? null;
|
||||||
if (!quiz) return;
|
if (!quiz) return;
|
||||||
|
|
||||||
@ -160,11 +172,11 @@ export const updateQuizWithFnOptimistic = async (
|
|||||||
|
|
||||||
setQuiz(currentUpdatedQuiz);
|
setQuiz(currentUpdatedQuiz);
|
||||||
try {
|
try {
|
||||||
const { updated } = await quizApi.edit(quizToEditQuizRequest(currentUpdatedQuiz), controller.signal);
|
const { updated: newId } = await quizApi.edit(quizToEditQuizRequest(currentUpdatedQuiz), controller.signal);
|
||||||
// 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, "version", updated);
|
setQuizField(quiz.id, "id", newId);
|
||||||
navigate(`/setting/${quizId}`, { replace: true });
|
navigate(`/setting/${newId}`, { replace: true });
|
||||||
|
|
||||||
controller = null;
|
controller = null;
|
||||||
savedOriginalQuiz = null;
|
savedOriginalQuiz = null;
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import { Quiz } from "@model/quiz/quiz";
|
import { Quiz } from "@model/quiz/quiz";
|
||||||
import { useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import { useQuizStore } from "./store";
|
import { useQuizStore } from "./store";
|
||||||
|
import { useCallback } from "react";
|
||||||
|
import { updateQuizWithFnOptimistic } from "./actions";
|
||||||
|
|
||||||
|
|
||||||
export function useQuizArray(): Quiz[] {
|
export function useQuizArray(): Quiz[] {
|
||||||
@ -10,8 +12,13 @@ export function useQuizArray(): Quiz[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useCurrentQuiz() {
|
export function useCurrentQuiz() {
|
||||||
|
const navigate = useNavigate();
|
||||||
const quizId = parseInt(useParams().quizId ?? "");
|
const quizId = parseInt(useParams().quizId ?? "");
|
||||||
const quiz = useQuizStore(state => state.quizById[quizId]);
|
const quiz = useQuizStore(state => state.quizById[quizId]);
|
||||||
|
|
||||||
return quiz;
|
const updateQuiz = useCallback((updateFn: (quiz: Quiz) => void) => {
|
||||||
|
updateQuizWithFnOptimistic(quizId, updateFn, navigate);
|
||||||
|
}, [navigate, quizId]);
|
||||||
|
|
||||||
|
return { quiz, updateQuiz };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ export const useQuizStore = create<QuizStore>()(
|
|||||||
{
|
{
|
||||||
name: "QuizStore",
|
name: "QuizStore",
|
||||||
enabled: process.env.NODE_ENV === "development",
|
enabled: process.env.NODE_ENV === "development",
|
||||||
|
trace: process.env.NODE_ENV === "development",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user