diff --git a/frontend/app/flashcards/page.tsx b/frontend/app/flashcards/page.tsx index f147454..2f4fcf7 100644 --- a/frontend/app/flashcards/page.tsx +++ b/frontend/app/flashcards/page.tsx @@ -24,35 +24,29 @@ function FlashcardsContent() { const [searchState, searchActions] = useFlashcardSearch(activeTab) // 例句圖片邏輯 - const getExampleImage = (word: string): string => { - const availableImages = [ - '/images/examples/bring_up.png', - '/images/examples/instinct.png', - '/images/examples/warrant.png' - ] - + const getExampleImage = (word: string): string | null => { const imageMap: {[key: string]: string} = { 'brought': '/images/examples/bring_up.png', 'instincts': '/images/examples/instinct.png', 'warrants': '/images/examples/warrant.png', - 'hello': '/images/examples/bring_up.png', - 'beautiful': '/images/examples/instinct.png', - 'understand': '/images/examples/warrant.png', - 'elaborate': '/images/examples/bring_up.png', - 'sophisticated': '/images/examples/instinct.png', - 'ubiquitous': '/images/examples/warrant.png' + 'evidence': '/images/examples/bring_up.png', + 'recovering': '/images/examples/instinct.png' } - // 根據詞彙返回對應圖片,如果沒有則根據字母分配 - const mappedImage = imageMap[word?.toLowerCase()] - if (mappedImage) return mappedImage + // 只返回已確認存在的圖片,沒有則返回 null + return imageMap[word?.toLowerCase()] || null + } - // 根據首字母分配圖片 - const firstChar = (word || 'a')[0].toLowerCase() - const charCode = firstChar.charCodeAt(0) - 97 // a=0, b=1, c=2... - const imageIndex = charCode % availableImages.length + // 檢查詞彙是否有例句圖片 + const hasExampleImage = (word: string): boolean => { + return getExampleImage(word) !== null + } - return availableImages[imageIndex] + // 處理AI生成例句圖片 (預留接口) + const handleGenerateExampleImage = (card: Flashcard) => { + console.log('準備為詞彙生成例句圖片:', card.word) + // TODO: 下階段實現AI生成流程 + // router.push(`/generate-image?word=${encodeURIComponent(card.word)}`) } // 初始化數據載入 @@ -258,6 +252,8 @@ function FlashcardsContent() { getCEFRColor={getCEFRColor} highlightSearchTerm={highlightSearchTerm} getExampleImage={getExampleImage} + hasExampleImage={hasExampleImage} + onGenerateExampleImage={handleGenerateExampleImage} router={router} /> @@ -469,7 +465,9 @@ interface SearchResultsProps { onToggleFavorite: (card: Flashcard) => void getCEFRColor: (level: string) => string highlightSearchTerm: (text: string, term: string) => React.ReactNode - getExampleImage: (word: string) => string + getExampleImage: (word: string) => string | null + hasExampleImage: (word: string) => boolean + onGenerateExampleImage: (card: Flashcard) => void router: any } @@ -482,6 +480,8 @@ function SearchResults({ getCEFRColor, highlightSearchTerm, getExampleImage, + hasExampleImage, + onGenerateExampleImage, router }: SearchResultsProps) { if (searchState.flashcards.length === 0) { @@ -521,6 +521,8 @@ function SearchResults({ getCEFRColor={getCEFRColor} highlightSearchTerm={highlightSearchTerm} getExampleImage={getExampleImage} + hasExampleImage={hasExampleImage} + onGenerateExampleImage={() => onGenerateExampleImage(card)} router={router} /> ))} @@ -537,11 +539,13 @@ interface FlashcardItemProps { onToggleFavorite: () => void getCEFRColor: (level: string) => string highlightSearchTerm: (text: string, term: string) => React.ReactNode - getExampleImage: (word: string) => string + getExampleImage: (word: string) => string | null + hasExampleImage: (word: string) => boolean + onGenerateExampleImage: () => void router: any } -function FlashcardItem({ card, searchTerm, onEdit, onDelete, onToggleFavorite, getCEFRColor, highlightSearchTerm, getExampleImage, router }: FlashcardItemProps) { +function FlashcardItem({ card, searchTerm, onEdit, onDelete, onToggleFavorite, getCEFRColor, highlightSearchTerm, getExampleImage, hasExampleImage, onGenerateExampleImage, router }: FlashcardItemProps) { return (