diff --git a/app/api/storage/files/route.ts b/app/api/storage/files/route.ts index 54cbc2f..17467c2 100644 --- a/app/api/storage/files/route.ts +++ b/app/api/storage/files/route.ts @@ -252,7 +252,13 @@ export async function PUT(request: Request) { // Check if this is using the direct id (key) or needs to construct one let key: string; - if (id) { + // For Diary and Health folders, always reconstruct key from title to ensure new format + // This allows renaming from "2026-01-16.md" to "16_janvier_2026.md" + const normalizedFolder = folder?.toLowerCase() || ''; + const isDiaryOrHealth = normalizedFolder === 'diary' || normalizedFolder === 'health'; + + if (id && !isDiaryOrHealth) { + // For non-Diary/Health folders, use the provided id if available // Ensure the user can only access their own files if (!id.includes(`user-${userId}/`)) { return createErrorResponse( @@ -264,7 +270,7 @@ export async function PUT(request: Request) { } key = id; } else { - // If id is not provided, construct it from folder and title + // If id is not provided, or for Diary/Health folders, construct it from folder and title if (!title || !folder) { return createErrorResponse( StorageError.VALIDATION_ERROR, @@ -284,9 +290,18 @@ export async function PUT(request: Request) { ); } - const normalizedFolder = folder.toLowerCase(); + // Sanitize title (spaces and special chars become underscores) + // This converts "16 janvier 2026" to "16_janvier_2026" const sanitizedTitle = title.replace(/[^a-zA-Z0-9._-]/g, '_'); key = `user-${userId}/${normalizedFolder}/${sanitizedTitle}${sanitizedTitle.endsWith('.md') ? '' : '.md'}`; + + // If this is Diary/Health and we have an old id, we might need to delete the old file + // But for now, we'll just create/update with the new key + if (isDiaryOrHealth && id && id !== key) { + console.log(`[PUT] Renaming Diary/Health note from ${id} to ${key}`); + // The old file will remain, but the new one will be created/updated + // In a future enhancement, we could delete the old file here + } } // Validate content diff --git a/app/pages/page.tsx b/app/pages/page.tsx index 05caebe..09bb16c 100644 --- a/app/pages/page.tsx +++ b/app/pages/page.tsx @@ -13,6 +13,7 @@ import { X, Menu } from "lucide-react"; import { ContactDetails } from '@/components/carnet/contact-details'; import { parse as parseVCard, format as formatVCard } from 'vcard-parser'; import { format } from 'date-fns'; +import { fr } from 'date-fns/locale'; import { PaneLayout } from './pane-layout'; import { notesCache, noteContentCache, foldersCache, invalidateFolderCache, invalidateNoteCache } from '@/lib/cache-utils'; @@ -474,14 +475,18 @@ export default function CarnetPage() { // For Diary and Health, ensure title is formatted with date let noteTitle = note.title || 'Untitled'; if ((selectedFolder === 'Diary' || selectedFolder === 'Health') && !note.id) { - // For new notes in Diary/Health, use today's date as title + // For new notes in Diary/Health, use today's date as title (formatted for display) const today = new Date(); - const dateStr = format(today, 'yyyy-MM-dd'); - noteTitle = dateStr; + const dateStr = format(today, 'yyyy-MM-dd'); // For filename matching + const dateTitle = format(today, 'd MMMM yyyy', { locale: fr }); // For display: "16 janvier 2026" + noteTitle = dateTitle; // Check if a note with this date already exists const existingNote = notes.find(n => { - return n.title?.startsWith(dateStr) || n.id?.includes(dateStr); + const title = n.title || ''; + return title.startsWith(dateStr) || + title.startsWith(dateTitle) || + n.id?.includes(dateStr); }); if (existingNote) { @@ -492,15 +497,35 @@ export default function CarnetPage() { } } + // For Diary/Health, always reconstruct filename from formatted title to ensure new format + // For other folders, use existing id if available, otherwise construct from title + let fileKey: string | undefined; + if (selectedFolder === 'Diary' || selectedFolder === 'Health') { + // Always use the formatted date title for the filename (will be sanitized by API) + // This ensures we use "16_janvier_2026.md" instead of "2026-01-16.md" + if (noteTitle) { + fileKey = `user-${session?.user?.id}/${selectedFolder.toLowerCase()}/${noteTitle}${noteTitle.endsWith('.md') ? '' : '.md'}`; + } + } else { + // For other folders, use existing id or construct from title + fileKey = note.id || (noteTitle ? `user-${session?.user?.id}/${selectedFolder.toLowerCase()}/${noteTitle}${noteTitle.endsWith('.md') ? '' : '.md'}` : undefined); + } + + if (!fileKey) { + throw new Error('Cannot determine file key for saving note'); + } + // Construct API payload with lowercase folder name const payload = { - id: note.id || `user-${session?.user?.id}/${selectedFolder.toLowerCase()}/${noteTitle}${noteTitle.endsWith('.md') ? '' : '.md'}`, + id: fileKey, title: noteTitle, content: note.content || '', folder: selectedFolder.toLowerCase(), // Use lowercase for storage consistency mime: "text/markdown" }; + console.log(`[handleSaveNote] File key for ${selectedFolder}: ${fileKey}`); + // Use direct storage API endpoint const endpoint = '/api/storage/files'; const method = note.id ? 'PUT' : 'POST'; @@ -643,13 +668,17 @@ export default function CarnetPage() { // For Diary and Health folders, check if a note exists for today if (selectedFolder === 'Diary' || selectedFolder === 'Health') { const today = new Date(); - const dateStr = format(today, 'yyyy-MM-dd'); - const dateTitle = `${dateStr}`; + const dateStr = format(today, 'yyyy-MM-dd'); // For filename + const dateTitle = format(today, 'd MMMM yyyy', { locale: fr }); // For display: "16 janvier 2026" // Check if a note with this date already exists + // We check both the date string (YYYY-MM-DD) and the formatted title const existingNote = notes.find(note => { - // Check if note title starts with today's date - return note.title?.startsWith(dateStr); + // Check if note title matches today's date in any format + const title = note.title || ''; + return title.startsWith(dateStr) || + title.startsWith(dateTitle) || + note.id?.includes(dateStr); }); if (existingNote) { @@ -659,10 +688,10 @@ export default function CarnetPage() { return; } - // Create a new note with today's date as title + // Create a new note with today's date as title (formatted for display) const newNote: Note = { id: '', - title: dateStr, // Use date as title for Diary/Health + title: dateTitle, // Use formatted date for display: "16 janvier 2026" content: '', lastModified: today.toISOString(), type: 'file', diff --git a/components/carnet/editor.tsx b/components/carnet/editor.tsx index 956ccfc..147c89b 100644 --- a/components/carnet/editor.tsx +++ b/components/carnet/editor.tsx @@ -87,7 +87,12 @@ export const Editor: React.FC = ({ note, onSave, currentFolder = 'N // For Diary and Health, if it's a new note (no id), set title to today's date if ((currentFolder === 'Diary' || currentFolder === 'Health') && !note.id) { const today = new Date(); - const dateStr = today.toISOString().split('T')[0]; // YYYY-MM-DD format + // Use French locale for date formatting: "16 janvier 2026" + const dateStr = today.toLocaleDateString('fr-FR', { + day: 'numeric', + month: 'long', + year: 'numeric' + }); setTitle(dateStr); } else { setTitle(note.title || '');