'use client' import { useState, useMemo, useCallback } from 'react' import { ProtectedRoute } from '@/components/shared/ProtectedRoute' import { Navigation } from '@/components/shared/Navigation' import { ClickableTextV2 } from '@/components/generate/ClickableTextV2' import { WordPopup } from '@/components/word/WordPopup' import { useToast } from '@/components/shared/Toast' import { flashcardsService } from '@/lib/services/flashcards' import { compareCEFRLevels, getLevelIndex, getTargetLearningRange } from '@/lib/utils/cefrUtils' import { API_CONFIG } from '@/lib/config/api' import Link from 'next/link' // 常數定義 const MAX_MANUAL_INPUT_LENGTH = 300 interface GrammarCorrection { hasErrors: boolean; originalText: string; correctedText: string | null; corrections: Array<{ position: { start: number; end: number }; error: string; correction: string; type: string; explanation: string; severity: 'high' | 'medium' | 'low'; }>; confidenceScore: number; } // 移除 IdiomPopup - 使用統一的 WordPopup 組件 function GenerateContent() { const toast = useToast() const [textInput, setTextInput] = useState('') const [isAnalyzing, setIsAnalyzing] = useState(false) const [showAnalysisView, setShowAnalysisView] = useState(false) const [sentenceAnalysis, setSentenceAnalysis] = useState | null>(null) const [sentenceMeaning, setSentenceMeaning] = useState('') const [grammarCorrection, setGrammarCorrection] = useState(null) const [selectedIdiom, setSelectedIdiom] = useState(null) // 處理句子分析 - 使用真實API const handleAnalyzeSentence = async () => { setIsAnalyzing(true) try { const response = await fetch(`${API_CONFIG.BASE_URL}/api/ai/analyze-sentence`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ inputText: textInput, analysisMode: 'full', options: { includeGrammarCheck: true, includeVocabularyAnalysis: true, includeTranslation: true, includeIdiomDetection: true, includeExamples: true } }) }) if (!response.ok) { let errorMessage = `API請求失敗: ${response.status}` try { const errorData = await response.json() errorMessage = errorData.error?.message || errorData.message || errorMessage } catch (e) { console.warn('無法解析錯誤回應:', e) } throw new Error(errorMessage) } const result = await response.json() if (!result.success || !result.data) { throw new Error('API回應格式錯誤') } // 處理API回應 - 適配新的後端格式 const apiData = result.data.data // 需要深入兩層:result.data.data // 設定完整的分析結果(包含vocabularyAnalysis和其他數據) const analysisData = { originalText: apiData.originalText, sentenceMeaning: apiData.sentenceMeaning, grammarCorrection: apiData.grammarCorrection, vocabularyAnalysis: apiData.vocabularyAnalysis, idioms: apiData.idioms || [], processingTime: result.processingTime } setSentenceAnalysis(analysisData) setSentenceMeaning(apiData.sentenceMeaning || '') // 處理語法修正 if (apiData.grammarCorrection) { setGrammarCorrection({ hasErrors: apiData.grammarCorrection.hasErrors, originalText: textInput, correctedText: apiData.grammarCorrection.correctedText || textInput, corrections: apiData.grammarCorrection.corrections || [], confidenceScore: apiData.grammarCorrection.confidenceScore || 0.9 }) } else { setGrammarCorrection({ hasErrors: false, originalText: textInput, correctedText: textInput, corrections: [], confidenceScore: 1.0 }) } setShowAnalysisView(true) } catch (error) { console.error('Error in sentence analysis:', error) setGrammarCorrection({ hasErrors: true, originalText: textInput, correctedText: textInput, corrections: [], confidenceScore: 0.0 }) setSentenceMeaning('分析過程中發生錯誤,請稍後再試。') // 錯誤時也不設置finalText,使用原始輸入 setShowAnalysisView(true) } finally { setIsAnalyzing(false) } } const handleAcceptCorrection = useCallback(() => { if (grammarCorrection?.correctedText) { // 更新用戶輸入為修正後的版本 setTextInput(grammarCorrection.correctedText) console.log('✅ 已採用修正版本,文本已更新為正確版本!') } }, [grammarCorrection?.correctedText]) const handleRejectCorrection = useCallback(() => { // 保持原始輸入不變,只是隱藏語法修正面板 setGrammarCorrection(null) console.log('📝 已保持原始版本,繼續使用您的原始輸入。') }, []) // 詞彙統計計算 - 適配新的後端API格式 const vocabularyStats = useMemo(() => { if (!sentenceAnalysis?.vocabularyAnalysis) { return { simpleCount: 0, moderateCount: 0, difficultCount: 0, idiomCount: 0 } } const userLevel = localStorage.getItem('userEnglishLevel') || 'A2' let simpleCount = 0 let moderateCount = 0 let difficultCount = 0 // 處理vocabularyAnalysis物件 Object.values(sentenceAnalysis.vocabularyAnalysis).forEach((wordData: any) => { const cefr = wordData?.cefr || 'A1' const userIndex = getLevelIndex(userLevel) const wordIndex = getLevelIndex(cefr) if (userIndex > wordIndex) { simpleCount++ } else if (userIndex === wordIndex) { moderateCount++ } else { difficultCount++ } }) // 處理慣用語統計 const idiomCount = sentenceAnalysis.idioms?.length || 0 return { simpleCount, moderateCount, difficultCount, idiomCount } }, [sentenceAnalysis]) // 保存單個詞彙 const handleSaveWord = useCallback(async (word: string, analysis: any) => { try { const cefrValue = analysis.cefr || analysis.cefrLevel || analysis.CEFR || 'A0' const cardData = { word: word, translation: analysis.translation || analysis.Translation || '', definition: analysis.definition || analysis.Definition || '', pronunciation: analysis.pronunciation || analysis.Pronunciation || `/${word}/`, partOfSpeech: analysis.partOfSpeech || analysis.PartOfSpeech || 'noun', example: analysis.example || `Example sentence with ${word}.`, // 使用分析結果的例句 exampleTranslation: analysis.exampleTranslation, cefr: cefrValue } const response = await flashcardsService.createFlashcard(cardData) if (response.success) { // 顯示成功提示 const successMessage = `已成功將「${word}」保存到詞卡庫!` toast.success(successMessage) console.log('✅', successMessage) return { success: true } } else if (response.error && response.error.includes('已存在')) { // 顯示重複提示 const duplicateMessage = `詞卡「${word}」已經存在於詞卡庫中` toast.warning(duplicateMessage) console.log('⚠️', duplicateMessage) return { success: false, error: 'duplicate', message: duplicateMessage } } else { throw new Error(response.error || '保存失敗') } } catch (error) { console.error('Save word error:', error) const errorMessage = error instanceof Error ? error.message : '保存失敗' toast.error(`保存詞卡失敗: ${errorMessage}`) return { success: false, error: errorMessage } } }, []) return (
{!showAnalysisView ? (

AI 智能生成詞卡

{/* Content Input */}

輸入英文文本