diff --git a/next.config.ts b/next.config.ts index 58a1fa5..682e91f 100644 --- a/next.config.ts +++ b/next.config.ts @@ -9,6 +9,11 @@ const nextConfig: NextConfig = { ignoreBuildErrors: true, }, output: "standalone", + experimental: { + turbopack: { + root: './', + }, + }, }; export default nextConfig; diff --git a/src/components/ExportModal.tsx b/src/components/ExportModal.tsx index 4a7c504..8b62366 100644 --- a/src/components/ExportModal.tsx +++ b/src/components/ExportModal.tsx @@ -20,6 +20,8 @@ const ExportModal: React.FC = ({ isOpen, onClose, project, onP const [pageSize, setPageSize] = useState('A4'); const [includeCover, setIncludeCover] = useState(true); const [includeTOC, setIncludeTOC] = useState(true); + const [includeBible, setIncludeBible] = useState(true); + const [includeOutils, setIncludeOutils] = useState(true); const { t } = useLanguage(); if (!isOpen) return null; @@ -41,7 +43,14 @@ const ExportModal: React.FC = ({ isOpen, onClose, project, onP a { color: #000; text-decoration: none; } ul { list-style-type: none; padding: 0; } li { margin-bottom: 0.5em; } + .mermaid-container { margin: 2em 0; text-align: center; } + .node-info { margin-bottom: 1.5em; padding-left: 1em; border-left: 3px solid #e2e8f0; } + .node-type { font-size: 0.8em; font-weight: bold; text-transform: uppercase; color: #64748b; } + + `; @@ -71,6 +80,80 @@ const ExportModal: React.FC = ({ isOpen, onClose, project, onP `; }); + + if (includeBible && project.entities && project.entities.length > 0) { + html += ` +
+

La Bible de l'Univers

+ `; + + const types = ['Personnage', 'Lieu', 'Objet', 'Note']; + types.forEach(type => { + const entitiesOfType = project.entities.filter(e => e.type === type); + if (entitiesOfType.length > 0) { + html += `

${type}s

    `; + entitiesOfType.forEach(e => { + html += `
  • ${e.name}: ${e.description}
  • `; + }); + html += `
`; + } + }); + html += `
`; + } + + if (includeOutils) { + if (project.workflow && project.workflow.nodes && project.workflow.nodes.length > 0) { + // Generate Mermaid syntax + let mermaidText = "graph TD\n"; + project.workflow.nodes.forEach(node => { + const safeTitle = node.title.replace(/[()]/g, ''); + mermaidText += ` ${node.id}["${safeTitle}"]\n`; + }); + if (project.workflow.connections) { + project.workflow.connections.forEach(conn => { + mermaidText += ` ${conn.source} --> ${conn.target}\n`; + }); + } + + html += ` +
+

Structure du Récit

+
+
+${mermaidText}
+              
+
+

Détails des Étapes

+ `; + project.workflow.nodes.forEach(node => { + html += ` +
+
${node.type || 'Étape'}
+ ${node.title} +

${node.description}

+
+ `; + }); + html += `
`; + } + + if (project.ideas && project.ideas.length > 0) { + html += ` +
+

Idées & Notes

+ `; + project.ideas.forEach(idea => { + html += ` +
+
${idea.category} • ${idea.status}
+ ${idea.title} +

${idea.description}

+
+ `; + }); + html += `
`; + } + } html += ``; return html; @@ -116,6 +199,58 @@ const ExportModal: React.FC = ({ isOpen, onClose, project, onP const text = c.content.replace(/<[^>]+>/g, '\n'); md += `## ${c.title}\n\n${text}\n\n---\n\n`; }); + + if (includeBible && project.entities && project.entities.length > 0) { + md += `# La Bible de l'Univers\n\n`; + const types = ['Personnage', 'Lieu', 'Objet', 'Note']; + types.forEach(type => { + const entitiesOfType = project.entities.filter(e => e.type === type); + if (entitiesOfType.length > 0) { + md += `## ${type}s\n\n`; + entitiesOfType.forEach(e => { + md += `### ${e.name}\n${e.description}\n\n`; + }); + } + }); + md += `---\n\n`; + } + + if (includeOutils) { + if (project.workflow && project.workflow.nodes && project.workflow.nodes.length > 0) { + md += `# Structure du Récit\n\n`; + + // Mermaid block + md += `\`\`\`mermaid\ngraph TD\n`; + project.workflow.nodes.forEach(node => { + const safeTitle = node.title.replace(/[()]/g, ''); + md += ` ${node.id}["${safeTitle}"]\n`; + }); + if (project.workflow.connections) { + project.workflow.connections.forEach(conn => { + md += ` ${conn.source} --> ${conn.target}\n`; + }); + } + md += `\`\`\`\n\n`; + + md += `## Détails des Étapes\n\n`; + project.workflow.nodes.forEach(node => { + md += `### ${node.title}\n`; + md += `**Type**: ${node.type || 'Étape'}\n\n`; + md += `${node.description}\n\n`; + }); + md += `\n---\n\n`; + } + + if (project.ideas && project.ideas.length > 0) { + md += `# Idées & Notes\n\n`; + project.ideas.forEach(idea => { + md += `## ${idea.title}\n`; + md += `**Catégorie**: ${idea.category} | **Statut**: ${idea.status}\n\n`; + md += `${idea.description}\n\n`; + }); + md += `\n---\n\n`; + } + } const blob = new Blob([md], { type: 'text/markdown' }); downloadBlob(blob, `${filename}.md`); } @@ -227,6 +362,28 @@ const ExportModal: React.FC = ({ isOpen, onClose, project, onP /> +
+ + setIncludeBible(e.target.checked)} + className="w-5 h-5 rounded border-slate-300 text-blue-600 focus:ring-blue-500" + /> +
+ +
+ + setIncludeOutils(e.target.checked)} + className="w-5 h-5 rounded border-slate-300 text-blue-600 focus:ring-blue-500" + /> +
+ {format === 'epub' && (

{t('export.epub_note')}