diff --git a/components/versions/export-pdf-button.js b/components/versions/export-pdf-button.js new file mode 100644 index 0000000..f6b12f5 --- /dev/null +++ b/components/versions/export-pdf-button.js @@ -0,0 +1,145 @@ +'use client' + +import {useState} from 'react' +import PropTypes from 'prop-types' +import Button from '@mui/material/Button' +import CircularProgress from '@mui/material/CircularProgress' +import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf' +import {formatDate} from '@/lib/format.js' + +export default function ExportPdfButton({versionData, size = 'medium', variant = 'outlined'}) { + const [isExporting, setIsExporting] = useState(false) + + const handleExportPdf = async () => { + setIsExporting(true) + + try { + const {default: jsPDF} = await import('jspdf') + const {default: html2canvas} = await import('html2canvas') + + // Créer un élément temporaire avec le contenu formaté + const tempDiv = document.createElement('div') + tempDiv.style.cssText = ` + padding: 40px; + font-family: 'Roboto', Arial, sans-serif; + line-height: 1.6; + color: #333; + background-color: white; + width: 210mm; + position: fixed; + top: -9999px; + left: -9999px; + z-index: -1; + ` + + const authorName = versionData.user_created?.split('-')[0] || 'Système' + const createdAt = new Date(versionData.date_created) + const threeDaysAgo = new Date(Date.now() - (3 * 24 * 60 * 60 * 1000)) + const voteStatus = createdAt < threeDaysAgo ? 'fermé' : 'ouvert' + const voteColor = voteStatus === 'ouvert' ? '#2e7d32' : '#d32f2f' + + tempDiv.innerHTML = ` +
+

+ ${versionData.name} +

+
+

+ Auteur : @${authorName} +

+

+ Date de création : ${formatDate(versionData.date_created, 'PPpp')} +

+

+ Statut du vote : + ${voteStatus} +

+
+
+ +
+

+ Contenu +

+
+ ${versionData.delta?.contenu || 'Aucun contenu disponible'} +
+
+ +
+ Exporté depuis Konstitisyon.la le ${formatDate(new Date(), 'PPpp')} +
+ ` + + document.body.append(tempDiv) + + // Générer le canvas avec une meilleure qualité + const canvas = await html2canvas(tempDiv, { + scale: 2, + useCORS: true, + allowTaint: true, + backgroundColor: '#ffffff', + width: tempDiv.scrollWidth, + height: tempDiv.scrollHeight + }) + + tempDiv.remove() + + // Créer le PDF + const imgData = canvas.toDataURL('image/png', 1) + const pdf = new jsPDF('p', 'mm', 'a4') // eslint-disable-line new-cap + + const pageWidth = pdf.internal.pageSize.getWidth() + const pageHeight = pdf.internal.pageSize.getHeight() + const imgWidth = pageWidth + const imgHeight = (canvas.height * imgWidth) / canvas.width + + let heightLeft = imgHeight + let position = 0 + + // Ajouter la première page + pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight) + heightLeft -= pageHeight + + // Ajouter des pages supplémentaires si nécessaire + while (heightLeft >= 0) { + position = heightLeft - imgHeight + pdf.addPage() + pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight) + heightLeft -= pageHeight + } + + // Nom du fichier sécurisé + const fileName = `${versionData.name.replaceAll(/[^a-zA-Z\d\s]/g, '').replaceAll(/\s+/g, '_')}_${formatDate(new Date(), 'yyyy-MM-dd')}.pdf` + pdf.save(fileName) + } catch (error) { + console.error('Erreur lors de l\'export PDF:', error) + } finally { + setIsExporting(false) + } + } + + return ( + + ) +} + +ExportPdfButton.propTypes = { + versionData: PropTypes.object.isRequired, + size: PropTypes.oneOf(['small', 'medium', 'large']), + variant: PropTypes.oneOf(['text', 'outlined', 'contained']) +} diff --git a/components/versions/list-versions.js b/components/versions/list-versions.js index c38ac0f..145b6de 100644 --- a/components/versions/list-versions.js +++ b/components/versions/list-versions.js @@ -21,6 +21,7 @@ import VersionSearch from './version-search.js' import VersionFilters from './version-filters.js' import CopyButton from './copy-button.js' import ShareButton from './share-button.js' +import ExportPdfButton from './export-pdf-button.js' import {formatDate} from '@/lib/format.js' import {compareVersion} from '@/lib/directus.js' import {filterVersions, getFilterStats} from '@/lib/version-utils.js' @@ -122,6 +123,11 @@ function rowContent({ versionName={row.name} hasSnackbarVisible={false} /> +