import React, { useState, useMemo, useCallback, memo } from 'react' import { getCorrectAnswer } from '@/utils/answerExtractor' import { ErrorReportButton, SentenceInput, TestResultDisplay, HintPanel } from '@/components/review/shared' import { FillTestProps } from '@/types/review' interface SentenceFillTestProps extends FillTestProps { // SentenceFillTest specific props (if any) } const SentenceFillTestComponent: React.FC = ({ cardData, onAnswer, onReportError, disabled = false }) => { const [fillAnswer, setFillAnswer] = useState('') const [showResult, setShowResult] = useState(false) const [showHint, setShowHint] = useState(false) const handleSubmit = useCallback(() => { if (disabled || showResult || !fillAnswer.trim()) return setShowResult(true) onAnswer(fillAnswer) }, [disabled, showResult, fillAnswer, onAnswer]) const handleToggleHint = useCallback(() => { setShowHint(prev => !prev) }, []) // 動態計算正確答案:從例句和挖空題目推導 const correctAnswer = useMemo(() => { return getCorrectAnswer(cardData.example, cardData.filledQuestionText, cardData.word) }, [cardData.example, cardData.filledQuestionText, cardData.word]) const isCorrect = useMemo(() => { return fillAnswer.toLowerCase().trim() === correctAnswer.toLowerCase().trim() }, [fillAnswer, correctAnswer]) // 統一的填空句子渲染邏輯 const renderFilledSentence = useCallback(() => { const text = cardData.filledQuestionText || cardData.example const isUsingFilledText = !!cardData.filledQuestionText if (isUsingFilledText) { // 使用後端提供的挖空題目 const parts = text.split('____') return (
{parts.map((part, index) => ( {part} {index < parts.length - 1 && ( )} ))}
) } else { // 降級處理:使用前端挖空邏輯 const parts = text.split(new RegExp(`\\b${cardData.word}\\b`, 'gi')) const matches = text.match(new RegExp(`\\b${cardData.word}\\b`, 'gi')) || [] return (
{parts.map((part, index) => ( {part} {index < matches.length && ( )} ))}
) } }, [ cardData.filledQuestionText, cardData.example, cardData.word, fillAnswer, handleSubmit, disabled, showResult, correctAnswer.length ]) return (
{/* 標題區 */}

例句填空

{cardData.difficultyLevel}
{/* 圖片區(如果有) */} {cardData.exampleImage && (
Example illustration { // 這裡需要處理圖片點擊,但我們暫時移除 onImageClick // 因為新的 cardData 接口可能不包含這個功能 }} />
)} {/* 指示文字 */}

請點擊例句中的空白處輸入正確的單字:

{/* 填空句子區域 */}
{renderFilledSentence()}
{/* 操作按鈕 */}
{/* 提示區域 */} {/* 結果反饋區 */}
) } export const SentenceFillTest = memo(SentenceFillTestComponent) SentenceFillTest.displayName = 'SentenceFillTest'