@@ -42,6 +42,7 @@ const Editor = ({ pageId, initialValue }: EditorProp) => {
4242 const [ openNode , setOpenNode ] = useState ( false ) ;
4343 const [ openColor , setOpenColor ] = useState ( false ) ;
4444 const [ openLink , setOpenLink ] = useState ( false ) ;
45+ const [ saveStatus , setSaveStatus ] = useState ( "Saved" ) ;
4546
4647 const updatePageMutation = useUpdatePage ( ) ;
4748
@@ -50,7 +51,13 @@ const Editor = ({ pageId, initialValue }: EditorProp) => {
5051 if ( pageId === undefined ) return ;
5152
5253 const json = editor . getJSON ( ) ;
53- updatePageMutation . mutate ( { id : pageId , pageData : json } ) ;
54+ const response = await updatePageMutation . mutateAsync ( {
55+ id : pageId ,
56+ pageData : json ,
57+ } ) ;
58+ if ( response ) {
59+ setSaveStatus ( "Saved" ) ;
60+ }
5461 } ,
5562
5663 500 ,
@@ -62,69 +69,77 @@ const Editor = ({ pageId, initialValue }: EditorProp) => {
6269 } , [ pageId ] ) ;
6370
6471 return (
65- < EditorRoot >
66- < EditorContent
67- initialContent = { initialContent === null ? undefined : initialContent }
68- className = "relative h-[720px] w-[520px] overflow-auto border-muted bg-background bg-white sm:rounded-lg sm:border sm:shadow-lg"
69- extensions = { extensions }
70- editorProps = { {
71- handleDOMEvents : {
72- keydown : ( _view , event ) => handleCommandNavigation ( event ) ,
73- } ,
74- attributes : {
75- class : `prose prose-lg prose-headings:font-title font-default focus:outline-none max-w-full` ,
76- } ,
77- } }
78- slotAfter = { < ImageResizer /> }
79- onUpdate = { ( { editor } ) => {
80- debouncedUpdates ( editor ) ;
81- } }
82- >
83- < EditorCommand className = "z-50 h-auto max-h-[330px] overflow-y-auto rounded-md border border-muted bg-background px-1 py-2 shadow-md transition-all" >
84- < EditorCommandEmpty className = "px-2 text-muted-foreground" >
85- No results
86- </ EditorCommandEmpty >
87- < EditorCommandList >
88- { suggestionItems . map ( ( item ) => (
89- < EditorCommandItem
90- value = { item . title }
91- onCommand = { ( val ) => item . command ?.( val ) }
92- className = "flex w-full items-center space-x-2 rounded-md px-2 py-1 text-left text-sm hover:cursor-pointer hover:bg-accent aria-selected:bg-accent"
93- key = { item . title }
94- >
95- < div className = "flex h-10 w-10 items-center justify-center rounded-md border border-muted bg-background" >
96- { item . icon }
97- </ div >
98- < div >
99- < p className = "font-medium" > { item . title } </ p >
100- < p className = "text-xs text-muted-foreground" >
101- { item . description }
102- </ p >
103- </ div >
104- </ EditorCommandItem >
105- ) ) }
106- </ EditorCommandList >
107- </ EditorCommand >
108- < EditorBubble
109- tippyOptions = { {
110- placement : "top" ,
72+ < div className = "relative h-[720px] w-[520px] overflow-auto border-muted bg-background bg-white sm:rounded-lg sm:border sm:shadow-lg" >
73+ < div className = "absolute right-5 top-5 z-10 mb-5 flex gap-2" >
74+ < div className = "rounded-lg bg-accent px-2 py-1 text-sm text-muted-foreground" >
75+ { saveStatus }
76+ </ div >
77+ </ div >
78+ < EditorRoot >
79+ < EditorContent
80+ initialContent = { initialContent === null ? undefined : initialContent }
81+ className = ""
82+ extensions = { extensions }
83+ editorProps = { {
84+ handleDOMEvents : {
85+ keydown : ( _view , event ) => handleCommandNavigation ( event ) ,
86+ } ,
87+ attributes : {
88+ class : `prose prose-lg prose-headings:font-title font-default focus:outline-none max-w-full` ,
89+ } ,
90+ } }
91+ slotAfter = { < ImageResizer /> }
92+ onUpdate = { ( { editor } ) => {
93+ debouncedUpdates ( editor ) ;
94+ setSaveStatus ( "Unsaved" ) ;
11195 } }
112- className = "flex w-fit max-w-[90vw] overflow-hidden rounded-md border border-muted bg-background shadow-xl"
11396 >
114- { " " }
115- < Separator orientation = "vertical" />
116- < NodeSelector open = { openNode } onOpenChange = { setOpenNode } />
117- < Separator orientation = "vertical" />
118- < LinkSelector open = { openLink } onOpenChange = { setOpenLink } />
119- < Separator orientation = "vertical" />
120- < MathSelector />
121- < Separator orientation = "vertical" />
122- < TextButtons />
123- < Separator orientation = "vertical" />
124- < ColorSelector open = { openColor } onOpenChange = { setOpenColor } />
125- </ EditorBubble >
126- </ EditorContent >
127- </ EditorRoot >
97+ < EditorCommand className = "z-50 h-auto max-h-[330px] overflow-y-auto rounded-md border border-muted bg-background px-1 py-2 shadow-md transition-all" >
98+ < EditorCommandEmpty className = "px-2 text-muted-foreground" >
99+ No results
100+ </ EditorCommandEmpty >
101+ < EditorCommandList >
102+ { suggestionItems . map ( ( item ) => (
103+ < EditorCommandItem
104+ value = { item . title }
105+ onCommand = { ( val ) => item . command ?.( val ) }
106+ className = "flex w-full items-center space-x-2 rounded-md px-2 py-1 text-left text-sm hover:cursor-pointer hover:bg-accent aria-selected:bg-accent"
107+ key = { item . title }
108+ >
109+ < div className = "flex h-10 w-10 items-center justify-center rounded-md border border-muted bg-background" >
110+ { item . icon }
111+ </ div >
112+ < div >
113+ < p className = "font-medium" > { item . title } </ p >
114+ < p className = "text-xs text-muted-foreground" >
115+ { item . description }
116+ </ p >
117+ </ div >
118+ </ EditorCommandItem >
119+ ) ) }
120+ </ EditorCommandList >
121+ </ EditorCommand >
122+ < EditorBubble
123+ tippyOptions = { {
124+ placement : "top" ,
125+ } }
126+ className = "flex w-fit max-w-[90vw] overflow-hidden rounded-md border border-muted bg-background shadow-xl"
127+ >
128+ { " " }
129+ < Separator orientation = "vertical" />
130+ < NodeSelector open = { openNode } onOpenChange = { setOpenNode } />
131+ < Separator orientation = "vertical" />
132+ < LinkSelector open = { openLink } onOpenChange = { setOpenLink } />
133+ < Separator orientation = "vertical" />
134+ < MathSelector />
135+ < Separator orientation = "vertical" />
136+ < TextButtons />
137+ < Separator orientation = "vertical" />
138+ < ColorSelector open = { openColor } onOpenChange = { setOpenColor } />
139+ </ EditorBubble >
140+ </ EditorContent >
141+ </ EditorRoot >
142+ </ div >
128143 ) ;
129144} ;
130145
0 commit comments