version nice
This commit is contained in:
181
app/components/AnonymizationInterface.tsx
Normal file
181
app/components/AnonymizationInterface.tsx
Normal file
@@ -0,0 +1,181 @@
|
||||
import { CheckCircle } from "lucide-react";
|
||||
|
||||
interface AnonymizationInterfaceProps {
|
||||
isProcessing: boolean;
|
||||
outputText?: string;
|
||||
sourceText?: string;
|
||||
}
|
||||
|
||||
export const AnonymizationInterface = ({
|
||||
isProcessing,
|
||||
outputText,
|
||||
sourceText,
|
||||
}: AnonymizationInterfaceProps) => {
|
||||
// Fonction pour détecter quels types de données ont été anonymisés
|
||||
const getAnonymizedDataTypes = () => {
|
||||
if (!outputText || !sourceText) return new Set();
|
||||
|
||||
const anonymizedTypes = new Set<string>();
|
||||
|
||||
// Détecter les patterns d'anonymisation dans le texte de sortie
|
||||
|
||||
// Noms (Prénoms, Noms de famille, Noms complets)
|
||||
if (outputText.includes("[Nom1]") || outputText.includes("[Nom")) {
|
||||
anonymizedTypes.add("Prénoms");
|
||||
anonymizedTypes.add("Noms de famille");
|
||||
anonymizedTypes.add("Noms complets");
|
||||
}
|
||||
|
||||
// Emails
|
||||
if (outputText.includes("[Email1]") || outputText.includes("[Email")) {
|
||||
anonymizedTypes.add("Adresses e-mail");
|
||||
}
|
||||
|
||||
// Téléphones
|
||||
if (
|
||||
outputText.includes("[Téléphone1]") ||
|
||||
outputText.includes("[Téléphone")
|
||||
) {
|
||||
anonymizedTypes.add("Numéros de téléphone");
|
||||
}
|
||||
|
||||
// Adresses
|
||||
if (outputText.includes("[Adresse1]") || outputText.includes("[Adresse")) {
|
||||
anonymizedTypes.add("Adresses");
|
||||
}
|
||||
|
||||
// Numéros d'ID / Sécurité sociale
|
||||
if (
|
||||
outputText.includes("[NuméroSS1]") ||
|
||||
outputText.includes("[NuméroSS") ||
|
||||
outputText.includes("[ID")
|
||||
) {
|
||||
anonymizedTypes.add("Numéros d'ID");
|
||||
}
|
||||
|
||||
// Dates
|
||||
if (
|
||||
outputText.includes("[Date") ||
|
||||
/\[\d{2}\/\d{2}\/\d{4}\]/.test(outputText)
|
||||
) {
|
||||
anonymizedTypes.add("Dates");
|
||||
}
|
||||
|
||||
// Valeurs monétaires
|
||||
if (outputText.includes("[Montant") || /\[\d+[€$]\]/.test(outputText)) {
|
||||
anonymizedTypes.add("Valeurs monétaires");
|
||||
}
|
||||
|
||||
// Noms de domaine
|
||||
if (outputText.includes("[Domaine") || /\[.*\.com\]/.test(outputText)) {
|
||||
anonymizedTypes.add("Noms de domaine");
|
||||
}
|
||||
|
||||
// Valeurs numériques
|
||||
if (
|
||||
/\[\d+\]/.test(outputText) &&
|
||||
!outputText.includes("[Téléphone") &&
|
||||
!outputText.includes("[Montant")
|
||||
) {
|
||||
anonymizedTypes.add("Valeurs numériques");
|
||||
}
|
||||
|
||||
// Texte personnalisé (si du texte a été modifié mais pas avec les patterns spécifiques)
|
||||
if (sourceText !== outputText && anonymizedTypes.size === 0) {
|
||||
anonymizedTypes.add("Texte personnalisé");
|
||||
}
|
||||
|
||||
return anonymizedTypes;
|
||||
};
|
||||
|
||||
// Structure exacte de SupportedDataTypes (récupérée dynamiquement)
|
||||
const supportedDataStructure = [
|
||||
{
|
||||
items: ["Prénoms", "Numéros de téléphone", "Noms de domaine"],
|
||||
},
|
||||
{
|
||||
items: ["Noms de famille", "Adresses", "Dates"],
|
||||
},
|
||||
{
|
||||
items: ["Noms complets", "Numéros d'ID", "Valeurs numériques"],
|
||||
},
|
||||
{
|
||||
items: ["Adresses e-mail", "Valeurs monétaires", "Texte personnalisé"],
|
||||
},
|
||||
];
|
||||
|
||||
if (isProcessing) {
|
||||
return (
|
||||
<div className="bg-gray-50 border border-gray-200 rounded-xl p-6">
|
||||
<div className="flex items-center justify-center space-x-3 mb-4">
|
||||
<div className="animate-spin rounded-full h-6 w-6 border-b-2 border-gray-500"></div>
|
||||
<h4 className="text-sm font-semibold text-gray-700">
|
||||
Anonymisation en cours...
|
||||
</h4>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="w-2 h-2 bg-gray-500 rounded-full animate-pulse"></div>
|
||||
<span className="text-xs text-gray-600">Analyse du contenu</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div
|
||||
className="w-2 h-2 bg-gray-500 rounded-full animate-pulse"
|
||||
style={{ animationDelay: "0.5s" }}
|
||||
></div>
|
||||
<span className="text-xs text-gray-600">
|
||||
Détection des données sensibles
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div
|
||||
className="w-2 h-2 bg-gray-500 rounded-full animate-pulse"
|
||||
style={{ animationDelay: "1s" }}
|
||||
></div>
|
||||
<span className="text-xs text-gray-600">
|
||||
Application de l'anonymisation
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (outputText) {
|
||||
const anonymizedTypes = getAnonymizedDataTypes();
|
||||
|
||||
return (
|
||||
<div className="bg-green-50 border border-green-200 rounded-xl p-6">
|
||||
<div className="flex items-center space-x-3 mb-4">
|
||||
<CheckCircle className="h-5 w-5 text-green-600" />
|
||||
<h4 className="text-sm font-semibold text-green-700">
|
||||
Anonymisation terminée avec succès
|
||||
</h4>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-xs">
|
||||
{supportedDataStructure.map((column, columnIndex) => (
|
||||
<div key={columnIndex} className="flex flex-col space-y-2">
|
||||
{column.items.map((item, itemIndex) => {
|
||||
const isAnonymized = anonymizedTypes.has(item);
|
||||
return (
|
||||
<span
|
||||
key={itemIndex}
|
||||
className={
|
||||
isAnonymized
|
||||
? "text-green-700 font-medium"
|
||||
: "text-gray-400"
|
||||
}
|
||||
>
|
||||
{isAnonymized ? "✓" : "•"} {item}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
Reference in New Issue
Block a user