33import { useEffect , useState } from "react" ;
44import { useRouter } from "next/navigation" ;
55
6+ import Sidebar from "@/components/sidebar" ;
67import { Button } from "@/components/ui/button" ;
78import { Input } from "@/components/ui/input" ;
89import { TOPIC } from "@/constants/topic" ;
@@ -12,8 +13,6 @@ import { useTopicStore } from "@/lib/zustand/topic-store";
1213import { revalidatePath } from "@/utils/revalidate" ;
1314import { errorToast , successToast } from "@/utils/toast" ;
1415import { Dialog , DialogTrigger } from "@repo/ui/components/dialog" ;
15- import { useOutsideClick } from "@repo/ui/hooks/use-outside-click" ;
16- import { cn } from "@repo/ui/utils/cn" ;
1716import CodeBlock from "@tiptap/extension-code-block" ;
1817import Highlight from "@tiptap/extension-highlight" ;
1918import Image from "@tiptap/extension-image" ;
@@ -38,16 +37,18 @@ export default function EditTopicSidebar() {
3837 const { setEditingTopic, setShowEditTopicSidebar, editingTopic, showEditTopicSidebar } =
3938 useTopicStore ( ) ;
4039
40+ const buttonDisabled = isUpdatePending || isDeletePending ;
41+
4142 const onClose = ( ) => {
4243 setEditingTopic ( null ) ;
4344 setShowEditTopicSidebar ( false ) ;
4445 } ;
4546
46- const [ sidebarRef ] = useOutsideClick < HTMLDivElement > ( ( ) => {
47+ const onClickOutside = ( ) => {
4748 if ( ! isDeleteModalOpen ) {
4849 onClose ( ) ;
4950 }
50- } ) ;
51+ } ;
5152
5253 const editor = useEditor ( {
5354 extensions : [
@@ -143,93 +144,76 @@ export default function EditTopicSidebar() {
143144 } ;
144145
145146 return (
146- < div
147- className = { cn (
148- "pointer-events-none fixed inset-0 z-50" ,
149- showEditTopicSidebar && "pointer-events-auto bg-black/50"
150- ) }
151- aria-label = "토픽 편집 사이드바 닫기"
152- >
153- { /* 사이드바 */ }
154- < div
155- ref = { sidebarRef }
156- className = { cn (
157- "fixed top-0 right-0 z-50 h-full w-full max-w-xl transform bg-white shadow-xl transition-all duration-300 ease-out" ,
158- showEditTopicSidebar ? "translate-x-0" : "translate-x-full"
159- ) }
160- >
161- < div className = "flex h-full flex-col" >
162- { /* 헤더 */ }
163- < div className = "flex items-center justify-between border-b p-6" >
164- < h2 className = "text-xl font-semibold" > 토픽 편집</ h2 >
165- < Button variant = "ghost" size = "icon" onClick = { onCloseSidebar } aria-label = "사이드바 닫기" >
166- < X size = { 24 } />
167- </ Button >
147+ < Sidebar isOpen = { showEditTopicSidebar } onClose = { onClickOutside } >
148+ < div className = "flex h-full flex-col" >
149+ { /* 헤더 */ }
150+ < div className = "flex items-center justify-between border-b p-6" >
151+ < h2 className = "text-xl font-semibold" > 토픽 편집</ h2 >
152+ < Button variant = "ghost" size = "icon" onClick = { onCloseSidebar } aria-label = "사이드바 닫기" >
153+ < X size = { 24 } />
154+ </ Button >
155+ </ div >
156+
157+ { /* 내용 */ }
158+ < div className = "flex-1 space-y-6 overflow-y-auto p-6" >
159+ { /* 제목 입력 */ }
160+ < div >
161+ < label className = "mb-2 block text-base font-medium" > 제목</ label >
162+ < Input
163+ value = { title }
164+ onChange = { ( e ) => setTitle ( e . target . value ) }
165+ placeholder = "토픽 제목을 입력하세요"
166+ className = "text-base"
167+ />
168168 </ div >
169169
170- { /* 내용 */ }
171- < div className = "flex-1 overflow-y-auto p-6" >
172- < div className = "space-y-6" >
173- { /* 제목 입력 */ }
174- < div >
175- < label className = "mb-2 block text-base font-medium" > 제목</ label >
176- < Input
177- value = { title }
178- onChange = { ( e ) => setTitle ( e . target . value ) }
179- placeholder = "토픽 제목을 입력하세요"
180- className = "text-base"
181- />
182- </ div >
183-
184- { /* 리치 텍스트 툴바 */ }
185- { editor && < EditTopicTooltipList editor = { editor } /> }
186-
187- { /* 리치 텍스트 에디터 */ }
188- < div >
189- < label className = "mb-2 block text-base font-medium" > 내용</ label >
190- < div className = "min-h-[400px] rounded-md border bg-white" >
191- < EditorContent editor = { editor } />
192- </ div >
193- </ div >
194- </ div >
170+ { /* 리치 텍스트 툴바 */ }
171+ { editor && < EditTopicTooltipList editor = { editor } /> }
172+
173+ { /* 리치 텍스트 에디터 */ }
174+ < div className = "" >
175+ < label className = "block text-base font-medium" > 내용</ label >
176+ < EditorContent editor = { editor } className = "rounded-md border bg-white" />
195177 </ div >
178+ </ div >
196179
197- { /* 액션 버튼 */ }
198- < div className = "border-t p-6" >
199- < div className = "flex gap-2" >
180+ { /* 액션 버튼 */ }
181+ < div className = "border-t p-6" >
182+ < div className = "flex gap-2" >
183+ < Button
184+ onClick = { onSave }
185+ className = "h-12 flex-1 text-base"
186+ disabled = { buttonDisabled || ! title . trim ( ) }
187+ >
188+ { isUpdatePending ? (
189+ < Loader2 size = { 18 } className = "mr-2 animate-spin" />
190+ ) : (
191+ < >
192+ < Save size = { 18 } className = "mr-2" />
193+ 저장
194+ </ >
195+ ) }
196+ </ Button >
197+ < Dialog >
200198 < Button
201- onClick = { onSave }
202- className = "h-12 flex-1 text-base"
203- disabled = { isUpdatePending || ! title . trim ( ) }
199+ className = "h-12 bg-red-400 text-base hover:bg-red-500"
200+ asChild
201+ disabled = { buttonDisabled }
204202 >
205- { isUpdatePending ? (
206- < Loader2 size = { 18 } className = "mr-2 animate-spin" />
207- ) : (
208- < Save size = { 18 } className = "mr-2" />
209- ) }
210- 저장
203+ < DialogTrigger >
204+ < Trash2 size = { 18 } className = "mr-2" />
205+ 삭제
206+ </ DialogTrigger >
211207 </ Button >
212- < Dialog >
213- < Button
214- className = "h-12 bg-red-400 text-base hover:bg-red-500"
215- asChild
216- disabled = { isUpdatePending || isDeletePending }
217- >
218- < DialogTrigger >
219- < Trash2 size = { 18 } className = "mr-2" />
220- 삭제
221- </ DialogTrigger >
222- </ Button >
223- < RemoveDialogContent
224- id = { editingTopic ?. id || null }
225- setIsDeleteModalOpen = { setIsDeleteModalOpen }
226- onDelete = { onDelete }
227- />
228- </ Dialog >
229- </ div >
208+ < RemoveDialogContent
209+ id = { editingTopic ?. id || null }
210+ setIsDeleteModalOpen = { setIsDeleteModalOpen }
211+ onDelete = { onDelete }
212+ />
213+ </ Dialog >
230214 </ div >
231215 </ div >
232216 </ div >
233- </ div >
217+ </ Sidebar >
234218 ) ;
235219}
0 commit comments