Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | 1x 1x 1x 1x 1x 1x 8x 20x 20x 20x 20x 20x 6x 6x 6x 6x 4x 4x 2x 2x 2x 4x 6x 20x 16x 15x 14x | 'use client'
import { useState, useCallback } from 'react'
import { VocabularyItem } from '@/core/domain/VocabularyItem'
import { useQuiz } from '@/hooks/useQuiz'
import { MemorizationPhase } from './MemorizationPhase'
import { QuizPhase } from './QuizPhase'
import { ResultsPhase } from './ResultsPhase'
import { LoadingSpinner, ErrorMessage } from '@/components/ui'
interface VocabularyAppProps {
initialVocabulary: VocabularyItem[]
}
/**
* VocabularyApp Component
* Main application component managing the vocabulary learning flow.
*/
export function VocabularyApp({ initialVocabulary }: VocabularyAppProps) {
const [vocabulary, setVocabulary] = useState(initialVocabulary)
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const {
phase,
session,
currentQuestion,
shuffledOptions,
resultMessage,
startQuiz,
submitAnswer,
resetQuiz,
} = useQuiz(vocabulary)
const handleTryAgain = useCallback(async () => {
setIsLoading(true)
setError(null)
try {
const response = await fetch('/api/vocabulary')
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to fetch vocabulary')
}
setVocabulary(data.data)
resetQuiz()
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred')
} finally {
setIsLoading(false)
}
}, [resetQuiz])
if (error) {
return <ErrorMessage message={error} onRetry={handleTryAgain} />
}
if (phase === 'memorization') {
return (
<MemorizationPhase
vocabularyItems={vocabulary}
onStartQuiz={startQuiz}
/>
)
}
if (phase === 'quiz' && session && currentQuestion) {
return (
<QuizPhase
session={session}
currentQuestion={currentQuestion}
shuffledOptions={shuffledOptions}
onAnswer={submitAnswer}
/>
)
}
if (phase === 'results' && session) {
return (
<ResultsPhase
session={session}
resultMessage={resultMessage}
onTryAgain={handleTryAgain}
isLoading={isLoading}
/>
)
}
return <LoadingSpinner message="Loading quiz..." />
}
|