diff --git a/frontend/app/review-dev/page.tsx b/frontend/app/review-dev/page.tsx index 9cb9158..eb644a2 100644 --- a/frontend/app/review-dev/page.tsx +++ b/frontend/app/review-dev/page.tsx @@ -3,7 +3,7 @@ import { Navigation } from '@/components/shared/Navigation' import { FlipMemory } from '@/components/review/quiz/FlipMemory' import { VocabChoiceQuiz } from '@/components/review/quiz/VocabChoiceQuiz' -import { QuizProgress } from '@/components/review/ui/QuizProgress' +import { QuizProgressDev } from '@/components/review/ui/QuizProgressDev' import { QuizResult } from '@/components/review/quiz/QuizResult' import { useReviewSession } from '@/hooks/review/useReviewSession' @@ -115,7 +115,7 @@ export default function ReviewDevPage() {
{/* 使用修改後的 SimpleProgress 組件 */} -
- {/* 使用修改後的 SimpleProgress 組件 */} + {/* 使用簡化的 ReviewProgress 組件 */} {/* 根據當前測驗項目類型渲染對應組件 */} diff --git a/frontend/components/review/ui/QuizProgress.tsx b/frontend/components/review/ui/QuizProgress.tsx index 1df3a65..452cbb1 100644 --- a/frontend/components/review/ui/QuizProgress.tsx +++ b/frontend/components/review/ui/QuizProgress.tsx @@ -22,23 +22,7 @@ export function QuizProgress({ currentQuizItem, totalQuizItems, completedQuizIte return (
-
- 線性複習進度 - {currentQuizItem && ( -
- - {currentQuizItem.quizType === 'flip-card' ? '🔄' : '🎯'} - - - {currentQuizItem.quizType === 'flip-card' ? '翻卡記憶' : '詞彙選擇'} • {currentQuizItem.cardData.word} - -
- )} -
- - {completedQuizItems}/{totalQuizItems} 項目 - {score.total > 0 && ( 準確率 {accuracy}% diff --git a/frontend/components/review/ui/QuizProgressDev.tsx b/frontend/components/review/ui/QuizProgressDev.tsx new file mode 100644 index 0000000..ba05ef6 --- /dev/null +++ b/frontend/components/review/ui/QuizProgressDev.tsx @@ -0,0 +1,67 @@ +import { QuizItem } from '@/lib/data/reviewSimpleData' + +interface ReviewProgressProps { + currentQuizItem?: QuizItem + totalQuizItems: number + completedQuizItems: number + score: { correct: number; total: number } +} + +export function QuizProgressDev({ currentQuizItem, totalQuizItems, completedQuizItems, score }: ReviewProgressProps) { + const progress = (completedQuizItems / totalQuizItems) * 100 + const accuracy = score.total > 0 ? Math.round((score.correct / score.total) * 100) : 0 + + return ( +
+
+
+ 複習進度 + {currentQuizItem && ( +
+ + {currentQuizItem.quizType === 'flip-card' ? '🔄' : '🎯'} + + + {currentQuizItem.quizType === 'flip-card' ? '翻卡記憶' : '詞彙選擇'} • {currentQuizItem.cardData.word} + +
+ )} +
+
+ + {completedQuizItems}/{totalQuizItems} 項目 + + {score.total > 0 && ( + + 準確率 {accuracy}% + + )} +
+
+ + {/* 進度條 */} +
+
+
+ + {/* 基本統計 */} +
+ {score.total > 0 && ( + <> +
+ + 答對 {score.correct} +
+
+ + 答錯 {score.total - score.correct} +
+ + )} +
+
+ ) +} \ No newline at end of file diff --git a/frontend/hooks/review/useReviewSession.ts b/frontend/hooks/review/useReviewSession.ts index 77b943a..cf459d1 100644 --- a/frontend/hooks/review/useReviewSession.ts +++ b/frontend/hooks/review/useReviewSession.ts @@ -1,14 +1,17 @@ import { useReducer, useEffect, useMemo, useState } from 'react' import { flashcardsService, Flashcard } from '@/lib/services/flashcards' -// 重新定義所需的介面 +// 重新定義所需的介面,確保與 reviewSimpleData.CardState 完全兼容 interface CardState extends Flashcard { skipCount: number wrongCount: number isCompleted: boolean originalOrder: number - synonyms?: string[] - difficultyLevelNumeric: number // 添加缺少的屬性 + synonyms: string[] // 改為必需的數組 + difficultyLevelNumeric: number // 必需屬性 + exampleTranslation: string // 覆蓋 Flashcard 的可選定義,改為必需 + updatedAt: string // 覆蓋 Flashcard 的可選定義,改為必需 + primaryImageUrl: string | null // 確保類型匹配(null 而非 undefined) } interface QuizItem { @@ -89,16 +92,18 @@ const generateQuizItemsFromFlashcards = (flashcards: Flashcard[]): QuizItem[] => let order = 0 flashcards.forEach((card) => { - // 轉換 Flashcard 為 CardState 格式 + // 轉換 Flashcard 為 CardState 格式,確保所有屬性都有值 const cardState: CardState = { ...card, - exampleTranslation: card.exampleTranslation || '', // 確保 exampleTranslation 不為 undefined + exampleTranslation: card.exampleTranslation || '', // 確保為 string,不是 undefined + updatedAt: card.updatedAt || card.createdAt, // 確保 updatedAt 為 string + primaryImageUrl: card.primaryImageUrl || null, // 確保為 null 而非 undefined skipCount: 0, wrongCount: 0, isCompleted: false, originalOrder: order / 2, // 原始詞卡的順序 - synonyms: [], - difficultyLevelNumeric: card.masteryLevel || 1 // 添加缺少的屬性 + synonyms: [], // 確保為空數組而非 undefined + difficultyLevelNumeric: card.masteryLevel || 1 // 使用 masteryLevel 或預設值 1 } // 為每張詞卡生成兩種測驗模式