From ccbd1b5abc9ba8aee8bdbc1df4564c3c68501a37 Mon Sep 17 00:00:00 2001 From: Antigravity Date: Thu, 7 May 2026 22:35:52 +0000 Subject: [PATCH] feat: fullPage layout 1:1 prototype - white bg, px-12 py-8 toolbar, rounded-full buttons, breadcrumb notebook>date, hero image, prose-lg content --- memento-note/components/note-editor.tsx | 390 ++++++++++++++---------- 1 file changed, 230 insertions(+), 160 deletions(-) diff --git a/memento-note/components/note-editor.tsx b/memento-note/components/note-editor.tsx index 8475e46..2164c3d 100644 --- a/memento-note/components/note-editor.tsx +++ b/memento-note/components/note-editor.tsx @@ -25,7 +25,7 @@ import { } from '@/components/ui/dropdown-menu' import { NoteTypeSelector } from '@/components/note-type-selector' import { RichTextEditor } from '@/components/rich-text-editor' -import { X, Plus, Palette, Image as ImageIcon, Bell, Eye, Link as LinkIcon, Sparkles, Maximize2, Copy, Wand2, LogOut, ArrowLeft, Info, Check, Loader2 } from 'lucide-react' +import { X, Plus, Palette, Image as ImageIcon, Bell, Eye, Link as LinkIcon, Sparkles, Maximize2, Copy, Wand2, LogOut, ArrowLeft, ChevronRight, Info, Check, Loader2 } from 'lucide-react' import { updateNote, createNote, cleanupOrphanedImages, leaveSharedNote } from '@/app/actions/notes' import { format } from 'date-fns' import { useTitleSuggestions } from '@/hooks/use-title-suggestions' @@ -658,187 +658,257 @@ export function NoteEditor({ note, readOnly = false, onClose, fullPage = false } } } - // ── fullPage mode: early return with editorial layout ── + // ── fullPage mode: editorial layout (fidèle au prototype) ── if (fullPage) { + const notebookName = notebooks.find(nb => nb.id === note.notebookId)?.name || null + const plainFirstSentence = content.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim().split(/[.!?]/)[0] + return ( <> -
-
- {/* main scrollable column */} -
+ {/* ── outer container: white like prototype ── */} +
- {/* sticky toolbar — matches prototype */} -
- + + {/* Right: status + type + AI + Info */} +
+ {/* Save status */} + + {isSaving + ? <>Saving… + : isDirty + ? <>Modified + : <>Saved} + + + {/* Note type */} + { setNoteType(newType); setShowMarkdownPreview(newType === 'markdown'); setIsDirty(true) }} + compact + /> + + {/* AI — rounded-full, exact prototype style */} + -
- {/* Save status */} - - {isSaving - ? <>{t('notes.saving') || 'Enregistrement...'} - : isDirty - ? <>{t('notes.dirtyStatus') || 'Modifié'} - : <>{t('notes.savedStatus') || 'Enregistré'}} - - {/* Type selector */} - { setNoteType(newType); setShowMarkdownPreview(newType === 'markdown'); setIsDirty(true) }} - compact - /> - {/* AI button — rounded-full like prototype */} - - {/* Info button */} - -
-
- {/* body */} -
- {/* meta */} -
- {format(new Date(note.contentUpdatedAt), 'MMM d, yyyy')} -
- - {/* title + AI */} -
-
- { setTitle(e.target.value); setIsDirty(true); setDismissedTitleSuggestions(true) }} - disabled={readOnly} - className="w-full text-5xl md:text-6xl font-memento-serif font-bold border-0 outline-none px-0 bg-transparent text-foreground leading-tight placeholder:text-muted-foreground/30 pr-14" - /> - {!title && !readOnly && ( - - )} -
- {!title && !dismissedTitleSuggestions && autoTitleSuggestions.length > 0 && ( - { setTitle(s); setDismissedTitleSuggestions(true); setIsDirty(true) }} - onDismiss={() => setDismissedTitleSuggestions(true)} - /> + {/* Info — rounded-full */} +
- - {/* editor */} -
- {noteType === 'richtext' ? ( - { setContent(v); setIsDirty(true) }} - className="min-h-[200px] text-lg font-light leading-relaxed" - onImageUpload={uploadImageFile} - /> - ) : noteType === 'markdown' && showMarkdownPreview ? ( -
setShowMarkdownPreview(false)} - > - -

Cliquez pour éditer

-
- ) : ( -
-