maj export project

This commit is contained in:
2026-03-14 22:46:49 +01:00
parent 12de3a8328
commit 9f88e9472e
2 changed files with 162 additions and 0 deletions

View File

@@ -9,6 +9,11 @@ const nextConfig: NextConfig = {
ignoreBuildErrors: true,
},
output: "standalone",
experimental: {
turbopack: {
root: './',
},
},
};
export default nextConfig;

View File

@@ -20,6 +20,8 @@ const ExportModal: React.FC<ExportModalProps> = ({ isOpen, onClose, project, onP
const [pageSize, setPageSize] = useState<PageSize>('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<ExportModalProps> = ({ 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; }
</style>
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>
mermaid.initialize({ startOnLoad: true, theme: 'neutral' });
</script>
</head>
<body>
`;
@@ -71,6 +80,80 @@ const ExportModal: React.FC<ExportModalProps> = ({ isOpen, onClose, project, onP
</div>
`;
});
if (includeBible && project.entities && project.entities.length > 0) {
html += `
<div class="chapter">
<h1>La Bible de l'Univers</h1>
`;
const types = ['Personnage', 'Lieu', 'Objet', 'Note'];
types.forEach(type => {
const entitiesOfType = project.entities.filter(e => e.type === type);
if (entitiesOfType.length > 0) {
html += `<h3>${type}s</h3><ul>`;
entitiesOfType.forEach(e => {
html += `<li><strong>${e.name}</strong>: ${e.description}</li>`;
});
html += `</ul>`;
}
});
html += `</div>`;
}
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 += `
<div class="chapter">
<h1>Structure du Récit</h1>
<div class="mermaid-container">
<pre class="mermaid">
${mermaidText}
</pre>
</div>
<h2>Détails des Étapes</h2>
`;
project.workflow.nodes.forEach(node => {
html += `
<div class="node-info">
<div class="node-type">${node.type || 'Étape'}</div>
<strong>${node.title}</strong>
<p>${node.description}</p>
</div>
`;
});
html += `</div>`;
}
if (project.ideas && project.ideas.length > 0) {
html += `
<div class="chapter">
<h1>Idées & Notes</h1>
`;
project.ideas.forEach(idea => {
html += `
<div class="node-info">
<div class="node-type">${idea.category}${idea.status}</div>
<strong>${idea.title}</strong>
<p>${idea.description}</p>
</div>
`;
});
html += `</div>`;
}
}
html += `</body></html>`;
return html;
@@ -116,6 +199,58 @@ const ExportModal: React.FC<ExportModalProps> = ({ 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<ExportModalProps> = ({ isOpen, onClose, project, onP
/>
</div>
<div className="flex items-center justify-between border-t border-slate-200 pt-4 mt-4">
<label className="text-slate-700 font-medium cursor-pointer" htmlFor="bible">Inclure la Bible (Personnages, Lieux...)</label>
<input
id="bible"
type="checkbox"
checked={includeBible}
onChange={(e) => setIncludeBible(e.target.checked)}
className="w-5 h-5 rounded border-slate-300 text-blue-600 focus:ring-blue-500"
/>
</div>
<div className="flex items-center justify-between">
<label className="text-slate-700 font-medium cursor-pointer" htmlFor="outils">Inclure les Outils (Nodes, Idées)</label>
<input
id="outils"
type="checkbox"
checked={includeOutils}
onChange={(e) => setIncludeOutils(e.target.checked)}
className="w-5 h-5 rounded border-slate-300 text-blue-600 focus:ring-blue-500"
/>
</div>
{format === 'epub' && (
<p className="text-xs text-amber-600 bg-amber-50 p-2 rounded mt-2">
{t('export.epub_note')}