'use client'; import { useState, useEffect, useMemo } from 'react'; import { Library, Calendar, Hash, MessageSquare, Save, Trash2, Loader2, CheckCircle2, AlertCircle, ArrowRight, Info, Search, Plus, Sparkles, Zap } from 'lucide-react'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; import { cn } from '@/lib/utils'; import { useUser } from '@/app/dashboard/useUser'; import { useI18n } from '@/lib/i18n'; import { useGlossaries } from './useGlossaries'; import type { GlossaryListItem } from './types'; import { ProUpgradePrompt } from './ProUpgradePrompt'; import { useToast } from '@/components/ui/toast'; import { SUPPORTED_LANGUAGES } from './types'; import { useTranslationStore } from '@/lib/store'; // ── Chips de suggestions pour les consignes de contexte ───────────────────── const CONTEXT_SUGGESTIONS = [ { label: 'Ton formel', value: 'Utilise toujours un ton formel et professionnel dans tes traductions.' }, { label: 'Noms propres', value: 'Ne traduis pas les noms propres, marques et noms de personnes.' }, { label: 'Chiffres', value: 'Garde tous les chiffres, pourcentages et montants tels quels sans les modifier.' }, { label: 'Placeholders', value: 'Ne traduis pas les variables entre accolades comme {nom}, {date}, {montant}.' }, { label: 'Termes techniques', value: 'Conserve les termes techniques en langue originale et ne les traduis pas.' }, { label: 'Style concis', value: 'Préfère des formulations courtes et directes. Évite les périphrases.' }, ]; function renderTitle(title: string) { const lastSpaceIndex = title.lastIndexOf(' '); if (lastSpaceIndex === -1) return title; return ( <> {title.substring(0, lastSpaceIndex)}{' '} {title.substring(lastSpaceIndex + 1)} > ); } export default function GlossariesPage() { const { t } = useI18n(); const router = useRouter(); const { data: user, isLoading: isLoadingUser } = useUser(); const { glossaries, isLoading: isLoadingGlossaries } = useGlossaries(); const { toast } = useToast(); const { settings, updateSettings } = useTranslationStore(); const [systemPrompt, setSystemPrompt] = useState(settings.systemPrompt); const [isSavingPrompt, setIsSavingPrompt] = useState(false); const [promptSaved, setPromptSaved] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [activeTab, setActiveTab] = useState<'glossaries' | 'context'>('glossaries'); const isPro = user?.tier === 'pro'; const isLoading = isLoadingUser || isLoadingGlossaries; const currentTargetLang = settings.defaultTargetLanguage; const currentTargetInfo = SUPPORTED_LANGUAGES.find(l => l.code === currentTargetLang); const promptHasUnsavedChanges = systemPrompt !== settings.systemPrompt; const promptIsActive = !!settings.systemPrompt?.trim(); useEffect(() => { setSystemPrompt(settings.systemPrompt); setPromptSaved(false); }, [settings.systemPrompt]); const handleSavePrompt = async () => { setIsSavingPrompt(true); try { updateSettings({ systemPrompt }); await new Promise(resolve => setTimeout(resolve, 300)); setPromptSaved(true); toast({ title: t('context.saved'), description: t('context.savedDesc') }); setTimeout(() => setPromptSaved(false), 3000); } finally { setIsSavingPrompt(false); } }; const handleClearPrompt = () => { updateSettings({ systemPrompt: '' }); setSystemPrompt(''); }; const handleAddSuggestion = (value: string) => { const current = systemPrompt.trim(); const newPrompt = current ? `${current}\n${value}` : value; setSystemPrompt(newPrompt); }; const filteredGlossaries = useMemo(() => { if (!searchQuery.trim()) return glossaries; const q = searchQuery.toLowerCase(); return glossaries.filter((g) => g.name.toLowerCase().includes(q)); }, [glossaries, searchQuery]); if (isLoading) { return (
{t('glossaries.loading')}
{t('glossaries.description') || 'Gérez vos glossaires et instructions de contexte pour des traductions plus précises.'}
Pour utiliser un glossaire dans une traduction :{' '} cliquez sur « Utiliser » sur la carte souhaitée. Vous serez redirigé sur la page Traduire avec ce glossaire déjà sélectionné.
Aller traduireCes instructions sont envoyées automatiquement à l'IA avant chaque traduction en mode Pro LLM.
{glossaries.length > 0 ? `${glossaries.length} glossaire${glossaries.length > 1 ? 's' : ''} — cliquez sur une carte pour la modifier` : 'Aucun glossaire — créez-en un pour commencer'}
{t('glossaries.empty') || 'Aucun glossaire'}
{t('glossaries.emptyDesc') || 'Créez votre premier glossaire pour garantir une terminologie cohérente dans vos traductions.'}
Aucun résultat pour « {searchQuery} »
{srcInfo?.flag ?? '🌐'} {srcInfo?.label ?? glossary.source_language} → {tgtInfo?.flag ?? '🌐'} {tgtInfo?.label ?? glossary.target_language}