/** * Flashcard 相關工具函數 * 統一管理詞卡相關的顯示和處理邏輯 */ // 詞性簡寫轉換 export const getPartOfSpeechDisplay = (partOfSpeech: string): string => { const shortMap: {[key: string]: string} = { 'noun': 'n.', 'verb': 'v.', 'adjective': 'adj.', 'adverb': 'adv.', 'pronoun': 'pron.', 'conjunction': 'conj.', 'preposition': 'prep.', 'interjection': 'int.', 'idiom': 'idiom' } // 處理複合詞性 (如 "preposition/adverb") if (partOfSpeech?.includes('/')) { return partOfSpeech.split('/').map(p => shortMap[p.trim()] || p.trim()).join('/') } return shortMap[partOfSpeech] || partOfSpeech || '' } // CEFR等級顏色獲取 export const getCEFRColor = (level: string): string => { switch (level) { case 'A1': return 'bg-green-100 text-green-700 border-green-200' case 'A2': return 'bg-blue-100 text-blue-700 border-blue-200' case 'B1': return 'bg-yellow-100 text-yellow-700 border-yellow-200' case 'B2': return 'bg-orange-100 text-orange-700 border-orange-200' case 'C1': return 'bg-red-100 text-red-700 border-red-200' case 'C2': return 'bg-purple-100 text-purple-700 border-purple-200' default: return 'bg-gray-100 text-gray-700 border-gray-200' } } // 熟練度等級顏色獲取 export const getMasteryColor = (level: number): string => { if (level >= 90) return 'bg-green-100 text-green-800' if (level >= 70) return 'bg-yellow-100 text-yellow-800' if (level >= 50) return 'bg-orange-100 text-orange-800' return 'bg-red-100 text-red-800' } // 熟練度等級文字 export const getMasteryText = (level: number): string => { if (level >= 90) return '精通' if (level >= 70) return '熟悉' if (level >= 50) return '理解' return '學習中' } // 下次複習時間格式化 export const formatNextReviewDate = (dateString: string): string => { const reviewDate = new Date(dateString) const now = new Date() const diffInDays = Math.ceil((reviewDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24)) if (diffInDays < 0) return '需要複習' if (diffInDays === 0) return '今天' if (diffInDays === 1) return '明天' return `${diffInDays}天後` } // 詞卡創建時間格式化 export const formatCreatedDate = (dateString: string): string => { return new Date(dateString).toLocaleDateString('zh-TW') } // 獲取例句圖片URL (統一邏輯) export const getFlashcardImageUrl = (flashcard: any): string | null => { // 優先使用 primaryImageUrl if (flashcard.primaryImageUrl) { // 如果是相對路徑,加上後端基礎 URL if (flashcard.primaryImageUrl.startsWith('/')) { return `http://localhost:5008${flashcard.primaryImageUrl}` } return flashcard.primaryImageUrl } // 然後檢查 exampleImages 陣列 if (flashcard.exampleImages && flashcard.exampleImages.length > 0) { const primaryImage = flashcard.exampleImages.find((img: any) => img.isPrimary) if (primaryImage) { const imageUrl = primaryImage.imageUrl return imageUrl?.startsWith('/') ? `http://localhost:5008${imageUrl}` : imageUrl } const firstImageUrl = flashcard.exampleImages[0].imageUrl return firstImageUrl?.startsWith('/') ? `http://localhost:5008${firstImageUrl}` : firstImageUrl } return null } // 詞卡統計計算 export const calculateFlashcardStats = (flashcards: any[]) => { const total = flashcards.length const mastered = flashcards.filter(card => card.masteryLevel >= 80).length const learning = flashcards.filter(card => card.masteryLevel >= 40 && card.masteryLevel < 80).length const new_cards = flashcards.filter(card => card.masteryLevel < 40).length const favorites = flashcards.filter(card => card.isFavorite).length return { total, mastered, learning, new: new_cards, favorites, masteryPercentage: total > 0 ? Math.round((mastered / total) * 100) : 0 } }