import { Upload, FileText, AlertTriangle, Shield, Copy, Download, } from "lucide-react"; import { SampleTextComponent } from "./SampleTextComponent"; import { SupportedDataTypes } from "./SupportedDataTypes"; import { AnonymizationInterface } from "./AnonymizationInterface"; import { highlightEntities } from "../utils/highlightEntities"; import { useState } from "react"; import { EntityMapping } from "../config/entityLabels"; // Importer l'interface unifiée // Supprimer l'interface locale EntityMapping (lignes 15-21) interface FileUploadComponentProps { uploadedFile: File | null; handleFileChange: (e: React.ChangeEvent) => void; sourceText: string; setSourceText: (text: string) => void; setUploadedFile: (file: File | null) => void; onAnonymize?: () => void; isProcessing?: boolean; canAnonymize?: boolean; isLoadingFile?: boolean; onRestart?: () => void; outputText?: string; copyToClipboard?: () => void; downloadText?: () => void; isExampleLoaded?: boolean; setIsExampleLoaded?: (loaded: boolean) => void; entityMappings?: EntityMapping[]; } export const FileUploadComponent = ({ uploadedFile, handleFileChange, sourceText, setSourceText, setUploadedFile, onAnonymize, isProcessing = false, canAnonymize = false, isLoadingFile = false, onRestart, outputText, copyToClipboard, downloadText, setIsExampleLoaded, entityMappings, }: FileUploadComponentProps) => { const [isDragOver, setIsDragOver] = useState(false); // Fonction pour valider le type de fichier const isValidFileType = (file: File) => { const allowedTypes = ["text/plain", "application/pdf"]; const allowedExtensions = [".txt", ".pdf"]; return ( allowedTypes.includes(file.type) || allowedExtensions.some((ext) => file.name.toLowerCase().endsWith(ext)) ); }; // Gestionnaires de glisser-déposer const handleDragOver = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); }; const handleDragEnter = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); setIsDragOver(true); }; const handleDragLeave = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); // Vérifier si on quitte vraiment la zone de drop if (!e.currentTarget.contains(e.relatedTarget as Node)) { setIsDragOver(false); } }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); setIsDragOver(false); const files = Array.from(e.dataTransfer.files); if (files.length > 0) { const file = files[0]; // Vérifier le type de fichier if (!isValidFileType(file)) { alert( "Type de fichier non supporté. Veuillez sélectionner un fichier PDF ou TXT." ); return; } // Vérifier la taille (5MB max) if (file.size > 5 * 1024 * 1024) { alert("Le fichier est trop volumineux. Taille maximale : 5MB."); return; } const syntheticEvent = { target: { files: [file] }, } as unknown as React.ChangeEvent; handleFileChange(syntheticEvent); } }; // Gestionnaire de changement de fichier modifié pour valider le type const handleFileChangeWithValidation = ( e: React.ChangeEvent ) => { const file = e.target.files?.[0]; if (file && !isValidFileType(file)) { alert( "Type de fichier non supporté. Veuillez sélectionner un fichier PDF ou TXT." ); e.target.value = ""; // Reset l'input return; } handleFileChange(e); }; // On passe en preview seulement si : // 1. Un fichier est uploadé OU // 2. On a un résultat d'anonymisation // (On retire isExampleLoaded pour permettre l'édition du texte d'exemple) if (uploadedFile || outputText) { return (
{/* Si on a un résultat, afficher 2 blocs côte à côte */} {outputText ? (
{/* Preview du document original */}
{uploadedFile ? (

{uploadedFile.name} •{" "} {(uploadedFile.size / 1024).toFixed(1)} KB

) : (

Demo - Exemple de texte

)}
                    {sourceText || "Aucun contenu à afficher"}
                  
{/* Bloc résultat anonymisé */}

Document anonymisé

{/* Boutons d'action */}
{copyToClipboard && ( )} {downloadText && ( )}
{highlightEntities( sourceText || "Aucun contenu à afficher", // Utiliser sourceText au lieu de outputText entityMappings || [] // Fournir un tableau vide par défaut )}
) : ( /* Preview normal quand pas de résultat */
{uploadedFile ? (

{uploadedFile.name} •{" "} {(uploadedFile.size / 1024).toFixed(1)} KB

) : (

Demo - Exemple de texte

)}
{/* Zone de texte avec limite de hauteur et scroll */}
{isLoadingFile ? (
Chargement du fichier en cours...
) : (
                    {sourceText || "Aucun contenu à afficher"}
                  
)}
{/* Disclaimer déplacé en dessous du texte */}

Cet outil IA peut ne pas détecter toutes les informations sensibles. Vérifiez le résultat avant de le partager.

)} {/* Boutons d'action - Responsive mobile */} {canAnonymize && !isLoadingFile && (
{/* Bouton Anonymiser - seulement si pas encore anonymisé */} {onAnonymize && !outputText && ( )} {/* Bouton Recommencer - toujours visible */} {onRestart && ( )}
)} {/* Affichage conditionnel : Interface d'anonymisation OU Types de données supportées */} {isProcessing || outputText ? ( ) : ( )}
); } return (
{/* Deux colonnes côte à côte */}
{/* Colonne gauche - Zone de texte */}
{/* Header avec icône */}
{/* Titre */}

Saisissez votre texte

Tapez ou collez votre texte ici

{/* Zone de texte éditable */}
{/* Zone pour le texte - SANS overflow */}
{" "} {/* Ajout de pb-6 pour le compteur */} {/* Placeholder personnalisé avec lien cliquable */} {!sourceText && (
Commencez à taper du texte, ou 
)}