164 lines
5.7 KiB
TypeScript
164 lines
5.7 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { FileUploadComponent } from "./components/FileUploadComponent";
|
|
|
|
import { EntityMappingTable } from "./components/EntityMappingTable";
|
|
import { ProgressBar } from "./components/ProgressBar";
|
|
import { useFileHandler } from "./components/FileHandler";
|
|
import { useAnonymization } from "./components/AnonymizationLogic";
|
|
import { useDownloadActions } from "./components/DownloadActions";
|
|
|
|
interface EntityMapping {
|
|
originalValue: string;
|
|
anonymizedValue: string;
|
|
entityType: string;
|
|
startIndex: number;
|
|
endIndex: number;
|
|
}
|
|
|
|
export default function Home() {
|
|
const [sourceText, setSourceText] = useState("");
|
|
const [outputText, setOutputText] = useState("");
|
|
const [uploadedFile, setUploadedFile] = useState<File | null>(null);
|
|
const [fileContent, setFileContent] = useState("");
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [isLoadingFile, setIsLoadingFile] = useState(false);
|
|
const [entityMappings, setEntityMappings] = useState<EntityMapping[]>([]);
|
|
const [isExampleLoaded, setIsExampleLoaded] = useState(false); // NOUVEAU
|
|
|
|
const progressSteps = ["Téléversement", "Prévisualisation", "Anonymisation"];
|
|
|
|
const getCurrentStep = () => {
|
|
if (outputText) return 3;
|
|
if (uploadedFile || (sourceText && sourceText.trim())) return 2;
|
|
return 1;
|
|
};
|
|
|
|
// Fonction pour recommencer (retourner à l'état initial)
|
|
const handleRestart = () => {
|
|
setSourceText("");
|
|
setOutputText("");
|
|
setUploadedFile(null);
|
|
setFileContent("");
|
|
setError(null);
|
|
setIsLoadingFile(false);
|
|
setEntityMappings([]);
|
|
setIsExampleLoaded(false); // NOUVEAU
|
|
};
|
|
|
|
// Hooks personnalisés pour la logique métier
|
|
const { handleFileChange } = useFileHandler({
|
|
setUploadedFile,
|
|
setSourceText,
|
|
setFileContent,
|
|
setError,
|
|
setIsLoadingFile, // Passer le setter
|
|
});
|
|
|
|
const { anonymizeData, isProcessing } = useAnonymization({
|
|
sourceText,
|
|
fileContent,
|
|
uploadedFile,
|
|
setOutputText,
|
|
setError,
|
|
setEntityMappings,
|
|
});
|
|
|
|
const { copyToClipboard, downloadText } = useDownloadActions({ outputText });
|
|
|
|
return (
|
|
<div className="min-h-screen w-full overflow-hidden">
|
|
{/* Main Content */}
|
|
<div className="max-w-6xl mx-auto px-2 sm:px-4 py-4 sm:py-8 space-y-4">
|
|
{/* Progress Bar */}
|
|
<ProgressBar currentStep={getCurrentStep()} steps={progressSteps} />
|
|
|
|
{/* Upload Section */}
|
|
<div className="bg-white rounded-2xl border border-gray-50 overflow-hidden">
|
|
<div className="p-1 sm:p-3">
|
|
<FileUploadComponent
|
|
uploadedFile={uploadedFile}
|
|
handleFileChange={handleFileChange}
|
|
sourceText={sourceText}
|
|
setSourceText={setSourceText}
|
|
setUploadedFile={setUploadedFile}
|
|
setFileContent={setFileContent}
|
|
onAnonymize={anonymizeData}
|
|
isProcessing={isProcessing}
|
|
canAnonymize={
|
|
uploadedFile !== null ||
|
|
Boolean(sourceText && sourceText.trim())
|
|
}
|
|
isLoadingFile={isLoadingFile}
|
|
onRestart={handleRestart}
|
|
outputText={outputText}
|
|
copyToClipboard={copyToClipboard}
|
|
downloadText={downloadText}
|
|
isExampleLoaded={isExampleLoaded}
|
|
setIsExampleLoaded={setIsExampleLoaded}
|
|
entityMappings={entityMappings} // Ajouter cette ligne
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Entity Mapping Table - Seulement si outputText existe */}
|
|
{outputText && (
|
|
<div className="bg-white rounded-2xl border border-gray-100 overflow-hidden">
|
|
<div className="p-1 sm:p-3">
|
|
<EntityMappingTable mappings={entityMappings} />
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Error Message - Version améliorée */}
|
|
{error && (
|
|
<div className="bg-red-50 border border-red-200 rounded-xl p-3 sm:p-4 mx-2 sm:mx-0">
|
|
<div className="flex items-start space-x-3">
|
|
<svg
|
|
className="w-5 h-5 text-red-500 flex-shrink-0 mt-0.5"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
/>
|
|
</svg>
|
|
<div className="flex-1">
|
|
<h3 className="text-red-800 text-sm font-semibold mb-2">
|
|
{error.includes("scanné")
|
|
? "📄 PDF Scanné Détecté"
|
|
: error.includes("HTTP")
|
|
? "🚨 Erreur de Traitement"
|
|
: "⚠️ Erreur"}
|
|
</h3>
|
|
<div className="text-red-700 text-xs sm:text-sm leading-relaxed">
|
|
{error.split("\n").map((line, index) => (
|
|
<div key={index} className={index > 0 ? "mt-2" : ""}>
|
|
{line.startsWith("💡") ? (
|
|
<div className="bg-blue-50 border border-blue-200 rounded-lg p-3 mt-3">
|
|
<div className="text-blue-800 font-medium text-sm">
|
|
{line}
|
|
</div>
|
|
</div>
|
|
) : line.startsWith("-") ? (
|
|
<div className="ml-4 text-blue-700">{line}</div>
|
|
) : (
|
|
line
|
|
)}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|