feat: 完善AI生成頁面功能與體驗
- 修復詞彙顏色邏輯,實現基於用戶程度的相對難度顯示 - A2用戶看B2詞彙現在正確顯示橘色(挑戰等級),而非固定藍色 - 新增分析結果localStorage持久化,跳頁後保留分析內容 - 添加簡潔的用戶程度指示器,使用經典齒輪圖標 - 程度按鈕靠右對齊,固定灰色主題,清楚導航到設定頁面 提升個人化學習體驗和界面一致性 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
2c204c1146
commit
1b6e62de95
|
|
@ -1,12 +1,12 @@
|
|||
'use client'
|
||||
|
||||
import { useState, useMemo, useCallback } from 'react'
|
||||
import { useState, useMemo, useCallback, useEffect } from 'react'
|
||||
import { ProtectedRoute } from '@/components/shared/ProtectedRoute'
|
||||
import { Navigation } from '@/components/shared/Navigation'
|
||||
import { WordPopup } from '@/components/word/WordPopup'
|
||||
import { useToast } from '@/components/shared/Toast'
|
||||
import { flashcardsService } from '@/lib/services/flashcards'
|
||||
import { getLevelIndex, getTargetLearningRange } from '@/lib/utils/cefrUtils'
|
||||
import { getLevelIndex } from '@/lib/utils/cefrUtils'
|
||||
import { useWordAnalysis } from '@/hooks/word/useWordAnalysis'
|
||||
import { API_CONFIG } from '@/lib/config/api'
|
||||
import Link from 'next/link'
|
||||
|
|
@ -49,8 +49,50 @@ function GenerateContent() {
|
|||
const [selectedIdiom, setSelectedIdiom] = useState<string | null>(null)
|
||||
const [selectedWord, setSelectedWord] = useState<string | null>(null)
|
||||
|
||||
// localStorage 快取函數
|
||||
const saveAnalysisToCache = useCallback((cacheData: any) => {
|
||||
try {
|
||||
localStorage.setItem('generate_analysis_cache', JSON.stringify(cacheData))
|
||||
} catch (error) {
|
||||
console.warn('無法保存分析快取:', error)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const loadAnalysisFromCache = useCallback(() => {
|
||||
try {
|
||||
const cached = localStorage.getItem('generate_analysis_cache')
|
||||
return cached ? JSON.parse(cached) : null
|
||||
} catch (error) {
|
||||
console.warn('無法載入分析快取:', error)
|
||||
return null
|
||||
}
|
||||
}, [])
|
||||
|
||||
const clearAnalysisCache = useCallback(() => {
|
||||
try {
|
||||
localStorage.removeItem('generate_analysis_cache')
|
||||
} catch (error) {
|
||||
console.warn('無法清除分析快取:', error)
|
||||
}
|
||||
}, [])
|
||||
|
||||
// 組件載入時恢復快取的分析結果
|
||||
useEffect(() => {
|
||||
const cached = loadAnalysisFromCache()
|
||||
if (cached) {
|
||||
setTextInput(cached.textInput || '')
|
||||
setSentenceAnalysis(cached.sentenceAnalysis || null)
|
||||
setSentenceMeaning(cached.sentenceMeaning || '')
|
||||
setGrammarCorrection(cached.grammarCorrection || null)
|
||||
setShowAnalysisView(cached.showAnalysisView || false)
|
||||
console.log('✅ 已恢復快取的分析結果')
|
||||
}
|
||||
}, [loadAnalysisFromCache])
|
||||
|
||||
// 處理句子分析 - 使用真實API
|
||||
const handleAnalyzeSentence = async () => {
|
||||
// 清除舊的分析快取
|
||||
clearAnalysisCache()
|
||||
|
||||
setIsAnalyzing(true)
|
||||
|
||||
|
|
@ -126,6 +168,29 @@ function GenerateContent() {
|
|||
}
|
||||
|
||||
setShowAnalysisView(true)
|
||||
|
||||
// 保存分析結果到快取
|
||||
const cacheData = {
|
||||
textInput,
|
||||
sentenceAnalysis: analysisData,
|
||||
sentenceMeaning: apiData.sentenceMeaning || '',
|
||||
grammarCorrection: apiData.grammarCorrection ? {
|
||||
hasErrors: apiData.grammarCorrection.hasErrors,
|
||||
originalText: textInput,
|
||||
correctedText: apiData.grammarCorrection.correctedText || textInput,
|
||||
corrections: apiData.grammarCorrection.corrections || [],
|
||||
confidenceScore: apiData.grammarCorrection.confidenceScore || 1.0
|
||||
} : {
|
||||
hasErrors: false,
|
||||
originalText: textInput,
|
||||
correctedText: textInput,
|
||||
corrections: [],
|
||||
confidenceScore: 1.0
|
||||
},
|
||||
showAnalysisView: true
|
||||
}
|
||||
saveAnalysisToCache(cacheData)
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error in sentence analysis:', error)
|
||||
setGrammarCorrection({
|
||||
|
|
@ -299,32 +364,25 @@ function GenerateContent() {
|
|||
'🔍 分析句子'
|
||||
)}
|
||||
</button>
|
||||
|
||||
|
||||
{/* 個人化程度指示器 */}
|
||||
<div className="text-center text-sm text-gray-600 mt-2">
|
||||
{(() => {
|
||||
const userLevel = localStorage.getItem('userEnglishLevel') || 'A2'
|
||||
return (
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<span>🎯 您的程度: {userLevel}</span>
|
||||
<span className="text-gray-400">|</span>
|
||||
<span>📈 重點學習範圍: {getTargetLearningRange(userLevel)}</span>
|
||||
<Link
|
||||
href="/settings"
|
||||
className="text-blue-500 hover:text-blue-700 ml-2"
|
||||
>
|
||||
調整 ⚙️
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
/* 重新設計的句子分析視圖 - 簡潔流暢 */
|
||||
<>
|
||||
{/* 用戶程度指示器 */}
|
||||
<div className="flex justify-end mb-6">
|
||||
<Link
|
||||
href="/profile"
|
||||
className="flex items-center gap-2 px-4 py-2 rounded-lg transition-colors hover:shadow-md bg-gray-100 text-gray-700 border border-gray-200"
|
||||
>
|
||||
<span className="text-sm font-medium">你的程度 {userLevel}</span>
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth="2">
|
||||
<path d="M12 15a3 3 0 100-6 3 3 0 000 6z"/>
|
||||
<path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z"/>
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* 語法修正面板 - 如果需要的話 */}
|
||||
{grammarCorrection && grammarCorrection.hasErrors && (
|
||||
<div className="bg-yellow-50 border border-yellow-200 rounded-xl p-6 mb-6">
|
||||
|
|
|
|||
Loading…
Reference in New Issue