Augustin 4a8b6d1cf8 Amélioration complète de l'application web Journal de Conception
- Refonte complète du design avec système de panneaux latéraux rétractables
- Ajout de templates de projets par domaine (recherche, informatique, mathématiques, etc.)
- Implémentation système d'export PDF avec Puppeteer
- Amélioration de l'API REST avec nouvelles routes d'export et templates
- Ajout de JavaScript client pour interactions dynamiques
- Configuration environnement étendue pour futures fonctionnalités IA
- Amélioration responsive design et expérience utilisateur

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-25 12:09:49 +02:00

214 lines
6.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const express = require('express');
const router = express.Router();
const fs = require('fs');
const path = require('path');
const { v4: uuidv4 } = require('uuid');
// Importer le module d'export
const exportRouter = require('./export');
function modifMd(id, modifications) {
if (id === undefined) throw new Error('id obligatoire');
if (!Array.isArray(modifications) || modifications.length === 0) throw new Error('modifications requises');
const dataDir = path.resolve(__dirname, '../data');
const mapPath = path.join(dataDir, 'uuid_map.json');
if (!fs.existsSync(mapPath)) throw new Error('uuid_map.json inexistant');
const map = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
const uuid = map[id];
if (!uuid) throw new Error(`Aucun fichier pour l'id ${id}`);
const mdPath = path.join(dataDir, `${uuid}.md`);
if (!fs.existsSync(mdPath)) throw new Error('Fichier markdown inexistant');
let lignes = fs.readFileSync(mdPath, 'utf8').split('\n');
modifications = modifications.slice().sort((a, b) => a.debut - b.debut);
let offset = 0;
for (let m of modifications) {
let debut = m.debut + offset;
let fin = m.fin + offset;
const remplacement = Array.isArray(m.contenu) ? m.contenu : m.contenu.split('\n');
if (debut < 0 || fin >= lignes.length || debut > fin)
throw new Error('Plage invalide (début/fin) pour une modification');
const avant = lignes.slice(0, debut);
const apres = lignes.slice(fin + 1);
lignes = [...avant, ...remplacement, ...apres];
offset += remplacement.length - (fin - debut + 1);
}
const nouveau = lignes.join('\n');
fs.writeFileSync(mdPath, nouveau, { encoding: 'utf8', flag: 'w' });
return { id, uuid, path: mdPath, modifications };
}
function createMd(markdownContent = "# Titre\nContenu...") {
const uuid = uuidv4();
const dataDir = path.resolve(__dirname, '../data');
const mdPath = path.join(dataDir, `${uuid}.md`);
const mapPath = path.join(dataDir, 'uuid_map.json');
fs.writeFileSync(mdPath, markdownContent, { encoding: 'utf8', flag: 'w' });
let map = {};
if (fs.existsSync(mapPath)) {
map = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
}
let id = Object.keys(map).at(-1);
if (id == undefined){
map[0] = uuid;
} else {
id = +id+1
map[id] = uuid;
}
fs.writeFileSync(mapPath, JSON.stringify(map, null, 2), 'utf8');
return { id, uuid, path: mdPath, markdownContent};
}
function readMd(id = undefined) {
const dataDir = path.resolve(__dirname, '../data');
const mapPath = path.join(dataDir, 'uuid_map.json');
let map = {};
if (fs.existsSync(mapPath)) {
map = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
}
if (id !== undefined) {
const uuid = map[id];
if (!uuid) {
throw new Error(`Aucun fichier trouvé pour l'id ${id}`);
}
const mdPath = path.join(dataDir, `${uuid}.md`);
if (!fs.existsSync(mdPath)) {
throw new Error(`Le fichier ${mdPath} nexiste pas`);
}
const markdownContent = fs.readFileSync(mdPath, 'utf8');
return [{ id, uuid, path: mdPath, markdownContent }];
} else {
const results = [];
for (const [curId, uuid] of Object.entries(map)) {
const mdPath = path.join(dataDir, `${uuid}.md`);
if (fs.existsSync(mdPath)) {
const markdownContent = fs.readFileSync(mdPath, 'utf8');
results.push({ id: curId, uuid, path: mdPath, markdownContent });
}
}
return results;
}
}
function updateMd(id, newMarkdownContent) {
if (id === undefined) throw new Error('id obligatoire');
const dataDir = path.resolve(__dirname, '../data');
const mapPath = path.join(dataDir, 'uuid_map.json');
if (!fs.existsSync(mapPath)) throw new Error('uuid_map.json inexistant');
let map = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
const uuid = map[id];
if (!uuid) throw new Error(`Aucun fichier trouvé pour l'id ${id}`);
const mdPath = path.join(dataDir, `${uuid}.md`);
if (!fs.existsSync(mdPath)) throw new Error('Le fichier markdown n\'existe pas');
fs.writeFileSync(mdPath, newMarkdownContent, { encoding: 'utf8', flag: 'w' });
return { id, uuid, path: mdPath, newMarkdownContent };
}
function deteMd(id) {
if (id === undefined) throw new Error('id obligatoire');
const dataDir = path.resolve(__dirname, '../data');
const mapPath = path.join(dataDir, 'uuid_map.json');
if (!fs.existsSync(mapPath)) throw new Error('uuid_map.json inexistant');
let map = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
const uuid = map[id];
if (!uuid) throw new Error(`Aucun fichier trouvé pour l'id ${id}`);
const mdPath = path.join(dataDir, `${uuid}.md`);
if (fs.existsSync(mdPath)) fs.unlinkSync(mdPath);
delete map[id];
fs.writeFileSync(mapPath, JSON.stringify(map, null, 2), 'utf8');
return { id, deleted: true };
}
// GET /api/journals - Récupérer tous les journaux
router.get('/journals', (req, res) => {
res.json({
success: true,
data: readMd()
});
});
// POST /api/journals - Créer un nouveau journal
router.post('/journals', (req, res) => {
const { content } = req.body;
res.status(201).json({
success: true,
data: createMd(content)
});
});
// GET /api/journals/:id - Récupérer un journal spécifique
router.get('/journals/:id', (req, res) => {
const { id } = req.params;
res.json({
success: true,
data: readMd(id)
});
});
// PUT /api/journals/:id - Mettre à jour un journal
router.put('/journals/:id', (req, res) => {
const { id } = req.params;
const { content, modifications } = req.body;
try {
let result;
if (content) {
// Mise à jour complète du contenu
result = updateMd(id, content);
} else if (modifications) {
// Modifications partielles (pour compatibilité future)
result = modifMd(id, modifications);
} else {
return res.status(400).json({
success: false,
error: 'Content ou modifications requis'
});
}
res.json({
success: true,
data: result
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
});
// DELETE /api/journals/:id - Supprimer un journal
router.delete('/journals/:id', (req, res) => {
const { id } = req.params;
res.json({
success: true,
data: deteMd(id)
});
});
// Intégrer les routes d'export
router.use('/export', exportRouter);
module.exports = router;