dramaling-vocab-learning/frontend/components/review/review-tests/VocabChoiceTest.tsx

102 lines
3.4 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 React, { useState, useCallback, useMemo, memo } from 'react'
import AudioPlayer from '@/components/AudioPlayer'
import { ChoiceTestProps } from '@/types/review'
import {
ErrorReportButton,
TestResultDisplay,
TestHeader
} from '@/components/review/shared'
interface VocabChoiceTestProps extends ChoiceTestProps {
// VocabChoiceTest specific props (if any)
}
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])
return (
<div className="relative">
<div className="flex justify-end mb-2">
<ErrorReportButton onClick={onReportError} />
</div>
<div className="bg-white rounded-xl shadow-lg p-8">
{/* 標題區 */}
<TestHeader
title="詞彙選擇"
difficultyLevel={cardData.difficultyLevel}
/>
{/* 指示文字 */}
<p className="text-lg text-gray-700 mb-6 text-left">
</p>
{/* 定義顯示區 */}
<div className="text-center mb-8">
<div className="bg-gray-50 rounded-lg p-4 mb-6">
<h3 className="font-semibold text-gray-900 mb-2 text-left"></h3>
<p className="text-gray-700 text-left">{cardData.definition}</p>
</div>
</div>
{/* 選項區域 - 響應式網格布局 */}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 mb-6">
{options.map((option, idx) => (
<button
key={idx}
onClick={() => handleAnswerSelect(option)}
disabled={disabled || showResult}
className={`p-4 text-center rounded-lg border-2 transition-all ${
showResult
? option === cardData.word
? 'border-green-500 bg-green-50 text-green-700'
: option === selectedAnswer
? 'border-red-500 bg-red-50 text-red-700'
: 'border-gray-200 bg-gray-50 text-gray-500'
: 'border-gray-200 hover:border-blue-300 hover:bg-blue-50'
}`}
>
<div className="text-lg font-medium">{option}</div>
</button>
))}
</div>
{/* 結果反饋區 */}
{showResult && (
<TestResultDisplay
isCorrect={isCorrect}
correctAnswer={cardData.word}
userAnswer={selectedAnswer || ''}
word={cardData.word}
pronunciation={cardData.pronunciation}
example={cardData.example}
exampleTranslation={cardData.exampleTranslation}
showResult={showResult}
/>
)}
</div>
</div>
)
}
export const VocabChoiceTest = memo(VocabChoiceTestComponent)
VocabChoiceTest.displayName = 'VocabChoiceTest'