import React, { useState, useCallback, useMemo } from ‘react’;
import { fetchWordFamily } from ‘./services/geminiService’;
import { WordFamilyResponse, WordInfo } from ‘./types’;
import { SearchIcon, BookOpenIcon, TagIcon, LightbulbIcon } from ‘./components/Icons’;
const WordDetailSection: React.FC<{ title: string; items: string[]; icon: React.ReactNode }> = ({ title, items, icon }) => {
if (!items || items.length === 0) return null;
return (
{icon}
{title}
-
- {items.map((item, index) => (
- {item}
))}
);
};
const WordFamilyCard: React.FC<{ info: WordInfo }> = ({ info }) => (
{info.word}
{info.wordClass}
{info.ipa} – {info.vietnameseMeaning}
Example:”{info.example}”
} />
} />
Grammar Note
{info.grammarNote}
);
const App: React.FC = () => {
const [searchTerm, setSearchTerm] = useState(”);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const [wordData, setWordData] = useState(null);
const [activeFilter, setActiveFilter] = useState(‘all’);
const handleSearch = useCallback(async (e: React.FormEvent) => {
e.preventDefault();
if (!searchTerm.trim()) {
setError(“Please enter a word to search.”);
return;
}
setIsLoading(true);
setError(null);
setWordData(null);
setActiveFilter(‘all’);
try {
const data = await fetchWordFamily(searchTerm.trim());
setWordData(data);
} catch (err) {
setError(err instanceof Error ? err.message : “An unknown error occurred.”);
} finally {
setIsLoading(false);
}
}, [searchTerm]);
const filteredWordFamily = useMemo(() => {
if (!wordData) return [];
if (activeFilter === ‘all’) return wordData.wordFamily;
return wordData.wordFamily.filter(word => word.wordClass.toLowerCase().startsWith(activeFilter));
}, [wordData, activeFilter]);
const wordClasses = useMemo(() => {
if (!wordData) return [];
const classes = wordData.wordFamily.map(w => w.wordClass.toLowerCase().split(‘ ‘)[0]);
return [‘all’, …Array.from(new Set(classes))];
}, [wordData]);
return (
Word Family Explorer
Your expert guide to English vocabulary, word families, and collocations.
{error && (
Error
{error}
)}
{wordData && (
Root Word: {wordData.rootWord.word}
{wordData.rootWord.ipa} – {wordData.rootWord.vietnameseMeaning}
{wordData.wordFamily.length > 0 && (
))}
)}
{Object.keys(wordData.relatedByTopic).length > 0 && (
Related Words by Topic
// FIX: Add Array.isArray type guard to fix type inference issue with Object.entries.
(Array.isArray(words) && words.length > 0) &&
{topic.replace(/([A-Z])/g, ‘ $1’).trim()}
{word}
))}
))}
)}
)}
{!isLoading && !wordData && !error && (
Start Your Search
Discover word families, collocations, and more.
Just type a word above and press Search.
)}
);
};
export default App;
