Skip to content

Commit 10c7877

Browse files
committed
feat: 자동 저장 상태 표시 기능 추가
1 parent e870d9e commit 10c7877

File tree

1 file changed

+77
-62
lines changed

1 file changed

+77
-62
lines changed

frontend/src/components/editor/index.tsx

Lines changed: 77 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)