11'use client' ; 
2+ import  {  useRef  }  from  'react' ; 
23
34import  {  APIBook  }  from  '@/types/book' ; 
45import  {  useBookTitle  }  from  '@/queries/book/useBookInfoQuery' ; 
6+ import  {  useHasBookComment  }  from  '@/queries/book/useBookCommentsQuery' ; 
7+ import  useCreateBookCommentMutation  from  '@/queries/book/useCreateBookCommentMutation' ; 
8+ import  useToast  from  '@/v1/base/Toast/useToast' ; 
9+ import  useDisclosure  from  '@/hooks/useDisclosure' ; 
10+ import  { 
11+   checkAuthentication , 
12+   isAxiosErrorWithCustomCode , 
13+ }  from  '@/utils/helpers' ; 
14+ import  {  SERVICE_ERROR_MESSAGE  }  from  '@/constants' ; 
515
616import  Skeleton  from  '@/v1/base/Skeleton' ; 
717import  SSRSafeSuspense  from  '@/components/SSRSafeSuspense' ; 
818import  TopNavigation  from  '@/v1/base/TopNavigation' ; 
919import  BottomActionButton  from  '@/v1/base/BottomActionButton' ; 
20+ import  LoginBottomActionButton  from  '@/v1/base/LoginBottomActionButton' ; 
21+ import  CommentDrawer  from  '@/v1/comment/CommentDrawer' ; 
1022import  BackButton  from  '@/v1/base/BackButton' ; 
1123import  BookInfo ,  {  BookInfoSkeleton  }  from  '@/v1/book/detail/BookInfo' ; 
1224import  BookCommentList  from  '@/v1/comment/BookCommentList' ; 
@@ -16,6 +28,8 @@ const BookDetailPage = ({
1628} : { 
1729  params : {  bookId : APIBook [ 'bookId' ]  } ; 
1830} )  =>  { 
31+   const  isAuthenticated  =  checkAuthentication ( ) ; 
32+ 
1933  return  ( 
2034    < > 
2135      < BookTopNavigation  bookId = { bookId }  /> 
@@ -27,8 +41,12 @@ const BookDetailPage = ({
2741            < BookCommentList  bookId = { bookId }  /> 
2842          </ div > 
2943        </ div > 
44+         { isAuthenticated  ? ( 
45+           < AddBookCommentButton  bookId = { bookId }  /> 
46+         )  : ( 
47+           < LoginBottomActionButton  /> 
48+         ) } 
3049      </ SSRSafeSuspense > 
31-       < BottomActionButton > 코멘트 작성하기</ BottomActionButton > 
3250    </ > 
3351  ) ; 
3452} ; 
@@ -63,6 +81,65 @@ const Heading = ({ text }: { text: string }) => (
6381  < p  className = "text-xl font-bold" > { text } </ p > 
6482) ; 
6583
84+ const  AddBookCommentButton  =  ( {  bookId } : {  bookId : APIBook [ 'bookId' ]  } )  =>  { 
85+   const  { 
86+     isOpen : isDrawerOpen , 
87+     onOpen : onDrawerOpen , 
88+     onClose : onDrawerClose , 
89+   }  =  useDisclosure ( ) ; 
90+   const  {  show : showToast  }  =  useToast ( ) ; 
91+ 
92+   const  commentRef  =  useRef < HTMLTextAreaElement > ( null ) ; 
93+   const  createComment  =  useCreateBookCommentMutation ( bookId ) ; 
94+ 
95+   const  {  data : hasBookComment  }  =  useHasBookComment ( bookId ) ; 
96+ 
97+   const  handleCommentCreate  =  ( )  =>  { 
98+     const  comment  =  commentRef . current ?. value ; 
99+ 
100+     if  ( ! comment )  { 
101+       return ; 
102+     } 
103+ 
104+     createComment . mutate ( comment ,  { 
105+       onSuccess : ( )  =>  { 
106+         onDrawerClose ( ) ; 
107+         showToast ( {  type : 'success' ,  message : '코멘트를 등록했어요 🎉'  } ) ; 
108+       } , 
109+       onError : error  =>  { 
110+         if  ( isAxiosErrorWithCustomCode ( error ) )  { 
111+           const  {  code }  =  error . response . data ; 
112+           const  message  =  SERVICE_ERROR_MESSAGE [ code ] ; 
113+           showToast ( {  type : 'error' ,  message } ) ; 
114+           return ; 
115+         } 
116+ 
117+         showToast ( {  type : 'error' ,  message : '코멘트를 등록하지 못했어요 🥲'  } ) ; 
118+       } , 
119+     } ) ; 
120+   } ; 
121+ 
122+   if  ( hasBookComment )  { 
123+     return  null ; 
124+   } 
125+ 
126+   return  ( 
127+     < > 
128+       < BottomActionButton  onClick = { onDrawerOpen } > 
129+         코멘트 작성하기
130+       </ BottomActionButton > 
131+       < CommentDrawer 
132+         isOpen = { isDrawerOpen } 
133+         onClose = { onDrawerClose } 
134+         title = "책 코멘트 작성하기" 
135+         placeholder = "작성해주신 코멘트가 다른 사람들에게 많은 도움이 될 거예요!" 
136+         onConfirm = { handleCommentCreate } 
137+         ref = { commentRef } 
138+       /> 
139+     </ > 
140+   ) ; 
141+ } ; 
142+ 
66143const  BookTitleSkeleton  =  ( )  =>  ( 
67144  < Skeleton > 
68145    < Skeleton . Text  fontSize = "medium"  width = "20rem"  /> 
0 commit comments