fix(frontend): improve glossary selector responsiveness and add contextual warning logic
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 3m10s

This commit is contained in:
2026-05-31 11:24:52 +02:00
parent 58d9d8a74c
commit f33da82c29

View File

@@ -309,6 +309,31 @@ export function GlossarySelector({ sourceLang, targetLang, isPro, mode, glossary
) : isGlossaryEnabled ? ( ) : isGlossaryEnabled ? (
<div className="space-y-3 animate-fade-in"> <div className="space-y-3 animate-fade-in">
{/* Help Info text */}
<p className="text-[10.5px] text-brand-dark/60 dark:text-white/40 leading-normal font-light">
Le glossaire force la traduction de termes précis. Choisissez un glossaire dont la <strong>langue source</strong> correspond à la langue d'origine de votre document.
</p>
{/* Mismatch Warning */}
{selected && sourceLang !== 'auto' && selected.source_language !== sourceLang && (
<div className="flex items-start gap-1.5 p-2 rounded-lg bg-amber-500/10 border border-amber-500/20 text-amber-600 dark:text-amber-400 text-[10px] leading-normal font-medium animate-fade-in">
<span className="shrink-0 text-amber-500">⚠️</span>
<span>
<strong>Attention :</strong> Ce glossaire utilise la langue source <strong>{getFlag(selected.source_language)} {selected.source_language.toUpperCase()}</strong>, mais votre document est configuré en <strong>{getFlag(sourceLang)} {sourceLang.toUpperCase()}</strong>.
</span>
</div>
)}
{/* Incompatibility Warning */}
{selected && selected.source_language === targetLang && (
<div className="flex items-start gap-1.5 p-2 rounded-lg bg-red-500/10 border border-red-500/20 text-red-600 dark:text-red-400 text-[10px] leading-normal font-medium animate-fade-in">
<span className="shrink-0 text-red-500">⚠️</span>
<span>
<strong>Incompatibilité :</strong> La langue source du glossaire est identique à la langue cible de traduction ({getFlag(targetLang)}). Les termes ne seront pas appliqués correctement.
</span>
</div>
)}
{/* Select Glossary Trigger button */} {/* Select Glossary Trigger button */}
<div className="relative"> <div className="relative">
<button <button
@@ -458,10 +483,16 @@ export function GlossarySelector({ sourceLang, targetLang, isPro, mode, glossary
{/* Empty State */} {/* Empty State */}
{filteredGlossaries.length === 0 && filteredTemplates.length === 0 && ( {filteredGlossaries.length === 0 && filteredTemplates.length === 0 && (
<div className="px-2.5 py-4 text-center"> <div className="px-2.5 py-4 text-center">
<p className="text-xs text-brand-dark/45 dark:text-white/45 italic mb-3"> <p className="text-xs text-brand-dark/45 dark:text-white/45 italic mb-3 font-light">
Aucun glossaire ni modèle disponible pour la langue {sourceFlag || sourceLang.toUpperCase()}. Aucun glossaire ni modèle pour la langue source {sourceFlag || sourceLang.toUpperCase()}.
</p> </p>
<div className="flex flex-col gap-1.5"> <div className="flex flex-col gap-1.5">
<a
href={`/dashboard/glossaries?new=true&source=${sourceLang}`}
className="w-full py-2 px-2 bg-brand-dark dark:bg-white text-white dark:text-brand-dark hover:opacity-90 rounded-lg text-xs font-bold uppercase tracking-wider block text-center transition-opacity cursor-pointer"
>
Créer un glossaire {sourceLang === 'auto' ? '' : sourceLang.toUpperCase()}
</a>
{filterByLang && (glossaries.length > 0 || templates.length > 0) && ( {filterByLang && (glossaries.length > 0 || templates.length > 0) && (
<button <button
type="button" type="button"
@@ -471,12 +502,6 @@ export function GlossarySelector({ sourceLang, targetLang, isPro, mode, glossary
Afficher tous les glossaires Afficher tous les glossaires
</button> </button>
)} )}
<a
href="/dashboard/glossaries"
className="w-full py-2 px-2 bg-brand-dark dark:bg-white text-white dark:text-brand-dark hover:opacity-90 rounded-lg text-xs font-bold uppercase tracking-wider block text-center transition-opacity cursor-pointer"
>
Créer un glossaire
</a>
</div> </div>
</div> </div>
)} )}
@@ -524,7 +549,7 @@ export function GlossarySelector({ sourceLang, targetLang, isPro, mode, glossary
{/* Ultra-neat Quick Term Adder */} {/* Ultra-neat Quick Term Adder */}
{selected && ( {selected && (
<form onSubmit={handleAddTerm} className="flex gap-1.5"> <form onSubmit={handleAddTerm} className="grid grid-cols-2 gap-2">
<input <input
type="text" type="text"
required required
@@ -532,29 +557,31 @@ export function GlossarySelector({ sourceLang, targetLang, isPro, mode, glossary
value={newSource} value={newSource}
onChange={(e) => setNewSource(e.target.value)} onChange={(e) => setNewSource(e.target.value)}
disabled={isAddingTerm || disabled} disabled={isAddingTerm || disabled}
className="flex-1 bg-white dark:bg-[#1a1a1a] border border-black/5 dark:border-white/5 rounded-lg px-2.5 py-1.5 text-xs font-semibold text-brand-dark dark:text-white placeholder:text-brand-dark/30 outline-none focus:border-brand-accent" className="w-full bg-white dark:bg-[#1a1a1a] border border-black/5 dark:border-white/5 rounded-lg px-2.5 py-1.5 text-xs font-semibold text-brand-dark dark:text-white placeholder:text-brand-dark/30 outline-none focus:border-brand-accent min-w-0"
/> />
<input <div className="flex gap-1.5">
type="text" <input
required type="text"
placeholder="Traduction" required
value={newTarget} placeholder="Traduction"
onChange={(e) => setNewTarget(e.target.value)} value={newTarget}
disabled={isAddingTerm || disabled} onChange={(e) => setNewTarget(e.target.value)}
className="flex-1 bg-white dark:bg-[#1a1a1a] border border-black/5 dark:border-white/5 rounded-lg px-2.5 py-1.5 text-xs font-semibold text-brand-dark dark:text-white placeholder:text-brand-dark/30 outline-none focus:border-brand-accent" disabled={isAddingTerm || disabled}
/> className="flex-1 bg-white dark:bg-[#1a1a1a] border border-black/5 dark:border-white/5 rounded-lg px-2.5 py-1.5 text-xs font-semibold text-brand-dark dark:text-white placeholder:text-brand-dark/30 outline-none focus:border-brand-accent min-w-0"
<button />
type="submit" <button
disabled={isAddingTerm || disabled || !newSource.trim() || !newTarget.trim()} type="submit"
className="px-3 bg-brand-dark dark:bg-white text-white dark:text-brand-dark rounded-lg flex items-center justify-center disabled:opacity-35 transition-colors cursor-pointer" disabled={isAddingTerm || disabled || !newSource.trim() || !newTarget.trim()}
title="Ajouter le terme" className="px-3 bg-brand-dark dark:bg-white text-white dark:text-brand-dark rounded-lg flex items-center justify-center disabled:opacity-35 transition-colors cursor-pointer shrink-0"
> title="Ajouter le terme"
{isAddingTerm ? ( >
<Loader2 size={12} className="animate-spin" /> {isAddingTerm ? (
) : ( <Loader2 size={12} className="animate-spin" />
<Plus size={14} /> ) : (
)} <Plus size={14} />
</button> )}
</button>
</div>
</form> </form>
)} )}
</div> </div>