92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
import { useState, useCallback, useRef } from 'react'
|
|
import { ReviewCardData, AnswerFeedback, ConfidenceLevel, ReviewResult } from '@/types/review'
|
|
|
|
interface UseReviewLogicProps {
|
|
cardData: ReviewCardData
|
|
testType: string
|
|
}
|
|
|
|
export const useReviewLogic = ({ cardData, testType }: UseReviewLogicProps) => {
|
|
// 共用狀態
|
|
const [userAnswer, setUserAnswer] = useState<string>('')
|
|
const [feedback, setFeedback] = useState<AnswerFeedback | null>(null)
|
|
const [isSubmitted, setIsSubmitted] = useState(false)
|
|
const [confidence, setConfidence] = useState<ConfidenceLevel | undefined>(undefined)
|
|
const [startTime] = useState(Date.now())
|
|
|
|
// 答案驗證邏輯
|
|
const validateAnswer = useCallback((answer: string): AnswerFeedback => {
|
|
const correctAnswer = cardData.word.toLowerCase()
|
|
const normalizedAnswer = answer.toLowerCase().trim()
|
|
|
|
// 檢查是否為正確答案或同義詞
|
|
const isCorrect = normalizedAnswer === correctAnswer ||
|
|
cardData.synonyms.some(synonym =>
|
|
synonym.toLowerCase() === normalizedAnswer)
|
|
|
|
return {
|
|
isCorrect,
|
|
userAnswer: answer,
|
|
correctAnswer: cardData.word,
|
|
explanation: isCorrect ?
|
|
'答案正確!' :
|
|
`正確答案是 "${cardData.word}"${cardData.synonyms.length > 0 ?
|
|
`,同義詞包括:${cardData.synonyms.join(', ')}` : ''}`
|
|
}
|
|
}, [cardData])
|
|
|
|
// 提交答案
|
|
const submitAnswer = useCallback((answer: string) => {
|
|
if (isSubmitted) return
|
|
|
|
const result = validateAnswer(answer)
|
|
setUserAnswer(answer)
|
|
setFeedback(result)
|
|
setIsSubmitted(true)
|
|
|
|
return result
|
|
}, [validateAnswer, isSubmitted])
|
|
|
|
// 提交信心度
|
|
const submitConfidence = useCallback((level: ConfidenceLevel) => {
|
|
setConfidence(level)
|
|
}, [])
|
|
|
|
// 生成測試結果
|
|
const generateResult = useCallback((): ReviewResult => {
|
|
return {
|
|
cardId: cardData.id,
|
|
testType,
|
|
isCorrect: feedback?.isCorrect ?? false,
|
|
confidence,
|
|
timeSpent: Math.round((Date.now() - startTime) / 1000),
|
|
userAnswer
|
|
}
|
|
}, [cardData.id, testType, feedback, confidence, startTime, userAnswer])
|
|
|
|
// 重置狀態
|
|
const reset = useCallback(() => {
|
|
setUserAnswer('')
|
|
setFeedback(null)
|
|
setIsSubmitted(false)
|
|
setConfidence(undefined)
|
|
}, [])
|
|
|
|
return {
|
|
// 狀態
|
|
userAnswer,
|
|
feedback,
|
|
isSubmitted,
|
|
confidence,
|
|
|
|
// 方法
|
|
setUserAnswer,
|
|
submitAnswer,
|
|
submitConfidence,
|
|
generateResult,
|
|
reset,
|
|
|
|
// 輔助方法
|
|
validateAnswer
|
|
}
|
|
} |