198 lines
6.0 KiB
TypeScript
198 lines
6.0 KiB
TypeScript
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>();
|
|
|
|
if (outputText.includes("<PERSON>")) {
|
|
anonymizedTypes.add("Prénoms");
|
|
anonymizedTypes.add("Noms de famille");
|
|
anonymizedTypes.add("Noms complets");
|
|
}
|
|
|
|
// EMAIL_ADDRESS -> Adresses e-mail
|
|
if (outputText.includes("<EMAIL_ADDRESS>")) {
|
|
anonymizedTypes.add("Adresses e-mail");
|
|
}
|
|
|
|
// PHONE_NUMBER -> Numéros de téléphone
|
|
if (outputText.includes("<PHONE_NUMBER>")) {
|
|
anonymizedTypes.add("Numéros de téléphone");
|
|
}
|
|
|
|
// BE_PHONE_NUMBER -> aussi Numéros de téléphone
|
|
if (outputText.includes("<BE_PHONE_NUMBER>")) {
|
|
anonymizedTypes.add("Numéros de téléphone");
|
|
}
|
|
|
|
// LOCATION -> Adresses
|
|
if (outputText.includes("<LOCATION>")) {
|
|
anonymizedTypes.add("Adresses");
|
|
}
|
|
|
|
// BE_ADDRESS -> aussi Adresses
|
|
if (outputText.includes("<BE_ADDRESS>")) {
|
|
anonymizedTypes.add("Adresses");
|
|
}
|
|
|
|
// FLEXIBLE_DATE ou DATE_TIME -> Dates
|
|
if (
|
|
outputText.includes("<FLEXIBLE_DATE>") ||
|
|
outputText.includes("<DATE_TIME>")
|
|
) {
|
|
anonymizedTypes.add("Dates");
|
|
}
|
|
|
|
// IBAN -> Coordonnées bancaires (au lieu de Numéros d'ID)
|
|
if (outputText.includes("<IBAN>")) {
|
|
anonymizedTypes.add("Coordonnées bancaires");
|
|
}
|
|
|
|
// CREDIT_CARD -> aussi Coordonnées bancaires (au lieu de Valeurs numériques)
|
|
if (outputText.includes("<CREDIT_CARD>")) {
|
|
anonymizedTypes.add("Coordonnées bancaires");
|
|
}
|
|
|
|
// NRP -> Numéros d'ID
|
|
if (outputText.includes("<NRP>")) {
|
|
anonymizedTypes.add("Numéros d'ID");
|
|
}
|
|
|
|
// BE_PRO_ID -> Numéros d'ID
|
|
if (outputText.includes("<BE_PRO_ID>")) {
|
|
anonymizedTypes.add("Numéros d'ID");
|
|
}
|
|
|
|
// BE_ENTERPRISE_NUMBER -> Numéros d'ID
|
|
if (outputText.includes("<BE_ENTERPRISE_NUMBER>")) {
|
|
anonymizedTypes.add("Numéros d'ID");
|
|
}
|
|
|
|
// URL -> Noms de domaine
|
|
if (outputText.includes("<URL>")) {
|
|
anonymizedTypes.add("Noms de domaine");
|
|
}
|
|
|
|
// CREDIT_CARD -> Coordonnées bancaires (supprimer la duplication)
|
|
if (outputText.includes("<CREDIT_CARD>")) {
|
|
anonymizedTypes.add("Coordonnées bancaires");
|
|
}
|
|
|
|
// IP_ADDRESS -> Valeurs numériques
|
|
if (outputText.includes("<IP_ADDRESS>")) {
|
|
anonymizedTypes.add("Valeurs numériques");
|
|
}
|
|
|
|
// BE_VAT -> Valeurs numériques
|
|
if (outputText.includes("<BE_VAT>")) {
|
|
anonymizedTypes.add("Valeurs numériques");
|
|
}
|
|
|
|
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", "Coordonnées bancaires"],
|
|
},
|
|
{
|
|
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;
|
|
};
|