From 4c0622e47e46568477a5cefbb7175bffd054c3df Mon Sep 17 00:00:00 2001 From: nBiqoz Date: Sat, 14 Jun 2025 21:08:43 +0200 Subject: [PATCH] full pages --- app/components/MarkdownModal.tsx | 22 ++++++--- app/page.tsx | 82 ++++++++++++++++---------------- 2 files changed, 57 insertions(+), 47 deletions(-) diff --git a/app/components/MarkdownModal.tsx b/app/components/MarkdownModal.tsx index 7a3cbbe..36a920c 100644 --- a/app/components/MarkdownModal.tsx +++ b/app/components/MarkdownModal.tsx @@ -1,14 +1,16 @@ -// components/MarkdownModal.tsx +// app/components/MarkdownModal.tsx import { X, Download } from "lucide-react"; import { jsPDF } from "jspdf"; import { useState } from "react"; +import { type PageObject } from "../page"; // Importer le type depuis la page principale interface HtmlModalProps { - content: string[] | null; + content: PageObject[] | null; // Utilise le type PageObject importé onClose: () => void; } +// Moteur de rendu HTML vers PDF, robuste et récursif const renderHtmlOnPdfPage = (pdf: jsPDF, htmlContent: string) => { const pageHeight = pdf.internal.pageSize.getHeight(); const pageWidth = pdf.internal.pageSize.getWidth(); @@ -105,10 +107,13 @@ export default function MarkdownModal({ content, onClose }: HtmlModalProps) { try { const pdf = new jsPDF({ orientation: "p", unit: "mm", format: "a4" }); pdf.setFont("Helvetica", "normal"); - content.forEach((pageHtml, index) => { + + // Mis à jour pour boucler sur les objets et passer le contenu HTML + content.forEach((page, index) => { if (index > 0) pdf.addPage(); - renderHtmlOnPdfPage(pdf, pageHtml); + renderHtmlOnPdfPage(pdf, page.htmlContent); }); + pdf.save("document_anonymise.pdf"); } catch (error) { console.error("Erreur lors de la génération du PDF:", error); @@ -117,9 +122,12 @@ export default function MarkdownModal({ content, onClose }: HtmlModalProps) { } }; - const previewHtml = content.join( - '
' - ); + // Mis à jour pour extraire le contenu HTML de chaque page avant de l'afficher + const previewHtml = content + .map((page) => page.htmlContent) + .join( + '
' + ); return (
( 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(null); + // CORRECTION : L'état de la modale attend maintenant la nouvelle structure de données + const [modalContent, setModalContent] = useState(null); const handleOptionChange = (id: string) => setAnonymizationOptions((prev) => ({ ...prev, [id]: !prev[id] })); - const handleFileChange = (event: React.ChangeEvent) => { - if (event.target.files?.length) { - setFile(event.target.files[0]); + const handleFileChange = (e: React.ChangeEvent) => { + 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 (
- {history.length === 0 ? ( -
-
- -
-

- Aucun Document -

-

- Vos fichiers apparaîtront ici. -

-
- ) : ( + {history.length > 0 ? ( history.map((item) => { const status = getStatusInfo(item); return ( @@ -360,7 +350,7 @@ export default function Home() { )} {item.status === "completed" && (
); }) + ) : ( +
+
+ +
+

+ Aucun Document +

+

+ Vos fichiers apparaîtront ici. +

+
)}