diff --git a/frontend/app/dashboard/page.tsx b/frontend/app/dashboard/page.tsx index 9423dc7..468db0d 100644 --- a/frontend/app/dashboard/page.tsx +++ b/frontend/app/dashboard/page.tsx @@ -2,8 +2,8 @@ import Link from 'next/link' import { useState } from 'react' -import { ProtectedRoute } from '@/components/ProtectedRoute' -import { Navigation } from '@/components/Navigation' +import { ProtectedRoute } from '@/components/shared/ProtectedRoute' +import { Navigation } from '@/components/shared/Navigation' import { useAuth } from '@/contexts/AuthContext' function DashboardContent() { diff --git a/frontend/app/flashcards/[id]/page.tsx b/frontend/app/flashcards/[id]/page.tsx index 19e5df9..67f33c0 100644 --- a/frontend/app/flashcards/[id]/page.tsx +++ b/frontend/app/flashcards/[id]/page.tsx @@ -2,9 +2,9 @@ import { useState, useEffect, use } from 'react' import { useRouter, useSearchParams } from 'next/navigation' -import { Navigation } from '@/components/Navigation' -import { ProtectedRoute } from '@/components/ProtectedRoute' -import { useToast } from '@/components/Toast' +import { Navigation } from '@/components/shared/Navigation' +import { ProtectedRoute } from '@/components/shared/ProtectedRoute' +import { useToast } from '@/components/shared/Toast' import { flashcardsService, type Flashcard } from '@/lib/services/flashcards' import { imageGenerationService } from '@/lib/services/imageGeneration' diff --git a/frontend/app/flashcards/page.tsx b/frontend/app/flashcards/page.tsx index 165b88f..f3c02be 100644 --- a/frontend/app/flashcards/page.tsx +++ b/frontend/app/flashcards/page.tsx @@ -3,13 +3,13 @@ import { useState, useEffect } from 'react' import Link from 'next/link' import { useRouter } from 'next/navigation' -import { ProtectedRoute } from '@/components/ProtectedRoute' -import { Navigation } from '@/components/Navigation' -import { FlashcardForm } from '@/components/FlashcardForm' -import { useToast } from '@/components/Toast' +import { ProtectedRoute } from '@/components/shared/ProtectedRoute' +import { Navigation } from '@/components/shared/Navigation' +import { FlashcardForm } from '@/components/flashcards/FlashcardForm' +import { useToast } from '@/components/shared/Toast' import { flashcardsService, type Flashcard } from '@/lib/services/flashcards' import { imageGenerationService } from '@/lib/services/imageGeneration' -import { useFlashcardSearch, type SearchActions } from '@/hooks/useFlashcardSearch' +import { useFlashcardSearch, type SearchActions } from '@/hooks/flashcards/useFlashcardSearch' // 詞性簡寫轉換 (全域函數) const getPartOfSpeechDisplay = (partOfSpeech: string): string => { diff --git a/frontend/app/generate/page.tsx b/frontend/app/generate/page.tsx index d7e4c65..fc384fb 100644 --- a/frontend/app/generate/page.tsx +++ b/frontend/app/generate/page.tsx @@ -1,10 +1,10 @@ 'use client' import { useState, useMemo, useCallback } from 'react' -import { ProtectedRoute } from '@/components/ProtectedRoute' -import { Navigation } from '@/components/Navigation' -import { ClickableTextV2 } from '@/components/ClickableTextV2' -import { useToast } from '@/components/Toast' +import { ProtectedRoute } from '@/components/shared/ProtectedRoute' +import { Navigation } from '@/components/shared/Navigation' +import { ClickableTextV2 } from '@/components/generate/ClickableTextV2' +import { useToast } from '@/components/shared/Toast' import { flashcardsService } from '@/lib/services/flashcards' import { compareCEFRLevels, getLevelIndex, getTargetLearningRange } from '@/lib/utils/cefrUtils' import { Play } from 'lucide-react' diff --git a/frontend/app/review-design/page.tsx b/frontend/app/review-design/page.tsx index 44b08bd..596b9ac 100644 --- a/frontend/app/review-design/page.tsx +++ b/frontend/app/review-design/page.tsx @@ -1,7 +1,7 @@ 'use client' import { useState, useEffect } from 'react' -import { Navigation } from '@/components/Navigation' +import { Navigation } from '@/components/shared/Navigation' import { FlipMemoryTest, VocabChoiceTest, @@ -50,6 +50,7 @@ export default function ReviewTestsPage() { pronunciation: currentCard.pronunciation, synonyms: currentCard.synonyms || [], difficultyLevel: currentCard.difficultyLevel, + cefr: currentCard.difficultyLevel || 'A1', translation: currentCard.translation, // 從 flashcardExampleImages 提取圖片URL exampleImage: currentCard.flashcardExampleImages?.[0]?.exampleImage ? @@ -64,6 +65,7 @@ export default function ReviewTestsPage() { pronunciation: "", synonyms: [], difficultyLevel: "A1", + cefr: "A1", translation: "載入中", exampleImage: undefined } diff --git a/frontend/app/review/page.tsx b/frontend/app/review/page.tsx index 4ca7683..3b2f65d 100644 --- a/frontend/app/review/page.tsx +++ b/frontend/app/review/page.tsx @@ -2,8 +2,8 @@ import { useEffect } from 'react' import { useRouter } from 'next/navigation' -import { Navigation } from '@/components/Navigation' -import LearningComplete from '@/components/LearningComplete' +import { Navigation } from '@/components/shared/Navigation' +import LearningComplete from '@/components/flashcards/LearningComplete' import { Modal } from '@/components/ui/Modal' // 新架構組件 diff --git a/frontend/components/debug/TestDebugPanel.tsx b/frontend/components/debug/TestDebugPanel.tsx index cda190c..2e940f4 100644 --- a/frontend/components/debug/TestDebugPanel.tsx +++ b/frontend/components/debug/TestDebugPanel.tsx @@ -9,20 +9,14 @@ interface TestDebugPanelProps { export const TestDebugPanel: React.FC = ({ className }) => { const [isVisible, setIsVisible] = useState(false) - const { testItems, currentTestIndex, addTestItems, resetQueue } = useTestQueueStore() - const { totalCorrect, totalIncorrect, resetScore } = useTestResultStore() + const { testItems, currentTestIndex, initializeTestQueue, resetQueue } = useTestQueueStore() + const { score, resetScore } = useTestResultStore() const stats = getTestStatistics(mockFlashcards) const handleLoadMockData = () => { - const queue = generateTestQueue(mockFlashcards) - addTestItems(queue.map(item => ({ - flashcardId: item.card.id, - mode: item.mode, - priority: item.priority, - attempts: item.card.testAttempts || 0, - completed: false - }))) + // 使用 initializeTestQueue 期望的參數格式 + initializeTestQueue(mockFlashcards, []) } const handleResetAll = () => { @@ -59,7 +53,7 @@ export const TestDebugPanel: React.FC = ({ className }) =>
隊列長度: {testItems.length}
當前位置: {currentTestIndex + 1}/{testItems.length}
-
正確: {totalCorrect} | 錯誤: {totalIncorrect}
+
正確: {score.correct} | 錯誤: {score.total - score.correct}
@@ -104,8 +98,8 @@ export const TestDebugPanel: React.FC = ({ className }) => key={index} className={`flex justify-between ${index === currentTestIndex ? 'font-bold text-blue-600' : ''}`} > - {item.mode} - P:{item.priority} + {item.testName} + #{item.order} ))} {testItems.length > 10 && ( diff --git a/frontend/components/flashcards/FlashcardForm.tsx b/frontend/components/flashcards/FlashcardForm.tsx index 038adab..242e5e5 100644 --- a/frontend/components/flashcards/FlashcardForm.tsx +++ b/frontend/components/flashcards/FlashcardForm.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react' import { flashcardsService, type CreateFlashcardRequest, type Flashcard } from '@/lib/services/flashcards' -import AudioPlayer from './AudioPlayer' +import AudioPlayer from '@/components/media/AudioPlayer' interface FlashcardFormProps { cardSets?: any[] // 保持相容性 @@ -21,7 +21,7 @@ export function FlashcardForm({ initialData, isEdit = false, onSuccess, onCancel partOfSpeech: initialData?.partOfSpeech || 'noun', example: initialData?.example || '', exampleTranslation: initialData?.exampleTranslation || '', - difficultyLevel: initialData?.difficultyLevel || 'A2', + cefr: initialData?.cefr || 'A2', }) const [loading, setLoading] = useState(false) @@ -156,13 +156,13 @@ export function FlashcardForm({ initialData, isEdit = false, onSuccess, onCancel
-