dramaling-vocab-learning/frontend/store/review/useTestResultStore.ts

123 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { create } from 'zustand'
import { subscribeWithSelector } from 'zustand/middleware'
import { flashcardsService } from '@/lib/services/flashcards'
import { ReviewMode } from './useTestQueueStore'
import { isTestMode } from '@/lib/mock/reviewMockData'
// 測試結果狀態接口
interface TestResultState {
// 分數狀態
score: { correct: number; total: number }
// 測試進行狀態
isRecordingResult: boolean
recordingError: string | null
// Actions
updateScore: (isCorrect: boolean) => void
resetScore: () => void
recordTestResult: (params: {
flashcardId: string
testType: ReviewMode
isCorrect: boolean
userAnswer?: string
confidenceLevel?: number
responseTimeMs?: number
}) => Promise<boolean>
setRecordingResult: (isRecording: boolean) => void
setRecordingError: (error: string | null) => void
// 統計方法
getAccuracyPercentage: () => number
getTotalAttempts: () => number
}
export const useTestResultStore = create<TestResultState>()(
subscribeWithSelector((set, get) => ({
// 初始狀態
score: { correct: 0, total: 0 },
isRecordingResult: false,
recordingError: null,
// Actions
updateScore: (isCorrect) => {
set(state => ({
score: {
correct: isCorrect ? state.score.correct + 1 : state.score.correct,
total: state.score.total + 1
}
}))
},
resetScore: () => set({
score: { correct: 0, total: 0 },
recordingError: null
}),
recordTestResult: async (params) => {
const { setRecordingResult, setRecordingError } = get()
try {
setRecordingResult(true)
setRecordingError(null)
console.log('🔄 開始記錄測驗結果...', {
flashcardId: params.flashcardId,
testType: params.testType,
isCorrect: params.isCorrect
})
// 🧪 測試模式:跳過 API 呼叫
if (isTestMode()) {
console.log('🧪 [測試模式] 跳過API呼叫直接返回成功')
// 模擬API延遲
await new Promise(resolve => setTimeout(resolve, 200))
console.log('✅ [測試模式] 測驗結果已記錄 (模擬)')
return true
}
// 🌐 正常模式:呼叫後端 API
const result = await flashcardsService.recordTestCompletion({
flashcardId: params.flashcardId,
testType: params.testType,
isCorrect: params.isCorrect,
userAnswer: params.userAnswer,
confidenceLevel: params.confidenceLevel,
responseTimeMs: params.responseTimeMs || 2000
})
if (result.success) {
console.log('✅ 測驗結果已記錄')
return true
} else {
console.error('❌ 記錄測驗結果失敗:', result.error)
setRecordingError('記錄測驗結果失敗')
return false
}
} catch (error) {
console.error('💥 記錄測驗結果異常:', error)
setRecordingError('記錄測驗結果異常')
return false
} finally {
setRecordingResult(false)
}
},
setRecordingResult: (isRecording) => set({ isRecordingResult: isRecording }),
setRecordingError: (error) => set({ recordingError: error }),
// 統計方法
getAccuracyPercentage: () => {
const { score } = get()
return score.total > 0 ? Math.round((score.correct / score.total) * 100) : 0
},
getTotalAttempts: () => {
const { score } = get()
return score.total
}
}))
)