70 lines
2.2 KiB
TypeScript
70 lines
2.2 KiB
TypeScript
import { useMemo, useCallback } from 'react'
|
|
import { getCEFRColor } from '@/lib/utils/flashcardUtils'
|
|
import type { WordAnalysis } from '@/lib/types/word'
|
|
|
|
export function useWordAnalysis() {
|
|
const getWordProperty = useCallback((analysis: WordAnalysis, property: keyof WordAnalysis, fallback: any = 'N/A') => {
|
|
if (!analysis) return fallback
|
|
const value = analysis[property]
|
|
|
|
if (value === undefined || value === null || value === '') {
|
|
return fallback
|
|
}
|
|
|
|
if (Array.isArray(value) && value.length === 0) {
|
|
return fallback
|
|
}
|
|
|
|
return value
|
|
}, [])
|
|
|
|
const findWordAnalysis = useCallback((word: string, analysis: Record<string, WordAnalysis> = {}) => {
|
|
const cleanWord = word.toLowerCase().replace(/[^\w]/g, '')
|
|
|
|
const directMatch = analysis[word] || analysis[cleanWord]
|
|
if (directMatch) return directMatch
|
|
|
|
const keys = Object.keys(analysis)
|
|
const matchKey = keys.find(key =>
|
|
key.toLowerCase().replace(/[^\w]/g, '') === cleanWord
|
|
)
|
|
|
|
return matchKey ? analysis[matchKey] : null
|
|
}, [])
|
|
|
|
const getWordClass = useCallback((word: string, analysis: Record<string, WordAnalysis> = {}) => {
|
|
const wordAnalysis = findWordAnalysis(word, analysis)
|
|
if (!wordAnalysis) return 'cursor-default text-gray-900'
|
|
|
|
let classes = 'cursor-pointer transition-all duration-200 '
|
|
|
|
if (wordAnalysis.isIdiom) {
|
|
classes += 'bg-purple-100 text-purple-800 border-b-2 border-purple-300 hover:bg-purple-200 font-medium'
|
|
} else {
|
|
const cefrColor = getCEFRColor(wordAnalysis.cefr)
|
|
classes += `underline decoration-2 hover:bg-opacity-20 ${cefrColor.replace('border-', 'decoration-').replace('text-', 'hover:bg-')}`
|
|
}
|
|
|
|
return classes
|
|
}, [findWordAnalysis])
|
|
|
|
const shouldShowStar = useCallback((analysis: WordAnalysis) => {
|
|
if (!analysis) return false
|
|
|
|
const conditions = [
|
|
analysis.isHighValue,
|
|
analysis.learningPriority === 'high',
|
|
analysis.cefr && ['B2', 'C1', 'C2'].includes(analysis.cefr),
|
|
analysis.frequency === 'high'
|
|
]
|
|
|
|
return conditions.some(Boolean)
|
|
}, [])
|
|
|
|
return {
|
|
getWordProperty,
|
|
findWordAnalysis,
|
|
getWordClass,
|
|
shouldShowStar
|
|
}
|
|
} |