124 lines
4.2 KiB
TypeScript
124 lines
4.2 KiB
TypeScript
'use client'
|
||
|
||
import { useState } from 'react'
|
||
import { Navigation } from '@/components/shared/Navigation'
|
||
import { VocabChoiceTest } from '@/components/review/simple/VocabChoiceTest'
|
||
import { SIMPLE_CARDS, CardState } from '@/lib/data/reviewSimpleData'
|
||
|
||
export default function TestVocabChoicePage() {
|
||
const [currentCardIndex, setCurrentCardIndex] = useState(0)
|
||
const [score, setScore] = useState({ correct: 0, total: 0 })
|
||
|
||
const currentCard = SIMPLE_CARDS[currentCardIndex]
|
||
|
||
// 生成測驗選項 (包含正確答案和3個干擾項)
|
||
const generateOptions = (correctWord: string) => {
|
||
const allWords = SIMPLE_CARDS.map(card => card.word).filter(word => word !== correctWord)
|
||
const shuffledWords = allWords.sort(() => Math.random() - 0.5)
|
||
const distractors = shuffledWords.slice(0, 3)
|
||
|
||
const options = [correctWord, ...distractors]
|
||
return options.sort(() => Math.random() - 0.5) // 隨機排列選項
|
||
}
|
||
|
||
const handleAnswer = (confidence: number) => {
|
||
const isCorrect = confidence >= 2
|
||
setScore(prev => ({
|
||
correct: prev.correct + (isCorrect ? 1 : 0),
|
||
total: prev.total + 1
|
||
}))
|
||
|
||
// 移動到下一張卡片
|
||
setTimeout(() => {
|
||
if (currentCardIndex < SIMPLE_CARDS.length - 1) {
|
||
setCurrentCardIndex(prev => prev + 1)
|
||
} else {
|
||
alert(`測試完成!正確率: ${score.correct + (isCorrect ? 1 : 0)}/${score.total + 1}`)
|
||
}
|
||
}, 100)
|
||
}
|
||
|
||
const handleSkip = () => {
|
||
setScore(prev => ({ ...prev, total: prev.total + 1 }))
|
||
|
||
if (currentCardIndex < SIMPLE_CARDS.length - 1) {
|
||
setCurrentCardIndex(prev => prev + 1)
|
||
} else {
|
||
alert(`測試完成!正確率: ${score.correct}/${score.total + 1}`)
|
||
}
|
||
}
|
||
|
||
const handleRestart = () => {
|
||
setCurrentCardIndex(0)
|
||
setScore({ correct: 0, total: 0 })
|
||
}
|
||
|
||
if (!currentCard) {
|
||
return (
|
||
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100">
|
||
<Navigation />
|
||
<div className="py-8">
|
||
<div className="max-w-4xl mx-auto px-4 text-center">
|
||
<h1 className="text-2xl font-bold mb-4">測試完成!</h1>
|
||
<button
|
||
onClick={handleRestart}
|
||
className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
|
||
>
|
||
重新開始
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
return (
|
||
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100">
|
||
<Navigation />
|
||
|
||
<div className="py-8">
|
||
<div className="max-w-4xl mx-auto px-4">
|
||
{/* 進度顯示 */}
|
||
<div className="mb-6 bg-white rounded-lg shadow p-4">
|
||
<div className="flex justify-between items-center">
|
||
<h1 className="text-xl font-bold">詞彙選擇測驗</h1>
|
||
<div className="text-sm text-gray-600">
|
||
第 {currentCardIndex + 1} / {SIMPLE_CARDS.length} 題
|
||
</div>
|
||
</div>
|
||
<div className="mt-2">
|
||
<div className="text-sm text-gray-600 mb-1">
|
||
得分: {score.correct} / {score.total}
|
||
{score.total > 0 && ` (${Math.round(score.correct / score.total * 100)}%)`}
|
||
</div>
|
||
<div className="w-full bg-gray-200 rounded-full h-2">
|
||
<div
|
||
className="bg-blue-600 h-2 rounded-full transition-all duration-300"
|
||
style={{ width: `${((currentCardIndex) / SIMPLE_CARDS.length) * 100}%` }}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* 測驗組件 */}
|
||
<VocabChoiceTest
|
||
card={currentCard}
|
||
options={generateOptions(currentCard.word)}
|
||
onAnswer={handleAnswer}
|
||
onSkip={handleSkip}
|
||
/>
|
||
|
||
{/* 控制按鈕 */}
|
||
<div className="mt-6 text-center">
|
||
<button
|
||
onClick={handleRestart}
|
||
className="px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600 mr-4"
|
||
>
|
||
重新開始
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
} |