'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'
// Helper function to render markdown to HTML
const renderMarkdownToHtml = async content => {
if (!content) {
return 'Aucun contenu disponible'
}
// Check if content contains markdown syntax
const hasMarkdown = content.includes('**')
|| content.includes('*')
|| content.includes('#')
|| content.includes('[')
|| content.includes('`')
|| content.includes('> ')
|| content.includes('- ')
|| content.includes('1. ')
if (!hasMarkdown) {
// Simple text with line breaks
return content.replaceAll('\n', '
')
}
try {
// Dynamic import of markdown parser
const {marked} = await import('marked')
// Configure marked for better PDF rendering
marked.setOptions({
breaks: true, // Convert \n to
gfm: true, // GitHub flavored markdown
headerIds: false, // No header IDs needed for PDF
mangle: false // Don't mangle email addresses
})
return marked(content)
} catch (error) {
console.warn('Failed to parse markdown, falling back to plain text:', error)
return content.replaceAll('\n', '
')
}
}
export default function ExportPdfButton({versionData, isOutdated = false, voteCounts = null, 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;
`
// Add CSS styles for markdown elements
const styleElement = document.createElement('style')
styleElement.textContent = `
.pdf-content h1, .pdf-content h2, .pdf-content h3, .pdf-content h4, .pdf-content h5, .pdf-content h6 {
margin: 20px 0 10px 0;
font-weight: bold;
color: #333;
}
.pdf-content h1 { font-size: 24px; color: #1976d2; }
.pdf-content h2 { font-size: 20px; }
.pdf-content h3 { font-size: 18px; }
.pdf-content h4 { font-size: 16px; }
.pdf-content p { margin: 10px 0; }
.pdf-content strong, .pdf-content b { font-weight: bold; }
.pdf-content em, .pdf-content i { font-style: italic; }
.pdf-content ul, .pdf-content ol {
margin: 10px 0;
padding-left: 25px;
}
.pdf-content li { margin: 5px 0; }
.pdf-content blockquote {
margin: 15px 0;
padding: 10px 20px;
border-left: 4px solid #1976d2;
background-color: #f5f5f5;
font-style: italic;
}
.pdf-content code {
background-color: #f5f5f5;
padding: 2px 4px;
border-radius: 3px;
font-family: 'Courier New', monospace;
font-size: 13px;
}
.pdf-content pre {
background-color: #f5f5f5;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
margin: 15px 0;
}
.pdf-content pre code {
background: none;
padding: 0;
}
.pdf-content a { color: #1976d2; text-decoration: underline; }
.pdf-content hr {
border: none;
border-top: 1px solid #ccc;
margin: 20px 0;
}
.pdf-content table {
border-collapse: collapse;
margin: 15px 0;
width: 100%;
}
.pdf-content th, .pdf-content td {
border: 1px solid #ccc;
padding: 8px;
text-align: left;
}
.pdf-content th {
background-color: #f5f5f5;
font-weight: bold;
}
`
document.head.append(styleElement)
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 isExpired = createdAt < threeDaysAgo
const voteStatus = (isExpired || isOutdated) ? 'fermé' : 'ouvert'
const voteColor = voteStatus === 'ouvert' ? '#2e7d32' : '#d32f2f'
// Vote counts display
const voteTotal = voteCounts ? voteCounts.total : 0
const voteTotalColor = voteTotal > 0 ? '#2e7d32' : (voteTotal < 0 ? '#d32f2f' : '#666')
const voteTotalSign = voteTotal >= 0 ? '+' : ''
// Render markdown content to HTML
const renderedContent = await renderMarkdownToHtml(versionData.delta?.contenu)
tempDiv.innerHTML = `
Auteur : @${authorName}
Date de création : ${formatDate(versionData.date_created, 'PPpp', {withTimezone: true})}
Statut du vote : ${voteStatus}
${voteCounts ? `📊 Résultats des votes
👍 Votes positifs : ${voteCounts.positive}
👎 Votes négatifs : ${voteCounts.negative}
🏆 Total : ${voteTotalSign}${voteTotal}