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
-
-
-
-
Modèle Mistral
-
setLlmModel(e.target.value)}
- placeholder="mistral-large-latest"
- />
-
Nom du modèle Mistral à utiliser pour l'extraction
-
-
-
-
Rétention des logs LLM (mois)
-
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)
-
-
-
-
- Numéro de facture
-
-
-
- Bon de livraison
-
-
-
- Numéro de commande
-
-
-
- Fournisseur
-
-
-
- Montant total
-
-
-
-
-
-
- {/* SFTP Configuration */}
-
-
- Configuration SFTP
- Paramètres d'export vers un serveur SFTP
-
-
-
-
-
-
-
-
Chemin distant
-
setSftpRemotePath(e.target.value)}
- placeholder="/invoices"
- />
-
- Les fichiers seront organisés par date: /chemin/YYYY/MM/DD/
-
-
-
-
-
-
Export automatique
-
- Exporter automatiquement les factures après extraction
-
-
-
-
-
-
+
+
- {testSftpMutation.isPending ? (
-
- ) : (
-
+
+ Intelligence AI
+
+
+
+ Mots-clés
+
+
+
+ Export SFTP
+ {isSftpConfigured && (
+
+ Configuré
+
)}
- Tester la connexion
-
-
-
+
+
- {/* Save button */}
-
-
+ {/* LLM Tab */}
+
+
+
+
+
+
+
+
+ Configuration du modèle AI
+
+ Paramètres du modèle d'extraction Mistral AI
+
+
+
+
+
+
+
Modèle Mistral
+
setLlmModel(e.target.value)}
+ placeholder="mistral-large-latest"
+ className="h-11"
+ />
+
+
+ Nom du modèle Mistral à utiliser pour l'extraction
+
+
+
+
+
+ Rétention des logs (mois)
+
+
setLlmLogsRetentionMonths(parseInt(e.target.value) || 3)}
+ min={1}
+ max={12}
+ className="h-11"
+ />
+
+
+ Durée de conservation des logs LLM (1-12 mois)
+
+
+
+
+
+
+
+
+
+
+
+
+ Champs de détection
+
+ Configurez quels champs sont obligatoires pour un score de 100%
+
+
+
+
+
+
+
+
+
+
+ {/* Keywords Tab */}
+
+
+
+
+
+
+
+
+ Mots-clés personnalisés
+
+ Améliorez la détection en ajoutant vos propres mots-clés (séparés par des virgules)
+
+
+
+
+
+
+
+
+ Numéro de facture
+
+
+
+
+
+ Bon de livraison
+
+
+
+
+
+ Numéro de commande
+
+
+
+
+
+ Fournisseur
+
+
+
+
+
+ Montant total
+
+
+
+
+
+
+
+
+
+ {/* SFTP Tab */}
+
+
+
+
+
+
+
+
+ Configuration SFTP
+
+ Paramètres d'export automatique vers un serveur SFTP
+
+
+
+
+
+
+
+
+
+
+
Chemin distant
+
setSftpRemotePath(e.target.value)}
+ placeholder="/invoices"
+ className="h-11"
+ />
+
+
+ Les fichiers seront organisés par date: /chemin/YYYY/MM/DD/
+
+
+
+
+
+
+ Export automatique
+
+
+ Exporter automatiquement les factures après extraction
+
+
+
+
+
+
+
+ {testSftpMutation.isPending ? (
+ <>
+
+ Test en cours...
+ >
+ ) : (
+ <>
+
+ Tester la connexion SFTP
+ >
+ )}
+
+
+
+
+
+
+
+ {/* Save Button */}
+
+
{saveMutation.isPending ? (
-
+ <>
+
+ Enregistrement...
+ >
) : (
-
+ <>
+
+ Enregistrer les paramètres
+ >
)}
- Enregistrer les paramètres
diff --git a/todo.md b/todo.md
index ac073ea..ffe331f 100644
--- a/todo.md
+++ b/todo.md
@@ -382,5 +382,17 @@
- [x] Modifier le code d'extraction (invoiceExtractor.ts) pour utiliser la configuration
- [x] Adapter le calcul du qualityScore selon les champs obligatoires configurés
- [x] Initialiser les valeurs par défaut (supplierName, invoiceNumber, invoiceDate, totalAmount obligatoires)
-- [ ] Tester la configuration et vérifier le calcul du score
+- [x] Tester la configuration et vérifier le calcul du score
+- [x] Déployer sur le VPS
+
+## Modernisation de la page Paramètres
+- [x] Analyser la structure actuelle et identifier les améliorations UX
+- [x] Remplacer le layout par un système de Tabs pour organiser les sections
+- [x] Utiliser des Cards modernes avec ombres et bordures pour chaque section
+- [x] Améliorer la typographie (titres, descriptions, espacements)
+- [x] Ajouter des icônes plus grandes et colorées pour chaque section
+- [x] Implémenter des animations de transition fluides
+- [x] Améliorer le responsive design pour mobile
+- [x] Ajouter des badges de statut (Actif/Inactif) avec couleurs
+- [x] Tester localement l'interface modernisée
- [ ] Déployer sur le VPS