From eed5696596f83ec83534adf2376ff53283de6497 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 17 Nov 2025 07:45:43 +0000 Subject: [PATCH] =?UTF-8?q?Fix:=20Synchronisation=20des=20dates=20de=20mod?= =?UTF-8?q?ification=20et=20tags=20apr=C3=A8s=20sauvegarde?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problème : - Après modification d'une note, il fallait rafraîchir la page pour voir updated_at - Après ajout d'un tag, il fallait rafraîchir la page pour le voir dans la note Solution backend : 1. routes/notes.routes.js - PUT /api/notes/:id : - Récupération de la note mise à jour après UPDATE - Retour de { message, note } au lieu de juste { message } - La note retournée contient la vraie updated_at générée par PostgreSQL Solution frontend : 1. NotesService.ts - updateNote() : - Changement du type de retour de Promise vers Promise - Récupération et retour de la note mise à jour depuis la réponse du serveur - Merge de la note locale (todos, images) avec les données du serveur (updated_at) 2. Index.tsx - handleNoteChange et handleContentChange : - Utilisation de la note retournée par updateNote() au lieu de l'état local - Mise à jour de openNote et notes avec les données du serveur 3. Index.tsx - Synchronisation des tags : - loadNoteTags : Mise à jour de openNote.tags après chargement - confirmAddTag : Mise à jour de openNote.tags après ajout - handleDeleteTag : Mise à jour de openNote.tags après suppression - Conversion du format { id, tag } vers { id, name } pour cohérence Résultat : - Les dates de modification s'affichent immédiatement après sauvegarde - Les tags ajoutés apparaissent immédiatement dans l'interface - Plus besoin de rafraîchir la page manuellement --- routes/notes.routes.js | 14 ++++++++++- src/pages/Index.tsx | 45 ++++++++++++++++++++++++++++++------ src/services/NotesService.ts | 23 ++++++++++++------ 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/routes/notes.routes.js b/routes/notes.routes.js index 11f807b..98a8977 100644 --- a/routes/notes.routes.js +++ b/routes/notes.routes.js @@ -238,7 +238,19 @@ router.put('/:id', await runQuery(`UPDATE notes SET ${updates.join(', ')} WHERE id = $${paramCount}`, params); } - res.json({ message: 'Note modifiée avec succès' }); + // Récupérer la note mise à jour avec sa nouvelle updated_at + const updatedNote = await getOne(` + SELECT id, title, content, image_filename, archived, priority, created_at, updated_at + FROM notes + WHERE id = $1 + `, [req.params.id]); + + logger.info(`[UPDATE NOTE] Note mise à jour - ID: ${req.params.id}, updated_at: ${updatedNote.updated_at}`); + + res.json({ + message: 'Note modifiée avec succès', + note: updatedNote + }); } catch (error) { logger.error('Erreur lors de la modification de la note:', error); res.status(500).json({ error: 'Erreur serveur' }); diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 43a55fb..aacbecd 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -423,6 +423,14 @@ const Index = () => { try { const tags = await TagsService.getTags(noteId); setNoteTags(tags || []); + + // Synchroniser avec openNote.tags (convertir de 'tag' vers 'name') + if (openNote && openNote.id === noteId) { + setOpenNote({ + ...openNote, + tags: (tags || []).map(t => ({ id: t.id, name: t.tag })) + }); + } } catch (error) { console.error("Erreur lors du chargement des tags:", error); setNoteTags([]); @@ -458,8 +466,12 @@ const Index = () => { setNotes(prev => prev.map(note => note.id === updatedNote.id ? updatedNote : note)); try { - const success = await NotesService.updateNote(updatedNote); - if (!success) { + const savedNote = await NotesService.updateNote(updatedNote); + if (savedNote) { + // Mettre à jour avec les données du serveur (updated_at, etc.) + setOpenNote(savedNote); + setNotes(prev => prev.map(note => note.id === savedNote.id ? savedNote : note)); + } else { showError("Erreur lors de la sauvegarde"); } } catch (error) { @@ -482,9 +494,12 @@ const Index = () => { saveTimerRef.current = setTimeout(async () => { try { - await NotesService.updateNote(updatedNote); - // Update notes list silently after save - setNotes(prev => prev.map(note => note.id === updatedNote.id ? updatedNote : note)); + const savedNote = await NotesService.updateNote(updatedNote); + if (savedNote) { + // Mettre à jour avec les données du serveur (updated_at, etc.) + setOpenNote(savedNote); + setNotes(prev => prev.map(note => note.id === savedNote.id ? savedNote : note)); + } } catch (error) { showError("Erreur lors de la sauvegarde automatique"); } @@ -701,7 +716,15 @@ const Index = () => { try { const newTag = await TagsService.addTag(openNote.id, tagText); if (newTag) { - setNoteTags([...noteTags, newTag]); + const updatedNoteTags = [...noteTags, newTag]; + setNoteTags(updatedNoteTags); + + // Synchroniser avec openNote.tags (convertir de 'tag' vers 'name') + setOpenNote({ + ...openNote, + tags: updatedNoteTags.map(t => ({ id: t.id, name: t.tag })) + }); + showSuccess("Tag ajouté"); } } catch (error) { @@ -715,7 +738,15 @@ const Index = () => { try { const success = await TagsService.deleteTag(openNote.id, tagId); if (success) { - setNoteTags(noteTags.filter(t => t.id !== tagId)); + const updatedNoteTags = noteTags.filter(t => t.id !== tagId); + setNoteTags(updatedNoteTags); + + // Synchroniser avec openNote.tags (convertir de 'tag' vers 'name') + setOpenNote({ + ...openNote, + tags: updatedNoteTags.map(t => ({ id: t.id, name: t.tag })) + }); + showSuccess("Tag supprimé"); } } catch (error) { diff --git a/src/services/NotesService.ts b/src/services/NotesService.ts index 0bb04a3..aa383d9 100644 --- a/src/services/NotesService.ts +++ b/src/services/NotesService.ts @@ -85,9 +85,9 @@ class NotesService { } } - async updateNote(note: Note): Promise { - if (!note.id) return false; - + async updateNote(note: Note): Promise { + if (!note.id) return null; + try { const response = await fetch(`/api/notes/${note.id}`, { method: "PUT", @@ -98,15 +98,24 @@ class NotesService { images: note.images || [] }) }); - + if (!response.ok) { throw new Error("Erreur lors de la mise à jour de la note"); } - - return true; + + const result = await response.json(); + // Le backend retourne { message, note } avec la note mise à jour incluant updated_at + if (result.note) { + return { + ...note, // Garder les todos et images de l'état local + ...result.note // Écraser avec les données du serveur (updated_at, etc.) + }; + } + + return note; // Fallback si le backend ne retourne pas la note } catch (error) { showError(error instanceof Error ? error.message : "Erreur serveur"); - return false; + return null; } }