From fecb3f7abbf2c1a3a03477a9244acb89b58c0920 Mon Sep 17 00:00:00 2001 From: sepehr Date: Sun, 31 May 2026 13:02:19 +0200 Subject: [PATCH] ux(glossaries): add how-it-works guide, status badges and activation hints --- .../src/app/dashboard/glossaries/page.tsx | 312 +++++++++++++----- 1 file changed, 221 insertions(+), 91 deletions(-) diff --git a/frontend/src/app/dashboard/glossaries/page.tsx b/frontend/src/app/dashboard/glossaries/page.tsx index 878ac95..2333552 100644 --- a/frontend/src/app/dashboard/glossaries/page.tsx +++ b/frontend/src/app/dashboard/glossaries/page.tsx @@ -4,9 +4,12 @@ import { useState, useEffect } from 'react'; import { BookText, Plus, Library, Calendar, Hash, Zap, Save, Trash2, MessageSquare, Loader2, - Wrench, HardHat, Monitor, Scale, Stethoscope, BarChart3, - Megaphone, Car, ShoppingCart, FlaskConical, Users, + Monitor, Scale, Stethoscope, BarChart3, + Megaphone, ShoppingCart, FlaskConical, Users, + CheckCircle2, AlertCircle, ArrowRight, MousePointerClick, + Info, ExternalLink, } from 'lucide-react'; +import Link from 'next/link'; import { useUser } from '@/app/dashboard/useUser'; import { useI18n } from '@/lib/i18n'; import { useGlossaries, useGlossary } from './useGlossaries'; @@ -54,10 +57,10 @@ export default function GlossariesPage() { const [editDialogOpen, setEditDialogOpen] = useState(false); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [selectedGlossary, setSelectedGlossary] = useState(null); - const [glossaryToEdit, setGlossaryToEdit] = useState(null); const [glossaryToDelete, setGlossaryToDelete] = useState<{ id: string; name: string } | null>(null); const [systemPrompt, setSystemPrompt] = useState(settings.systemPrompt); const [isSavingPrompt, setIsSavingPrompt] = useState(false); + const [promptSaved, setPromptSaved] = useState(false); const [creatingPreset, setCreatingPreset] = useState(null); const { glossary: fullGlossary, isLoading: isLoadingGlossaryDetail } = useGlossary( @@ -67,16 +70,23 @@ export default function GlossariesPage() { const isPro = user?.tier === 'pro'; const isLoading = isLoadingUser || isLoadingGlossaries; + // Track whether prompt has unsaved changes + const promptHasUnsavedChanges = systemPrompt !== settings.systemPrompt; + const promptIsActive = !!settings.systemPrompt?.trim(); + useEffect(() => { setSystemPrompt(settings.systemPrompt); - }, [settings]); + 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); } }; @@ -213,7 +223,7 @@ export default function GlossariesPage() {
-

Loading...

+

Chargement...

); @@ -237,8 +247,9 @@ export default function GlossariesPage() { return (
+ {/* ── Editorial Header ───────────────────────────────────── */} -
+
{t('glossaries.yourGlossaries') || "Vos Glossaires"} @@ -260,58 +271,150 @@ export default function GlossariesPage() {
-
+ {/* ── Comment ça marche ─────────────────────────────────── */} +
+
+ + Comment ces paramètres sont utilisés +
+
+ {/* Step 1 */} +
+
1
+
+

Configurez ici

+

+ Rédigez vos instructions de contexte ou créez/importez un glossaire de termes. +

+
+
+ {/* Arrow */} +
+ +
+ {/* Step 2 */} +
+
2
+
+

Activez dans Traduire

+

+ Sur la page de traduction, dans la colonne de droite, sélectionnez votre glossaire. +

+
+
+
+
+

+ ⚠️ Les instructions de contexte s'appliquent automatiquement à toutes vos traductions IA une fois enregistrées. Les glossaires doivent être sélectionnés manuellement sur la page Traduire. +

+ + Aller à Traduire + +
+
+ +
+ {/* ── System Prompt ────────────────────────────────────── */}
-
- -

- {t('context.instructions.title')} -

+ {/* Header with status badge */} +
+
+ +

+ {t('context.instructions.title')} +

+
+ {/* Status badge */} + {promptHasUnsavedChanges ? ( + + + Non enregistré + + ) : promptIsActive ? ( + + + Actif · s'applique à toutes les traductions IA + + ) : ( + + Inactif + + )}
-

- {t('context.instructions.desc')} -

+ + {/* Explanation box */} +
+

+ À quoi ça sert ? Ces instructions sont envoyées automatiquement à l'IA avant chaque traduction, sans que vous ayez besoin de faire quoi que ce soit sur la page Traduire. Utilisez-les pour guider le style, le registre ou la terminologie générale. +

+

+ Exemple : « Vous traduisez des rapports financiers. Soyez formel, précis et conservez tous les chiffres. » +

+
+