| import puppeteer from 'puppeteer'; |
| import { OnePagerData } from '../ai/types'; |
| import { DocumentRenderer } from './types'; |
|
|
| export class PdfOnePagerRenderer implements DocumentRenderer<OnePagerData> { |
| async render(data: OnePagerData): Promise<Buffer> { |
| |
| const htmlContent = ` |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <style> |
| @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@700&family=Inter:wght@400;600&display=swap'); |
| |
| body { |
| font-family: 'Inter', sans-serif; |
| color: #333; |
| line-height: 1.6; |
| margin: 0; |
| padding: 40px; |
| background-color: #fff; |
| } |
| |
| header { |
| text-align: center; |
| margin-bottom: 30px; |
| padding-bottom: 20px; |
| border-bottom: 3px solid #F4A261; |
| } |
| |
| .main-image { |
| width: 100%; |
| height: 250px; |
| object-fit: cover; |
| border-radius: 8px; |
| margin-bottom: 20px; |
| box-shadow: 0 4px 6px rgba(0,0,0,0.1); |
| } |
| |
| h1 { |
| font-family: 'Montserrat', sans-serif; |
| color: #1B3A57; |
| font-size: 28px; |
| margin: 0 0 10px 0; |
| text-transform: uppercase; |
| letter-spacing: 1px; |
| } |
| |
| .tagline { |
| color: #1C7C54; |
| font-size: 16px; |
| font-weight: 600; |
| margin: 0; |
| } |
| |
| .section { |
| margin-bottom: 30px; |
| } |
| |
| h2 { |
| font-family: 'Montserrat', sans-serif; |
| color: #1B3A57; |
| font-size: 20px; |
| border-left: 4px solid #1C7C54; |
| padding-left: 10px; |
| margin-bottom: 15px; |
| } |
| |
| p { |
| font-size: 14px; |
| margin: 0 0 10px 0; |
| color: #4a5568; |
| } |
| |
| .cta { |
| margin-top: 50px; |
| text-align: center; |
| background-color: #1B3A57; |
| color: white; |
| padding: 20px; |
| border-radius: 8px; |
| } |
| |
| .cta p { |
| color: white; |
| font-size: 16px; |
| font-weight: 600; |
| margin: 0; |
| } |
| </style> |
| </head> |
| <body> |
| <header> |
| ${data.mainImage ? `<img src="${data.mainImage}" class="main-image" alt="Brand Visual">` : ''} |
| <h1>${data.title || '[Nom du Projet]'}</h1> |
| <p class="tagline">${data.tagline || '[Votre Slogan Stratégique]'}</p> |
| </header> |
| |
| <div class="section"> |
| <h2>Analyse du Problème</h2> |
| <p>${data.problem || '[Donnée à compléter]'}</p> |
| </div> |
| |
| <div class="section"> |
| <h2>Notre Solution Stratégique</h2> |
| <p>${data.solution || '[Donnée à compléter]'}</p> |
| </div> |
| |
| <div class="section"> |
| <h2>Cible et Opportunité</h2> |
| <p>${data.targetAudience || '[Donnée à compléter]'}</p> |
| </div> |
| |
| <div class="section"> |
| <h2>Modèle Économique & Croissance</h2> |
| <p>${data.businessModel || '[Donnée à compléter]'}</p> |
| </div> |
| ${data.marketSources ? ` |
| <div class="section" style="margin-top: 40px; border-top: 1px solid #e2e8f0; padding-top: 20px;"> |
| <p style="font-size: 12px; color: #718096; text-align: center;"><strong>Sources & Données Réelles :</strong> ${data.marketSources}</p> |
| </div>` : ''} |
| |
| <div class="cta"> |
| <p>${data.callToAction || '[Action Suivante]'}</p> |
| </div> |
| </body> |
| </html> |
| `; |
|
|
| const browser = await puppeteer.launch({ |
| executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || undefined, |
| headless: true, |
| args: ['--no-sandbox', '--disable-setuid-sandbox'], |
| }); |
|
|
| const page = await browser.newPage(); |
| await page.setContent(htmlContent, { waitUntil: 'networkidle0' }); |
|
|
| const pdfBuffer = await page.pdf({ |
| format: 'A4', |
| printBackground: true, |
| margin: { top: '20px', right: '20px', bottom: '20px', left: '20px' } |
| }); |
|
|
| await browser.close(); |
|
|
| return pdfBuffer as Buffer; |
| } |
| } |
|
|