diff --git a/client/src/pages/Settings.tsx b/client/src/pages/Settings.tsx index ced9f5e..f18d21d 100644 --- a/client/src/pages/Settings.tsx +++ b/client/src/pages/Settings.tsx @@ -6,8 +6,20 @@ import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Switch } from "@/components/ui/switch"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { Badge } from "@/components/ui/badge"; import { trpc } from "@/lib/trpc"; -import { Loader2, Save, CheckCircle } from "lucide-react"; +import { + Loader2, + Save, + CheckCircle, + Brain, + Key, + Server, + FileCheck, + AlertCircle, + Sparkles +} from "lucide-react"; import { toast } from "sonner"; import { Checkbox } from "@/components/ui/checkbox"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; @@ -35,41 +47,81 @@ function LlmFieldsConfigSection() { if (isLoading) { return ( -
- +
+
); } + const requiredCount = fields?.filter(f => f.isRequired === 1).length || 0; + const totalCount = fields?.length || 0; + return ( -
-

- Les champs marqués comme obligatoires doivent être détectés pour atteindre un score de 100%. - Les champs optionnels n'affectent pas le score. +

+
+
+
+ +
+
+

Configuration actuelle

+

+ {requiredCount} champ{requiredCount > 1 ? 's' : ''} obligatoire{requiredCount > 1 ? 's' : ''} sur {totalCount} +

+
+
+ + Score 100% + +
+ +

+ + + Les champs marqués comme obligatoires doivent être détectés pour atteindre un score de 100%. + Les champs optionnels n'affectent pas le score. +

- - - - Champ - Obligatoire - - - - {fields?.map((field) => ( - - {field.displayName} - - handleToggle(field.fieldName, field.isRequired)} - disabled={updateFieldMutation.isPending} - /> - +
+
+ + + Champ + Statut + Obligatoire - ))} - -
+ + + {fields?.map((field) => ( + + {field.displayName} + + {field.isRequired === 1 ? ( + + Obligatoire + + ) : ( + + Optionnel + + )} + + +
+ handleToggle(field.fieldName, field.isRequired)} + disabled={updateFieldMutation.isPending} + className="data-[state=checked]:bg-green-500 data-[state=checked]:border-green-500" + /> +
+
+
+ ))} +
+ +
); } @@ -114,7 +166,7 @@ export default function Settings() { const saveMutation = trpc.settings.upsert.useMutation({ onSuccess: () => { - toast.success("Paramètres enregistrés"); + toast.success("Paramètres enregistrés avec succès"); utils.settings.get.invalidate(); }, onError: (error) => { @@ -125,9 +177,9 @@ export default function Settings() { const testSftpMutation = trpc.sftp.testConnection.useMutation({ onSuccess: (data) => { if (data.success) { - toast.success("Connexion SFTP réussie"); + toast.success("✓ Connexion SFTP réussie"); } else { - toast.error("Échec de la connexion SFTP"); + toast.error("✗ Échec de la connexion SFTP"); } }, onError: (error) => { @@ -161,250 +213,393 @@ export default function Settings() { if (isLoading) { return ( -
- +
+ +

Chargement des paramètres...

); } + const isSftpConfigured = sftpHost && sftpUsername; + return ( -
-
-

Paramètres

-

Configurez l'extraction et l'export de vos factures

+
+ {/* Header */} +
+
+
+ +
+
+

+ Paramètres +

+

+ Configurez l'extraction et l'export de vos factures +

+
+
- {/* LLM Configuration */} - - - Configuration LLM - Paramètres du modèle d'extraction Mistral AI - - -
- - setLlmModel(e.target.value)} - placeholder="mistral-large-latest" - /> -

Nom du modèle Mistral à utiliser pour l'extraction

-
- -
- - setLlmLogsRetentionMonths(parseInt(e.target.value) || 3)} - min={1} - max={12} - /> -

Durée de conservation des logs LLM (1-12 mois)

-
-
-
- - {/* LLM Fields Configuration */} - - - Champs de détection - - Configurez quels champs sont obligatoires pour atteindre un score de reconnaissance de 100% - - - - - - - - {/* Keywords Configuration */} - - - Mots-clés personnalisés - - Mots-clés pour améliorer la détection des champs (séparés par des virgules) - - - -
- -