feat: 優化智能複習系統mock數據展示四情境自動適配效果

## 🎯 Mock數據優化重點

### 📚 四情境完整演示
1. **A1學習者情境** (卡片1-2)
   - userLevel ≤ 20 → 自動限制基礎3題型
   - 詞彙: cat, dog (基礎詞彙)
   - 系統選擇: 翻卡記憶、詞彙選擇、詞彙聽力

2. **簡單詞彙情境** (卡片3)
   - userLevel > wordLevel (difficulty < -10)
   - 詞彙: happy (學習者70 vs 詞彙35)
   - 系統選擇: 例句重組、例句填空

3. **適中詞彙情境** (卡片4)
   - userLevel ≈ wordLevel (-10 ≤ difficulty ≤ 10)
   - 詞彙: determine (學習者60 vs 詞彙65)
   - 系統選擇: 填空、重組、口說

4. **困難詞彙情境** (卡片5)
   - userLevel < wordLevel (difficulty > 10)
   - 詞彙: sophisticated (學習者50 vs 詞彙85)
   - 系統選擇: 翻卡記憶、詞彙選擇

### 🖥️ UI增強功能
- **智能適配演示面板**: 實時顯示當前情境和程度差異
- **實時熟悉度指示器**: 展示記憶衰減效果
- **詳細演示說明**: 引導用戶體驗不同情境效果

### 📱 互動體驗
- 點擊「下一張」體驗不同情境下的自動題型選擇
- 每張卡片都會自動選擇最適合的複習方式
- 清楚展示零選擇負擔的智能學習體驗

## 🌟 演示價值
- 直觀展示四情境智能適配邏輯
- 證明A1學習者自動保護機制
- 展示基於學習程度的個人化複習體驗
- 體驗零選擇負擔的流暢學習流程

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
鄭沛軒 2025-09-25 18:09:49 +08:00
parent d6744b0da7
commit c2ca9e0aea
1 changed files with 180 additions and 43 deletions

View File

@ -112,60 +112,149 @@ export default function LearnPage() {
try {
setIsLoadingCard(true)
// 暫時使用mock data等後端API就緒後替換
// Mock data 展示四情境自動適配效果
const mockDueCards: ExtendedFlashcard[] = [
// 情境1: A1學習者 (userLevel ≤ 20) → 基礎3題型
{
id: '1',
word: 'brought',
partOfSpeech: 'verb',
pronunciation: '/brɔːt/',
translation: '提出、帶來',
definition: 'Past tense of bring; to mention or introduce a topic in conversation',
example: 'He brought this thing up during our meeting and no one agreed.',
exampleTranslation: '他在我們的會議中提出了這件事,但沒有人同意。',
masteryLevel: 65,
timesReviewed: 3,
isFavorite: false,
nextReviewDate: new Date().toISOString().split('T')[0], // 今天到期
difficultyLevel: 'B1',
createdAt: new Date().toISOString(),
// 智能複習欄位
userLevel: 60, // 學習者程度
wordLevel: 70, // 詞彙難度 (困難詞彙)
baseMasteryLevel: 75,
lastReviewDate: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(), // 2天前
exampleImages: [],
hasExampleImage: true,
primaryImageUrl: '/images/examples/bring_up.png',
synonyms: ['mentioned', 'raised', 'introduced'],
difficulty: 'B1',
exampleImage: '/images/examples/bring_up.png'
},
{
id: '2',
word: 'simple',
partOfSpeech: 'adjective',
pronunciation: '/ˈsɪmpəl/',
translation: '簡單的',
definition: 'Easy to understand or do; not complex',
example: 'This is a simple task that anyone can complete.',
exampleTranslation: '這是一個任何人都能完成的簡單任務。',
masteryLevel: 45,
word: 'cat',
partOfSpeech: 'noun',
pronunciation: '/kæt/',
translation: '貓',
definition: 'A small animal that people keep as a pet',
example: 'The cat is sleeping on the sofa.',
exampleTranslation: '這隻貓正在沙發上睡覺。',
masteryLevel: 30,
timesReviewed: 1,
isFavorite: false,
nextReviewDate: new Date().toISOString().split('T')[0],
difficultyLevel: 'A2',
difficultyLevel: 'A1',
createdAt: new Date().toISOString(),
// 智能複習欄位 - A1學習者
// A1學習者情境
userLevel: 15, // A1學習者
wordLevel: 25,
baseMasteryLevel: 50,
wordLevel: 20, // 基礎詞彙
baseMasteryLevel: 35,
lastReviewDate: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString(),
exampleImages: [],
hasExampleImage: false,
synonyms: ['easy', 'basic', 'straightforward'],
synonyms: ['kitty', 'feline'],
difficulty: 'A1',
exampleImage: '/images/examples/cat.png'
},
// 情境2: 簡單詞彙 (學習者程度 > 詞彙程度) → 應用2題型
{
id: '2',
word: 'happy',
partOfSpeech: 'adjective',
pronunciation: '/ˈhæpi/',
translation: '快樂的',
definition: 'Feeling pleasure and contentment',
example: 'She looks very happy today because of the good news.',
exampleTranslation: '她今天看起來很快樂,因為有好消息。',
masteryLevel: 85,
timesReviewed: 5,
isFavorite: true,
nextReviewDate: new Date().toISOString().split('T')[0],
difficultyLevel: 'A2',
createdAt: new Date().toISOString(),
// 簡單詞彙情境 (程度 > 難度)
userLevel: 70, // 中級學習者
wordLevel: 35, // 簡單詞彙 (difficulty = -35)
baseMasteryLevel: 90,
lastReviewDate: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString(),
exampleImages: [],
hasExampleImage: true,
primaryImageUrl: '/images/examples/happy.png',
synonyms: ['joyful', 'glad', 'cheerful'],
difficulty: 'A2',
exampleImage: '/images/examples/simple.png'
exampleImage: '/images/examples/happy.png'
},
// 情境3: 適中詞彙 (程度 ≈ 難度) → 全方位3題型
{
id: '3',
word: 'determine',
partOfSpeech: 'verb',
pronunciation: '/dɪˈːrmɪn/',
translation: '決定、確定',
definition: 'To decide or establish exactly what something is',
example: 'We need to determine the best solution for this problem.',
exampleTranslation: '我們需要確定這個問題的最佳解決方案。',
masteryLevel: 55,
timesReviewed: 3,
isFavorite: false,
nextReviewDate: new Date().toISOString().split('T')[0],
difficultyLevel: 'B1',
createdAt: new Date().toISOString(),
// 適中詞彙情境 (程度 ≈ 難度)
userLevel: 60, // 中級學習者
wordLevel: 65, // 適中詞彙 (difficulty = +5)
baseMasteryLevel: 65,
lastReviewDate: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(),
exampleImages: [],
hasExampleImage: true,
primaryImageUrl: '/images/examples/determine.png',
synonyms: ['decide', 'establish', 'figure out'],
difficulty: 'B1',
exampleImage: '/images/examples/determine.png'
},
// 情境4: 困難詞彙 (程度 < 難度) → 基礎2題型
{
id: '4',
word: 'sophisticated',
partOfSpeech: 'adjective',
pronunciation: '/səˈfɪstɪkeɪtɪd/',
translation: '精密的、複雜的',
definition: 'Having advanced knowledge, experience, or understanding',
example: 'The new software uses sophisticated algorithms to analyze data.',
exampleTranslation: '這個新軟體使用精密的算法來分析數據。',
masteryLevel: 25,
timesReviewed: 1,
isFavorite: false,
nextReviewDate: new Date().toISOString().split('T')[0],
difficultyLevel: 'C1',
createdAt: new Date().toISOString(),
// 困難詞彙情境 (程度 < 難度)
userLevel: 50, // 中級學習者
wordLevel: 85, // 困難詞彙 (difficulty = +35)
baseMasteryLevel: 30,
lastReviewDate: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString(),
exampleImages: [],
hasExampleImage: true,
primaryImageUrl: '/images/examples/sophisticated.png',
synonyms: ['advanced', 'complex', 'refined'],
difficulty: 'C1',
exampleImage: '/images/examples/sophisticated.png'
},
// 額外情境: A1學習者遇到困難詞彙 → 自動保護
{
id: '5',
word: 'dog',
partOfSpeech: 'noun',
pronunciation: '/dɔːg/',
translation: '狗',
definition: 'A four-legged animal that people keep as a pet',
example: 'My dog likes to play in the park.',
exampleTranslation: '我的狗喜歡在公園裡玩。',
masteryLevel: 20,
timesReviewed: 0,
isFavorite: false,
nextReviewDate: new Date().toISOString().split('T')[0],
difficultyLevel: 'A1',
createdAt: new Date().toISOString(),
// A1學習者保護測試 (即使是簡單詞彙也用基礎題型)
userLevel: 12, // A1初學者
wordLevel: 15, // 簡單詞彙但A1會被保護
baseMasteryLevel: 25,
lastReviewDate: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString(),
exampleImages: [],
hasExampleImage: false,
synonyms: ['puppy', 'hound'],
difficulty: 'A1',
exampleImage: '/images/examples/dog.png'
}
];
@ -555,8 +644,56 @@ export default function LearnPage() {
</div>
</div>
{/* Demo Information Panel */}
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">
<h3 className="text-lg font-semibold text-blue-900 mb-3">🎯 </h3>
<div className="grid grid-cols-1 md:grid-cols-4 gap-3 text-sm mb-4">
<div className="bg-white rounded p-3">
<div className="text-blue-700 font-medium"></div>
<div className="text-gray-600">
{currentCard && (() => {
const userLevel = currentCard.userLevel || 50;
const wordLevel = currentCard.wordLevel || 50;
const difficulty = wordLevel - userLevel;
if (userLevel <= 20) return 'A1學習者';
if (difficulty < -10) return '簡單詞彙';
if (difficulty >= -10 && difficulty <= 10) return '適中詞彙';
return '困難詞彙';
})()}
</div>
</div>
<div className="bg-white rounded p-3">
<div className="text-blue-700 font-medium"></div>
<div className="text-gray-600">{currentCard?.userLevel || '--'}</div>
</div>
<div className="bg-white rounded p-3">
<div className="text-blue-700 font-medium"></div>
<div className="text-gray-600">{currentCard?.wordLevel || '--'}</div>
</div>
<div className="bg-white rounded p-3">
<div className="text-blue-700 font-medium"></div>
<div className="text-gray-600">
{currentCard ? (currentCard.wordLevel || 50) - (currentCard.userLevel || 50) : '--'}
</div>
</div>
</div>
<div className="bg-white rounded-lg p-3">
<div className="text-blue-700 font-medium mb-2">📚 </div>
<div className="text-gray-600 text-xs">
<br/>
1-2: A1學習者 ()<br/>
卡片3: 簡單詞彙 ()<br/>
卡片4: 適中詞彙 ()<br/>
卡片5: 困難詞彙 ()
</div>
</div>
</div>
{/* Current Card Mastery Level */}
{currentCard.baseMasteryLevel && currentCard.lastReviewDate && (
{currentCard?.baseMasteryLevel && currentCard?.lastReviewDate && (
<div className="mb-4">
<MasteryIndicator
level={calculateCurrentMastery(currentCard.baseMasteryLevel, currentCard.lastReviewDate)}