diff --git a/client/src/components/post/detail/PostComment.tsx b/client/src/components/post/detail/PostComment.tsx
index 3e21efc..f0a0cb6 100644
--- a/client/src/components/post/detail/PostComment.tsx
+++ b/client/src/components/post/detail/PostComment.tsx
@@ -5,6 +5,7 @@ import { Stack, Avatar, Typography } from "@mui/material";
import dayjs from "dayjs";
import Link from "next/link";
import PostCommentDropdown from "./PostCommentDropdown";
+import useDeleteCommentMutation from "@/queries/post/comment/useDeleteCommentMutation";
type Props = {
content: string;
@@ -13,6 +14,8 @@ type Props = {
userPk: string;
profileImg?: string;
createdAt: string;
+ commentPk: string;
+ postPk: string;
};
const PostComment = ({
@@ -22,10 +25,13 @@ const PostComment = ({
createdAt,
profileImg,
userPk,
+ postPk,
+ commentPk,
}: Props) => {
const { data: myData } = useMyInfoQuery();
const isMyComment = userPk === String(myData?.userNo);
+ const { mutateAsync: onDelete } = useDeleteCommentMutation();
return (
@@ -50,7 +56,17 @@ const PostComment = ({
{dayjs(createdAt).format("MM.DD")}
- {isMyComment && }
+ {isMyComment && (
+ {
+ onDelete({
+ commentPk: String(commentPk),
+ postPk: String(postPk),
+ });
+ }}
+ onEdit={() => {}}
+ />
+ )}
{content}
diff --git a/client/src/components/post/detail/PostCommentDropdown.tsx b/client/src/components/post/detail/PostCommentDropdown.tsx
index 734c0c4..c2b957e 100644
--- a/client/src/components/post/detail/PostCommentDropdown.tsx
+++ b/client/src/components/post/detail/PostCommentDropdown.tsx
@@ -2,7 +2,15 @@ import { ButtonBase, Menu, MenuItem } from "@mui/material";
import { MoreVertOutlined } from "@mui/icons-material";
import { useState } from "react";
-const PostCommentDropdown = () => {
+interface PostCommentDropdownInterface {
+ onDelete: () => void;
+ onEdit: () => void;
+}
+
+const PostCommentDropdown = ({
+ onDelete,
+ onEdit,
+}: PostCommentDropdownInterface) => {
const [anchorEl, setAnchorEl] = useState(null);
const open = Boolean(anchorEl);
@@ -13,23 +21,15 @@ const PostCommentDropdown = () => {
const handleClose = () => {
setAnchorEl(null);
};
-
+
return (
<>
>
);
diff --git a/client/src/components/post/detail/PostCommentList.tsx b/client/src/components/post/detail/PostCommentList.tsx
index e9c71f1..81938d7 100644
--- a/client/src/components/post/detail/PostCommentList.tsx
+++ b/client/src/components/post/detail/PostCommentList.tsx
@@ -22,8 +22,7 @@ const PostCommentList = ({ postNo }: Props) => {
nickname,
userId,
profileImgUrls,
- },
- i
+ }
) => (
{
profileImg={profileImgUrls?.[0]?.attachUrl}
userId={userId}
userPk={String(createdBy)}
+ commentPk={String(commentNo)}
+ postPk={postNo}
key={commentNo}
/>
)
diff --git a/client/src/const/serverPath.ts b/client/src/const/serverPath.ts
index 15aa942..30f8ca2 100644
--- a/client/src/const/serverPath.ts
+++ b/client/src/const/serverPath.ts
@@ -15,7 +15,7 @@ export const MY_INFO = "/user/me" as const;
/**
* 유저정보를 수정하는 path
*/
-export const PATCH_USER_INFO = '/user' as const
+export const PATCH_USER_INFO = "/user" as const;
/**
* 쿠키를 심어주는 로그인 BFF
@@ -33,7 +33,16 @@ export const POST_LIST = "/posts" as const;
/**
* 게시물 pk 를 입력받아 댓글을 조회,생성 하는 URL
*/
-export const POST_COMMENT = (pk:string) => `${POST_LIST}/${pk}/comments`
+export const POST_COMMENT = (pk: string) => `${POST_LIST}/${pk}/comments`;
+
+/**
+ * 게시글Pk와 댓글 PK를 입력받아 댓글 삭제를 요청하는 URL
+ * @param postPk
+ * @param commentPk
+ * @returns
+ */
+export const DELETE_COMMENT = (postPk: string, commentPk: string) =>
+ `${POST_LIST}/${postPk}/comments/${commentPk}`;
/**
* 게시물리스트를 받아오거나, 작성하는 Path 버전2 (Breaking Change)
@@ -71,8 +80,6 @@ export const REMOVE_FILE = (attachNo: string) => `/attach/${attachNo}` as const;
*/
export const GET_ALCOHOL_LIST = "/alcohols" as const;
-
-
/**
* 포스트의 PK를 입력받아 해당 PK의 게시글의 좋아요 취소를 요청
* @param id 게시글의 PK
diff --git a/client/src/queries/post/comment/useDeleteCommentMutation.ts b/client/src/queries/post/comment/useDeleteCommentMutation.ts
new file mode 100644
index 0000000..59f13e7
--- /dev/null
+++ b/client/src/queries/post/comment/useDeleteCommentMutation.ts
@@ -0,0 +1,59 @@
+import { DELETE_COMMENT } from "@/const/serverPath";
+import useAxiosPrivate from "@/hooks/useAxiosPrivate";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { commentQueryKey } from "./useGetCommentQuery";
+import PostCommentListInterface from "@/types/post/PostCommentInterface";
+import { useErrorHandler } from "@/utils/errorHandler";
+
+const useDeleteCommentMutation = () => {
+ const queryClient = useQueryClient();
+ const errorHandler = useErrorHandler();
+
+ return useMutation({
+ mutationFn: ({ postPk, commentPk }: deleteCommentInterface) =>
+ deleteComment({ postPk, commentPk }),
+
+ onMutate({ commentPk,postPk }) {
+ queryClient.cancelQueries({ queryKey: commentQueryKey.byId(commentPk) });
+
+ const querySnapShot = queryClient.getQueryData(
+ commentQueryKey.byId(postPk)
+ );
+
+ queryClient.setQueryData(
+ commentQueryKey.byId(postPk),
+ (prev) => ({
+ list: (prev?.list ?? []).filter(
+ ({commentNo}) => String(commentNo) !== String(commentPk)
+ ),
+ totalCount: (prev?.totalCount ?? 0) - 1,
+ })
+ );
+ return { querySnapShot };
+ },
+ onError(err, queryFnParams, context) {
+ errorHandler(err);
+ queryClient.setQueryData(
+ commentQueryKey.byId(queryFnParams.postPk),
+ context?.querySnapShot
+ );
+ },
+ onSuccess(_data, variables) {
+ queryClient.invalidateQueries({
+ queryKey: commentQueryKey.byId(variables.postPk),
+ });
+ },
+ });
+};
+
+interface deleteCommentInterface {
+ postPk: string;
+ commentPk: string;
+}
+const deleteComment = async ({ postPk, commentPk }: deleteCommentInterface) => {
+ const axiosPrivate = useAxiosPrivate();
+ const { data } = await axiosPrivate.delete(DELETE_COMMENT(postPk, commentPk));
+ return data;
+};
+
+export default useDeleteCommentMutation;