import { QuestionVariant } from "@model/questionTypes/shared"; import { QuizStep } from "@model/settingsData"; import type { Moment } from "moment"; import { nanoid } from "nanoid"; import { createContext, useContext } from "react"; import { createStore, useStore } from "zustand"; import { immer } from "zustand/middleware/immer"; export type Answer = string | string[] | Moment; type QuestionAnswer = { questionId: string; answer: Answer; }; type OwnVariant = { id: string; variant: QuestionVariant; }; interface QuizViewStore { answers: QuestionAnswer[]; ownVariants: OwnVariant[]; pointsSum: number; points: Record; currentQuizStep: QuizStep; } interface QuizViewActions { updateAnswer: (questionId: string, answer: string | string[] | Moment, points: number) => void; deleteAnswer: (questionId: string) => void; updateOwnVariant: (id: string, answer: string) => void; deleteOwnVariant: (id: string) => void; setCurrentQuizStep: (step: QuizStep) => void; } export const QuizViewContext = createContext | null>(null); export function useQuizViewStore(selector: (state: QuizViewStore & QuizViewActions) => U): U { const store = useContext(QuizViewContext); if (!store) throw new Error("QuizViewStore context is null"); return useStore(store, selector); } export const createQuizViewStore = () => createStore()( immer((set, get) => ({ answers: [], ownVariants: [], points: {}, pointsSum: 0, currentQuizStep: "startpage", updateAnswer(questionId, answer, points) { set((state) => { const index = state.answers.findIndex((answer) => questionId === answer.questionId); if (index < 0) { state.answers.push({ questionId, answer }); } else { state.answers[index] = { questionId, answer }; } state.points = { ...state.points, ...{ [questionId]: points } }; state.pointsSum = Object.values(state.points).reduce((sum, value) => sum + value); }); }, deleteAnswer(questionId) { set((state) => { state.answers = state.answers.filter((answer) => questionId !== answer.questionId); }); }, updateOwnVariant(id, answer) { set((state) => { const index = state.ownVariants.findIndex((variant) => variant.id === id); if (index < 0) { state.ownVariants.push({ id, variant: { id: nanoid(), answer, extendedText: "", hints: "", originalImageUrl: "", }, }); } else { state.ownVariants[index].variant.answer = answer; } }); }, deleteOwnVariant(id) { set((state) => { state.ownVariants = state.ownVariants.filter((variant) => variant.id !== id); }); }, setCurrentQuizStep(step) { set({ currentQuizStep: step }); }, })) );