update flash card, test

This commit is contained in:
2026-04-15 00:41:02 +07:00
parent 4bc39225ab
commit 088c555515
32 changed files with 1988 additions and 415 deletions

View File

@@ -1,52 +1,66 @@
import { create } from 'zustand'
import { persist } from 'zustand/middleware'
import type { Question } from '@/types'
import type { SessionPart } from '@/types'
interface StartExamConfig {
testId: number | null
testName: string
parts: SessionPart[]
totalSeconds: number // 0 = no limit
}
interface TestStore {
partId: number
partName: string
questions: Question[]
answers: (number | null)[]
testId: number | null
testName: string
parts: SessionPart[]
currentPartIndex: number
answers: Record<number, number | null> // questionId → answerIndex (0-3), null=unanswered
isSubmitted: boolean
timeUsed: number // seconds elapsed when submitted
timeUsed: number // seconds elapsed when submitted
totalSeconds: number // time limit (0 = no limit)
startExam: (partId: number, partName: string, questions: Question[]) => void
setAnswer: (questionIndex: number, answerIndex: number) => void
startExam: (config: StartExamConfig) => void
setAnswer: (questionId: number, answerIndex: number) => void
setCurrentPart: (partIndex: number) => void
submitExam: (timeUsed: number) => void
reset: () => void
}
const INITIAL_STATE = {
testId: null,
testName: '',
parts: [],
currentPartIndex: 0,
answers: {},
isSubmitted: false,
timeUsed: 0,
totalSeconds: 0,
}
export const useTestStore = create<TestStore>()(
persist(
(set) => ({
partId: 2,
partName: '',
questions: [],
answers: [],
isSubmitted: false,
timeUsed: 0,
...INITIAL_STATE,
startExam: (partId, partName, questions) =>
set({
partId,
partName,
questions,
answers: new Array(questions.length).fill(null),
isSubmitted: false,
timeUsed: 0,
}),
startExam: ({ testId, testName, parts, totalSeconds }) => {
// Pre-fill all question IDs with null (unanswered)
const answers: Record<number, number | null> = {}
for (const part of parts) {
for (const q of part.questions) answers[q.id] = null
}
set({ testId, testName, parts, currentPartIndex: 0, answers, isSubmitted: false, timeUsed: 0, totalSeconds })
},
setAnswer: (questionIndex, answerIndex) =>
set((state) => {
const answers = [...state.answers]
answers[questionIndex] = answerIndex
return { answers }
}),
setAnswer: (questionId, answerIndex) =>
set((state) => ({
answers: { ...state.answers, [questionId]: answerIndex },
})),
setCurrentPart: (partIndex) => set({ currentPartIndex: partIndex }),
submitExam: (timeUsed) => set({ isSubmitted: true, timeUsed }),
reset: () =>
set({ partId: 2, partName: '', questions: [], answers: [], isSubmitted: false, timeUsed: 0 }),
reset: () => set(INITIAL_STATE),
}),
{ name: 'test-store' },
),