'use client' import React, { useState, useCallback, useRef, useEffect } from 'react' /** Supported language pairs */ const LANGUAGES = [ { code: 'en', label: 'Englisch' }, { code: 'de', label: 'Deutsch' }, { code: 'fr', label: 'Franzoesisch' }, { code: 'es', label: 'Spanisch' }, { code: 'it', label: 'Italienisch' }, { code: 'pt', label: 'Portugiesisch' }, { code: 'nl', label: 'Niederlaendisch' }, { code: 'tr', label: 'Tuerkisch' }, { code: 'ru', label: 'Russisch' }, { code: 'ar', label: 'Arabisch' }, { code: 'uk', label: 'Ukrainisch' }, { code: 'pl', label: 'Polnisch' }, { code: 'sv', label: 'Schwedisch' }, { code: 'da', label: 'Daenisch' }, { code: 'fi', label: 'Finnisch' }, { code: 'el', label: 'Griechisch' }, { code: 'hu', label: 'Ungarisch' }, { code: 'cs', label: 'Tschechisch' }, { code: 'ro', label: 'Rumaenisch' }, ] export interface UnitWord { id: string source_text: string target_text: string pos?: string is_custom?: boolean } interface Props { isDark: boolean glassCard: string glassInput: string selectedWords: UnitWord[] onWordsChange: (words: UnitWord[]) => void onCreateUnit: (title: string, sourceLang: string, targetLang: string) => void isCreating: boolean noSearchResults?: boolean searchQuery?: string } export default function UnitBuilder({ isDark, glassCard, glassInput, selectedWords, onWordsChange, onCreateUnit, isCreating, noSearchResults, searchQuery, }: Props) { const [unitTitle, setUnitTitle] = useState('') const [sourceLang, setSourceLang] = useState('de') const [targetLang, setTargetLang] = useState('en') const [showManualEntry, setShowManualEntry] = useState(false) const [manualSource, setManualSource] = useState('') const [manualTarget, setManualTarget] = useState('') const [suggestions, setSuggestions] = useState<{ source_text: string; target_text: string; pos?: string }[]>([]) const [isLookingUp, setIsLookingUp] = useState(false) const debounceRef = useRef>(null) // Auto-suggest translation when typing in source field useEffect(() => { if (!manualSource.trim() || manualSource.length < 2) { setSuggestions([]) return } if (debounceRef.current) clearTimeout(debounceRef.current) debounceRef.current = setTimeout(async () => { setIsLookingUp(true) try { const resp = await fetch( `/api/vocabulary/lookup-translation?word=${encodeURIComponent(manualSource)}&source=${sourceLang}&target=${targetLang}&limit=5` ) if (resp.ok) { const data = await resp.json() setSuggestions(data.results || []) // Auto-fill target if exactly one match if (data.results?.length === 1 && !manualTarget) { setManualTarget(data.results[0].target_text) } } } catch { /* ignore */ } setIsLookingUp(false) }, 400) return () => { if (debounceRef.current) clearTimeout(debounceRef.current) } }, [manualSource, sourceLang, targetLang]) // eslint-disable-line react-hooks/exhaustive-deps const addManualWord = useCallback(() => { if (!manualSource.trim() || !manualTarget.trim()) return const newWord: UnitWord = { id: `custom_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`, source_text: manualSource.trim(), target_text: manualTarget.trim(), is_custom: true, } onWordsChange([...selectedWords, newWord]) setManualSource('') setManualTarget('') setSuggestions([]) }, [manualSource, manualTarget, selectedWords, onWordsChange]) const removeWord = useCallback((id: string) => { onWordsChange(selectedWords.filter(w => w.id !== id)) }, [selectedWords, onWordsChange]) const swapLanguages = useCallback(() => { setSourceLang(targetLang) setTargetLang(sourceLang) }, [sourceLang, targetLang]) const srcLabel = LANGUAGES.find(l => l.code === sourceLang)?.label || sourceLang.toUpperCase() const tgtLabel = LANGUAGES.find(l => l.code === targetLang)?.label || targetLang.toUpperCase() return (

Lernunit erstellen

{/* Language pair selector */}
setUnitTitle(e.target.value)} placeholder="Titel (z.B. Unit 3 - Food)" className={`w-full px-4 py-2.5 rounded-xl border outline-none text-sm mb-3 ${glassInput}`} /> {/* Manual word entry toggle */} {/* Manual entry form */} {showManualEntry && (
setManualSource(e.target.value)} placeholder={`z.B. ${sourceLang === 'de' ? 'schottisches Hochland' : 'Scottish Highlands'}`} className={`w-full px-3 py-2 rounded-lg border outline-none text-sm ${glassInput}`} onKeyDown={e => e.key === 'Enter' && manualTarget && addManualWord()} />
setManualTarget(e.target.value)} placeholder={`z.B. ${targetLang === 'en' ? 'Scottish Highlands' : 'schottisches Hochland'}`} className={`w-full px-3 py-2 rounded-lg border outline-none text-sm ${glassInput}`} onKeyDown={e => e.key === 'Enter' && manualSource && addManualWord()} />
{/* Auto-suggest results */} {suggestions.length > 1 && (
Vorschlaege: {suggestions.map((s, i) => ( ))}
)}
)} {/* "No results" prompt to add manually */} {noSearchResults && searchQuery && !showManualEntry && (

"{searchQuery}" nicht im Woerterbuch

)} {/* Word list */} {selectedWords.length === 0 ? (

Woerter aus dem Woerterbuch auswaehlen oder eigene eingeben

) : (
{selectedWords.map((w, i) => (
{i+1}
{w.source_text} {w.target_text}
{w.is_custom && ( eigen )}
))}
)}
{selectedWords.length} Woerter · {sourceLang.toUpperCase()} → {targetLang.toUpperCase()}
) }