import { useState } from 'react' import { genderCheck, translateText } from '../api' import { speak } from '../tts' // Shared "quick tools" — the Gender Checker and Translator from the Tools // screen, also reusable as a side panel while doing exercises (see // Exercises.jsx). // ── Gender Checker ─────────────────────────────────────────────────────────── const GENDER_COLORS = { Masc: '#4A90D9', Fem: '#D96B8A' } const GENDER_LABELS = { Masc: 'Masculine ♂', Fem: 'Feminine ♀' } export function GenderChecker() { const [word, setWord] = useState('') const [data, setData] = useState(null) const [loading, setLoading] = useState(false) const [error, setError] = useState('') const handleCheck = async () => { const w = word.trim() if (!w) return setLoading(true) setError('') try { const result = await genderCheck(w) setData(result) } catch (e) { setError(`Could not check this word: ${e.message}`) } finally { setLoading(false) } } const color = data?.gender ? GENDER_COLORS[data.gender] : 'var(--fc-ink)' return (

Type a French noun to see its gender, articles (le/la, un/une), an example sentence, and a tip for remembering it.

setWord(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleCheck()} placeholder="e.g. pomme, restaurant, voiture…" />
{error &&
⚠ {error}
} {data && (
{data.article ? `${data.article} ` : ''}{data.word}
{data.gender && (
{GENDER_LABELS[data.gender]} {data.article} {data.word} {data.indefinite_article} {data.word}
)} {data.example && (
{data.example}
{data.example_translation &&
{data.example_translation}
}
)} {data.pattern_note &&
💡 {data.pattern_note}
}
)}
) } // ── Translator ─────────────────────────────────────────────────────────────── const DIRECTIONS = [ { id: 'en_fr', label: 'English → French' }, { id: 'fr_en', label: 'French → English' }, ] export function TranslatorWidget({ lessonText, onRemove }) { const [text, setText] = useState('') const [direction, setDirection] = useState('en_fr') const [useContext, setUseContext] = useState(false) const [data, setData] = useState(null) const [loading, setLoading] = useState(false) const [error, setError] = useState('') const handleTranslate = async () => { const t = text.trim() if (!t) return setLoading(true) setError('') try { const result = await translateText(t, direction, useContext ? lessonText : '') setData(result) } catch (e) { setError(`Could not translate: ${e.message}`) } finally { setLoading(false) } } const switchDirection = (id) => { if (id === direction) return setDirection(id) setData(null) } return (
{onRemove && ( )}
{DIRECTIONS.map((d) => ( ))}