version nice
This commit is contained in:
220
app/components/FileUploadComponent.tsx
Normal file
220
app/components/FileUploadComponent.tsx
Normal file
@@ -0,0 +1,220 @@
|
||||
import { Upload, FileText, AlertTriangle } from "lucide-react";
|
||||
import { SampleTextComponent } from "./SampleTextComponent";
|
||||
import { SupportedDataTypes } from "./SupportedDataTypes";
|
||||
import { AnonymizationInterface } from "./AnonymizationInterface";
|
||||
|
||||
interface FileUploadComponentProps {
|
||||
uploadedFile: File | null;
|
||||
handleFileChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
sourceText: string;
|
||||
setSourceText: (text: string) => void;
|
||||
setUploadedFile: (file: File | null) => void;
|
||||
setFileContent: (content: string) => void;
|
||||
onAnonymize?: () => void;
|
||||
isProcessing?: boolean;
|
||||
canAnonymize?: boolean;
|
||||
isLoadingFile?: boolean;
|
||||
onRestart?: () => void;
|
||||
outputText?: string;
|
||||
}
|
||||
|
||||
export const FileUploadComponent = ({
|
||||
uploadedFile,
|
||||
handleFileChange,
|
||||
sourceText,
|
||||
setSourceText,
|
||||
setUploadedFile,
|
||||
setFileContent,
|
||||
onAnonymize,
|
||||
isProcessing = false,
|
||||
canAnonymize = false,
|
||||
isLoadingFile = false,
|
||||
onRestart,
|
||||
outputText,
|
||||
}: FileUploadComponentProps) => {
|
||||
// Si un fichier est uploadé ou qu'il y a du texte d'exemple, on affiche le preview
|
||||
if (uploadedFile || (sourceText && sourceText.trim())) {
|
||||
return (
|
||||
<div className="w-full flex flex-col space-y-6">
|
||||
{/* Preview du document avec en-tête simple */}
|
||||
<div className="bg-white rounded-2xl border border-gray-100 overflow-hidden">
|
||||
<div className="bg-orange-50 border-b border-orange-200 px-4 sm:px-6 py-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="w-8 h-8 sm:w-10 sm:h-10 bg-orange-100 rounded-lg flex items-center justify-center">
|
||||
<FileText className="h-4 w-4 sm:h-5 sm:w-5 text-orange-600" />
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
{uploadedFile ? (
|
||||
<p className="text-xs sm:text-sm text-orange-600 truncate">
|
||||
{uploadedFile.name} •{" "}
|
||||
{(uploadedFile.size / 1024).toFixed(1)} KB
|
||||
</p>
|
||||
) : (
|
||||
<p className="text-xs sm:text-sm text-orange-600">
|
||||
Demo - Exemple de texte
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-4 sm:p-6">
|
||||
{/* Zone de texte avec limite de hauteur et scroll */}
|
||||
<div className="bg-gray-50 border border-gray-200 rounded-lg p-3 sm:p-4 max-h-48 overflow-y-auto">
|
||||
{isLoadingFile ? (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="animate-spin rounded-full h-5 w-5 sm:h-6 sm:w-6 border-b-2 border-[#f7ab6e]"></div>
|
||||
<span className="text-xs sm:text-sm text-gray-600">
|
||||
Chargement du fichier en cours...
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<pre className="text-xs sm:text-sm text-gray-700 whitespace-pre-wrap font-mono">
|
||||
{sourceText || "Aucun contenu à afficher"}
|
||||
</pre>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Disclaimer déplacé en dessous du texte */}
|
||||
<div className="mt-4">
|
||||
<div className="flex items-start gap-2 p-3 bg-[#f7ab6e] bg-opacity-10 border border-[#f7ab6e] border-opacity-30 rounded-lg">
|
||||
<AlertTriangle className="h-4 w-4 text-[#f7ab6e] mt-0.5 flex-shrink-0" />
|
||||
<p className="text-[10px] sm:text-[11px] text-[#092727] leading-relaxed">
|
||||
Cet outil IA peut ne pas détecter toutes les informations
|
||||
sensibles.
|
||||
<br />
|
||||
Vérifiez le résultat avant de le partager.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Boutons d'action - Responsive mobile */}
|
||||
{canAnonymize && !isLoadingFile && (
|
||||
<div className="flex flex-col sm:flex-row items-center justify-center space-y-4 sm:space-y-0 sm:space-x-4">
|
||||
{/* Bouton Anonymiser en premier */}
|
||||
{onAnonymize && (
|
||||
<button
|
||||
onClick={onAnonymize}
|
||||
disabled={isProcessing}
|
||||
className="w-full sm:w-auto bg-[#f7ab6e] hover:bg-[#f7ab6e]/90 disabled:opacity-50 disabled:cursor-not-allowed text-white px-6 py-3 rounded-lg text-sm font-medium transition-colors duration-300 flex items-center justify-center space-x-3"
|
||||
>
|
||||
{isProcessing ? (
|
||||
<>
|
||||
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
|
||||
<span>Anonymisation en cours...</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
|
||||
/>
|
||||
</svg>
|
||||
<span>Anonymiser mes données</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
||||
{/* Bouton Recommencer */}
|
||||
{onRestart && (
|
||||
<button
|
||||
onClick={onRestart}
|
||||
className="w-full sm:w-auto bg-gray-500 hover:bg-gray-600 text-white px-6 py-3 rounded-lg text-sm font-medium transition-colors duration-300 flex items-center justify-center space-x-2"
|
||||
>
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
|
||||
/>
|
||||
</svg>
|
||||
<span>Recommencer</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Affichage conditionnel : Interface d'anonymisation OU Types de données supportées */}
|
||||
{isProcessing || outputText ? (
|
||||
<AnonymizationInterface
|
||||
isProcessing={isProcessing}
|
||||
outputText={outputText}
|
||||
sourceText={sourceText}
|
||||
/>
|
||||
) : (
|
||||
<SupportedDataTypes />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Si pas de fichier ni de texte, on affiche la zone de drop
|
||||
return (
|
||||
<div className="w-full flex flex-col space-y-5">
|
||||
{/* Drop Zone - Responsive */}
|
||||
<label className="flex flex-col items-center justify-center cursor-pointer group transition-all duration-300 border-2 border-dashed border-[#092727] rounded-xl bg-gray-50 hover:bg-gray-100 hover:border-[#0a3030] p-6 sm:p-8">
|
||||
{/* Upload Icon */}
|
||||
<div className="w-12 h-12 sm:w-16 sm:h-16 bg-[#f7ab6e] group-hover:bg-[#f7ab6e]/75 rounded-full flex items-center justify-center mb-4 transition-colors duration-300">
|
||||
<Upload className="h-6 w-6 sm:h-8 sm:w-8 text-white transition-colors duration-300" />
|
||||
</div>
|
||||
|
||||
{/* Main Text */}
|
||||
<h3 className="text-base sm:text-lg font-semibold text-[#092727] mb-2 group-hover:text-[#0a3030] transition-colors duration-300 text-center">
|
||||
Déposer votre fichier ici
|
||||
</h3>
|
||||
<p className="text-sm sm:text-base text-[#092727] opacity-80 mb-4 text-center group-hover:opacity-90 transition-opacity duration-300">
|
||||
ou cliquez pour sélectionner un fichier
|
||||
</p>
|
||||
|
||||
{/* File Info */}
|
||||
<div className="flex flex-col sm:flex-row items-center gap-2 text-xs sm:text-sm text-[#092727] opacity-70">
|
||||
<span>📄 Fichiers TXT, PDF</span>
|
||||
<span className="hidden sm:inline">•</span>
|
||||
<span>Max 5MB</span>
|
||||
</div>
|
||||
|
||||
{/* Hidden Input */}
|
||||
<input
|
||||
type="file"
|
||||
onChange={handleFileChange}
|
||||
accept=".txt,.pdf"
|
||||
className="hidden"
|
||||
/>
|
||||
</label>
|
||||
|
||||
{/* Bouton d'exemple repositionné juste en dessous */}
|
||||
<div className="flex justify-center">
|
||||
<SampleTextComponent
|
||||
setSourceText={setSourceText}
|
||||
setFileContent={setFileContent}
|
||||
setUploadedFile={setUploadedFile}
|
||||
variant="button"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Supported Data Types */}
|
||||
<SupportedDataTypes />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user