123 lines
3.6 KiB
TypeScript
123 lines
3.6 KiB
TypeScript
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
|
||
}
|
||
}))
|
||
) |