diff --git a/client/src/components/common/Card/detail/CommentAction.tsx b/client/src/components/common/Card/detail/CommentAction.tsx new file mode 100644 index 00000000..e6f46993 --- /dev/null +++ b/client/src/components/common/Card/detail/CommentAction.tsx @@ -0,0 +1,40 @@ +import { useState } from "react"; + +export default function CommentAction({ id, handleModify }: { id: number; handleModify: (id: number) => void }) { + const [isOpen, setIsOpen] = useState(false); + const handleOpen = () => { + setIsOpen(!isOpen); + }; + return ( +
+ + + {isOpen && } +
+ ); +} + +function DeleteButton({ id, handleOpen }: { id: number; handleOpen: () => void }) { + return ( +
+
+
+ 댓글 삭제 +
+
+

댓글을 정말로 삭제하시겠습니까?

+
+
+ + +
+
+
+ ); +} diff --git a/client/src/components/common/Card/detail/PostComment.tsx b/client/src/components/common/Card/detail/PostComment.tsx new file mode 100644 index 00000000..0ba5b7f7 --- /dev/null +++ b/client/src/components/common/Card/detail/PostComment.tsx @@ -0,0 +1,108 @@ +import { useState } from "react"; + +import { Heart } from "lucide-react"; + +import CommentAction from "@/components/common/Card/detail/CommentAction"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; + +import { timeAgo } from "@/utils/timeago"; + +import { PostCommentType } from "@/types/post"; + +type PostCommentProps = { + comments: PostCommentType[]; +}; +export default function PostComment({ comments }: PostCommentProps) { + const [modifyId, setModifyId] = useState(null); + const handleModify = (id: number | null) => { + setModifyId(id); + }; + return ( +
+ {/* 댓글 입력 영역 */} +
+
+
+ + + CN + + +
+
+
+ +
+
+ + {/* 댓글 목록 헤더 */} +
+

+ 댓글 {comments.length} +

+
+ + {/* 댓글 목록 */} +
    + {comments + .sort((a, b) => Number(new Date(b.createdAt)) - Number(new Date(a.createdAt))) + .map((comment) => ( +
  • +
    + + + {comment.author.substring(0, 2)} + +
    +
    +
    +
    +

    {comment.author}

    +

    {timeAgo(comment.createdAt)}

    + + + {comment.likes} + +
    + {modifyId !== comment.id && } +
    +
    + {modifyId !== comment.id ? ( +

    {comment.content}

    + ) : ( +
    + +
    + + +
    +
    + )} +
    +
    +
  • + ))} +
+ + {/* 더보기 버튼 */} + {comments.length > 1 && ( +
+ +
+ )} +
+ ); +} diff --git a/client/src/components/common/Card/detail/PostContent.tsx b/client/src/components/common/Card/detail/PostContent.tsx index cc69e3df..d8df645b 100644 --- a/client/src/components/common/Card/detail/PostContent.tsx +++ b/client/src/components/common/Card/detail/PostContent.tsx @@ -2,10 +2,13 @@ import React from "react"; import Markdown from "react-markdown"; import LikeButton from "@/components/common/Card/detail/LikeButton"; +import PostComment from "@/components/common/Card/detail/PostComment"; import ShareButton from "@/components/common/Card/detail/ShareButton"; import { usePostCardActions } from "@/hooks/common/usePostCardActions"; +import { POST_COMMENT_DATA } from "@/constants/dummyData"; + import { useMediaStore } from "@/store/useMediaStore"; import { Post } from "@/types/post"; @@ -51,10 +54,11 @@ export const PostContent = React.memo(({ post }: PostContentProps) => {

💡 인공지능이 요약한 내용입니다. 오류가 포함될 수 있으니 참고 바랍니다.

)} -
+
+
); }); diff --git a/client/src/constants/dummyData.ts b/client/src/constants/dummyData.ts index 17fa3fc6..fad9d5ff 100644 --- a/client/src/constants/dummyData.ts +++ b/client/src/constants/dummyData.ts @@ -1,5 +1,6 @@ import { ChatType } from "@/types/chat"; import { PostDetailType } from "@/types/post"; +import { PostCommentType } from "@/types/post"; // export const TRENDING_POSTS: Post[] = [ // { @@ -151,3 +152,23 @@ export const POST_MODAL_DATA: PostDetailType = { tag: ["JavaScript", "React", "Frontend"], }, }; +export const POST_COMMENT_DATA: PostCommentType[] = [ + { + id: 1, + author: "나무보다 숲을", + content: "정말 유익한 포스트에요!!", + authorImage: "https://github.com/shadcn.png", + createdAt: "2025-03-23T01:00:00.000Z", + likes: 5, + isLiked: true, + }, + { + id: 2, + author: "월성참치", + content: "엌ㅋㅋㅋ 개추요", + authorImage: "https://github.com/shadcn.png", + createdAt: "2025-03-24T01:00:00.000Z", + likes: 10, + isLiked: false, + }, +]; diff --git a/client/src/hooks/common/usePostCardActions.ts b/client/src/hooks/common/usePostCardActions.ts index 52521dec..5f7cc37f 100644 --- a/client/src/hooks/common/usePostCardActions.ts +++ b/client/src/hooks/common/usePostCardActions.ts @@ -1,6 +1,5 @@ import { usePostViewIncrement } from "@/hooks/queries/usePostViewIncrement"; -// import { pipe } from "@/utils/pipe"; import { Post } from "@/types/post"; interface PostWithState { @@ -24,7 +23,7 @@ export const usePostCardActions = (post: Post) => { if (isWindowOpened) { mutate(undefined, { onSuccess: () => { - console.log("조회수 증가 성공"); + // console.log("조회수 증가 성공"); }, onError: (error) => { console.error("조회수 증가 실패", error); diff --git a/client/src/types/post.ts b/client/src/types/post.ts index a561e496..d468fbcd 100644 --- a/client/src/types/post.ts +++ b/client/src/types/post.ts @@ -37,3 +37,12 @@ export interface PostDetailType { message: string; data: Post; } +export interface PostCommentType { + id: number; + author: string; + content: string; + authorImage: string; + createdAt: string; + likes: number; + isLiked: boolean; +} diff --git a/client/src/utils/timeago.ts b/client/src/utils/timeago.ts new file mode 100644 index 00000000..fce18ab4 --- /dev/null +++ b/client/src/utils/timeago.ts @@ -0,0 +1,13 @@ +export function timeAgo(dateString: string) { + const now = new Date(); + const past = new Date(dateString); + const diff = Number(now) - Number(past); + + const diffMin = Math.floor(diff / (1000 * 60)); + const diffHour = Math.floor(diff / (1000 * 60 * 60)); + const diffDay = Math.floor(diff / (1000 * 60 * 60 * 24)); + + if (diffMin < 60) return `${diffMin}분 전`; + if (diffHour < 24) return `${diffHour}시간 전`; + return `${diffDay}일 전`; +}