diff --git a/src/components/post/PostInfoSection.tsx b/src/components/post/PostInfoSection.tsx
index 049110b..ccb6e95 100644
--- a/src/components/post/PostInfoSection.tsx
+++ b/src/components/post/PostInfoSection.tsx
@@ -5,6 +5,7 @@ import PostMenuModal from './PostMenuModal'
import CommentItem from './CommentItem'
import PostActionSection from './PostActionSection'
import { formatRelativeTime } from '../../utils/date.ts'
+import { instance } from '../../shared/api/ky'
interface Comment {
id: number
@@ -16,6 +17,9 @@ interface Comment {
createdAt: string
updatedAt: string
parentId: number | null
+ likeCount: number
+ liked: boolean
+ likedUserIds: number[]
}
export default function PostInfoSection({ data }: { data: PostData | null }) {
@@ -37,19 +41,30 @@ export default function PostInfoSection({ data }: { data: PostData | null }) {
isFetching.current = true
try {
- const response = await fetch(
- `/api/v1/posts/${postId}/comments?page=${pageNum}`
- )
- const result = await response.json()
+ const response = await instance
+ .get(`api/v1/posts/${postId}/comments`, {
+ searchParams: { page: pageNum },
+ })
+ .json<{ data: Comment[]; success: boolean }>()
+
+ if (response.success && response.data.length > 0) {
+ const newComments = response.data
+
+ setLikedComments((prev) => {
+ const nextLiked = { ...prev }
+ newComments.forEach((c: Comment) => {
+ nextLiked[c.id] = c.liked
+ })
+ return nextLiked
+ })
- if (result.isSuccess && result.data.length > 0) {
setComments((prev) => {
- if (pageNum === 1) return result.data
+ if (pageNum === 1) return newComments
const existingIds = new Set(prev.map((c) => c.id))
- const newComments = result.data.filter(
+ const filtered = newComments.filter(
(c: Comment) => !existingIds.has(c.id)
)
- return [...prev, ...newComments]
+ return [...prev, ...filtered]
})
pageRef.current = pageNum
setHasMore(true)
@@ -62,7 +77,7 @@ export default function PostInfoSection({ data }: { data: PostData | null }) {
isFetching.current = false
}
},
- [data]
+ [data?.id]
)
useEffect(() => {
@@ -92,34 +107,85 @@ export default function PostInfoSection({ data }: { data: PostData | null }) {
}
}, [hasMore, fetchComments])
- const handleDoubleClick = (id: number) => {
- if (!likedComments[id]) {
- setLikedComments((p) => ({ ...p, [id]: true }))
+ const handleCommentSubmit = async (content: string) => {
+ const postId = data?.id
+ if (!postId) return
+
+ try {
+ const response = await instance
+ .post(`api/v1/posts/${postId}/comments`, {
+ json: { content },
+ })
+ .json<{ data: Comment; success: boolean }>()
+
+ if (response.success) {
+ setComments((prev) => [response.data, ...prev])
+ setLikedComments((prev) => ({
+ ...prev,
+ [response.data.id]: response.data.liked,
+ }))
+ }
+ } catch (error) {
+ console.error(error)
}
}
- const handleHeartClick = (id: number, e: React.MouseEvent) => {
- e.stopPropagation()
- setLikedComments((p) => ({ ...p, [id]: !p[id] }))
+ const handleHeartClick = async (commentId: number, e?: React.MouseEvent) => {
+ e?.stopPropagation()
+ const postId = data?.id
+ if (!postId) return
+
+ const isCurrentlyLiked = !!likedComments[commentId]
+
+ try {
+ if (isCurrentlyLiked) {
+ await instance.delete(
+ `api/v1/posts/${postId}/comments/${commentId}/like`
+ )
+ } else {
+ await instance.post(`api/v1/posts/${postId}/comments/${commentId}/like`)
+ }
+
+ setLikedComments((p) => ({ ...p, [commentId]: !isCurrentlyLiked }))
+ setComments((prev) =>
+ prev.map((c) =>
+ c.id === commentId
+ ? {
+ ...c,
+ likeCount: Math.max(
+ 0,
+ c.likeCount + (isCurrentlyLiked ? -1 : 1)
+ ),
+ }
+ : c
+ )
+ )
+ } catch (error) {
+ console.error(error)
+ }
+ }
+
+ const handleDoubleClick = (id: number) => {
+ if (!likedComments[id]) {
+ handleHeartClick(id)
+ }
}
return (
- {data?.userImage ? (
+ {data?.profileImageUrl ? (

) : (
-
- {data?.username?.trim().slice(0, 1).toUpperCase() || '?'}
-
+
)}
- {data?.username || ''}
+ {data?.nickname || ''}