87 lines
2.4 KiB
TypeScript
87 lines
2.4 KiB
TypeScript
import React, { useState, useCallback, useMemo, memo } from 'react'
|
||
import { ChoiceTestProps } from '@/types/review'
|
||
import {
|
||
TestResultDisplay,
|
||
ChoiceTestContainer,
|
||
ChoiceGrid
|
||
} from '@/components/review/shared'
|
||
|
||
interface VocabChoiceTestProps extends ChoiceTestProps {}
|
||
|
||
const VocabChoiceTestComponent: React.FC<VocabChoiceTestProps> = ({
|
||
cardData,
|
||
options,
|
||
onAnswer,
|
||
onReportError,
|
||
disabled = false
|
||
}) => {
|
||
const [selectedAnswer, setSelectedAnswer] = useState<string | null>(null)
|
||
const [showResult, setShowResult] = useState(false)
|
||
|
||
|
||
const handleAnswerSelect = useCallback((answer: string) => {
|
||
if (disabled || showResult) return
|
||
setSelectedAnswer(answer)
|
||
setShowResult(true)
|
||
onAnswer(answer)
|
||
}, [disabled, showResult, onAnswer])
|
||
|
||
const isCorrect = useMemo(() =>
|
||
selectedAnswer === cardData.word
|
||
, [selectedAnswer, cardData.word])
|
||
|
||
// 問題顯示區域
|
||
const questionArea = (
|
||
<div className="text-center">
|
||
<div className="bg-gray-50 rounded-lg p-6">
|
||
<h3 className="font-semibold text-gray-900 mb-3 text-left">定義</h3>
|
||
<p className="text-gray-700 text-left text-lg leading-relaxed">{cardData.definition}</p>
|
||
</div>
|
||
<p className="text-lg text-gray-700 mt-4 text-left">
|
||
請選擇符合上述定義的英文詞彙:
|
||
</p>
|
||
</div>
|
||
)
|
||
|
||
// 選項區域
|
||
const optionsArea = (
|
||
<ChoiceGrid
|
||
options={options}
|
||
selectedOption={selectedAnswer}
|
||
correctAnswer={cardData.word}
|
||
showResult={showResult}
|
||
onSelect={handleAnswerSelect}
|
||
disabled={disabled}
|
||
/>
|
||
)
|
||
|
||
// 結果顯示區域
|
||
const resultArea = showResult ? (
|
||
<TestResultDisplay
|
||
isCorrect={isCorrect}
|
||
correctAnswer={cardData.word}
|
||
userAnswer={selectedAnswer || ''}
|
||
word={cardData.word}
|
||
pronunciation={cardData.pronunciation}
|
||
example={cardData.example}
|
||
exampleTranslation={cardData.exampleTranslation}
|
||
showResult={showResult}
|
||
/>
|
||
) : null
|
||
|
||
return (
|
||
<ChoiceTestContainer
|
||
cardData={cardData}
|
||
testTitle="詞彙選擇"
|
||
questionArea={questionArea}
|
||
optionsArea={optionsArea}
|
||
resultArea={resultArea}
|
||
onAnswer={onAnswer}
|
||
onReportError={onReportError}
|
||
disabled={disabled}
|
||
/>
|
||
)
|
||
}
|
||
|
||
export const VocabChoiceTest = memo(VocabChoiceTestComponent)
|
||
VocabChoiceTest.displayName = 'VocabChoiceTest' |