full pages

This commit is contained in:
nBiqoz
2025-06-14 21:08:43 +02:00
parent 3560f45c48
commit 4c0622e47e
2 changed files with 57 additions and 47 deletions

View File

@@ -33,7 +33,13 @@ import {
} from "lucide-react";
import MarkdownModal from "./components/MarkdownModal";
// === Interfaces et Données ===
// Définition de la structure d'un objet page, exporté pour être réutilisé
export type PageObject = {
pageNumber: number;
htmlContent: string;
};
// Interface mise à jour pour utiliser la nouvelle structure PageObject
interface ProcessedFile {
id: string;
name: string;
@@ -44,8 +50,7 @@ interface ProcessedFile {
piiCount?: number;
errorMessage?: string;
processedBlob?: Blob;
// textContent est maintenant un tableau de strings, une par page.
textContent?: string[];
textContent?: PageObject[];
}
interface AnonymizationOptions {
@@ -76,14 +81,14 @@ export default function Home() {
useState<AnonymizationOptions>(
piiOptions.reduce((acc, option) => ({ ...acc, [option.id]: true }), {})
);
// L'état de la modale attend maintenant un tableau de strings ou null
const [modalContent, setModalContent] = useState<string[] | null>(null);
// CORRECTION : L'état de la modale attend maintenant la nouvelle structure de données
const [modalContent, setModalContent] = useState<PageObject[] | null>(null);
const handleOptionChange = (id: string) =>
setAnonymizationOptions((prev) => ({ ...prev, [id]: !prev[id] }));
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.files?.length) {
setFile(event.target.files[0]);
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files?.length) {
setFile(e.target.files[0]);
setError(null);
}
};
@@ -99,8 +104,7 @@ export default function Home() {
e.preventDefault();
setIsDragOver(true);
}, []);
const handleDragLeave = useCallback((e: React.DragEvent) => {
e.preventDefault();
const handleDragLeave = useCallback(() => {
setIsDragOver(false);
}, []);
const formatFileSize = (bytes: number): string => {
@@ -118,7 +122,7 @@ export default function Home() {
const removeFromHistory = (id: string) =>
setHistory((prev) => prev.filter((item) => item.id !== id));
const handleDownload = (id: string) => {
const handleDownloadTxt = (id: string) => {
const fileToDownload = history.find((item) => item.id === id);
if (!fileToDownload?.processedBlob) return;
const url = URL.createObjectURL(fileToDownload.processedBlob);
@@ -132,7 +136,6 @@ export default function Home() {
a.remove();
};
// Met à jour le contenu de la modale avec le tableau de pages
const handlePreview = (id: string) => {
const fileToPreview = history.find((item) => item.id === id);
if (fileToPreview?.textContent) {
@@ -162,7 +165,6 @@ export default function Home() {
}
};
// === Fonction principale mise à jour pour gérer le format JSON ===
const processFile = async () => {
if (!file) return;
const n8nWebhookUrl = process.env.NEXT_PUBLIC_N8N_WEBHOOK_URL;
@@ -207,30 +209,31 @@ export default function Home() {
throw new Error(errorResult.error || `Échec du traitement.`);
}
// On parse la réponse JSON au lieu de lire un blob
const result = await response.json();
// Validation de la structure de la réponse
if (
!result.anonymizedDocument ||
!Array.isArray(result.anonymizedDocument.pages)
) {
const docData = result.anonymizedDocument;
if (!docData || !Array.isArray(docData.pages)) {
throw new Error(
"Format de réponse invalide du service d'anonymisation."
);
}
const textContent: string[] = result.anonymizedDocument.pages;
const piiCount: number = result.anonymizedDocument.piiCount || 0;
const textContent: PageObject[] = docData.pages;
const piiCount: number = docData.piiCount || 0;
// On crée un blob pour le téléchargement .txt en joignant les pages
const fullText = textContent.join("\n\n--- Page Suivante ---\n\n");
const fullText = textContent
.map(
(page) =>
`--- Page ${page.pageNumber} ---\n${page.htmlContent.replace(
/<[^>]*>/g,
"\n"
)}`
)
.join("\n\n");
const processedBlob = new Blob([fullText], {
type: "text/plain;charset=utf-8",
});
setProgress(90);
// On met à jour l'historique avec le tableau de pages
setHistory((prev) =>
prev.map((item) =>
item.id === fileId
@@ -263,7 +266,6 @@ export default function Home() {
}
};
// === Rendu du composant (JSX - inchangé) ===
return (
<div className="h-screen w-screen bg-[#061717] flex flex-col md:flex-row overflow-hidden">
<aside className="w-full md:w-80 md:flex-shrink-0 bg-[#061717] border-b-4 md:border-b-0 md:border-r-4 border-white flex flex-col shadow-[4px_0_0_0_black]">
@@ -291,19 +293,7 @@ export default function Home() {
)}
</div>
<div className="flex-1 overflow-y-auto p-3 space-y-3">
{history.length === 0 ? (
<div className="text-center py-10 px-4 flex flex-col justify-center h-full">
<div className="w-14 h-14 bg-[#F7AB6E] border-4 border-white shadow-[6px_6px_0_0_black] mx-auto mb-4 flex items-center justify-center">
<FileText className="h-7 w-7 text-white" />
</div>
<p className="text-white font-black text-base uppercase">
Aucun Document
</p>
<p className="text-white/70 font-bold mt-1 text-xs">
Vos fichiers apparaîtront ici.
</p>
</div>
) : (
{history.length > 0 ? (
history.map((item) => {
const status = getStatusInfo(item);
return (
@@ -360,7 +350,7 @@ export default function Home() {
)}
{item.status === "completed" && (
<Button
onClick={() => handleDownload(item.id)}
onClick={() => handleDownloadTxt(item.id)}
variant="ghost"
size="icon"
className="h-7 w-7 bg-[#061717] text-white border-2 border-white shadow-[2px_2px_0_0_black] hover:shadow-[1px_1px_0_0_black] active:shadow-none active:translate-x-0.5 active:translate-y-0.5"
@@ -381,6 +371,18 @@ export default function Home() {
</div>
);
})
) : (
<div className="text-center py-10 px-4 flex flex-col justify-center h-full">
<div className="w-14 h-14 bg-[#F7AB6E] border-4 border-white shadow-[6px_6px_0_0_black] mx-auto mb-4 flex items-center justify-center">
<FileText className="h-7 w-7 text-white" />
</div>
<p className="text-white font-black text-base uppercase">
Aucun Document
</p>
<p className="text-white/70 font-bold mt-1 text-xs">
Vos fichiers apparaîtront ici.
</p>
</div>
)}
</div>
</aside>