Skip to content

Commit

Permalink
Merge pull request #231 from team-offonoff/feat/modal-mutations
Browse files Browse the repository at this point in the history
  • Loading branch information
chaeyoung103 authored Feb 23, 2024
2 parents c941d1c + 2df9a2e commit d6fbb0d
Show file tree
Hide file tree
Showing 12 changed files with 345 additions and 154 deletions.
39 changes: 38 additions & 1 deletion src/apis/comment/useComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ const reactComment = (commentId: number, reaction: 'like' | 'hate', enable: bool
});
};

const reportComment = (commentId: number) => {
return client.post<CommentReaction>({
path: `/comments/${commentId}/report`,
body: {},
});
};

const deleteComment = (commentId: number) => {
return client.delete<CommentReaction>(`/comments/${commentId}`);
};

const useComments = (topicId: number) => {
return useInfiniteQuery({
queryKey: [COMMENT_KEY, topicId],
Expand Down Expand Up @@ -70,6 +81,18 @@ const useCreateComment = (topicId: number) => {
});
};

const useReportComment = (commentId: number) => {
return useMutation({
mutationFn: () => reportComment(commentId),
});
};

const useDeleteComment = (commentId: number) => {
return useMutation({
mutationFn: () => deleteComment(commentId),
});
};

const useReactComment = (topicId: number, commentId: number) => {
const queryClient = useQueryClient();

Expand Down Expand Up @@ -100,4 +123,18 @@ const useReactComment = (topicId: number, commentId: number) => {
});
};

export { COMMENT_KEY, useComments, useCreateComment, useReactComment, usePreviewComment };
export {
COMMENT_KEY,
getComments,
getCommentPreview,
createComments,
reactComment,
reportComment,
deleteComment,
useComments,
usePreviewComment,
useCreateComment,
useReportComment,
useDeleteComment,
useReactComment,
};
28 changes: 28 additions & 0 deletions src/apis/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,34 @@ class Fetch {
return data;
}

async patch<TData>({
path,
headers,
body,
}: {
path: string;
headers?: HeadersInit;
body: object;
}) {
const response = await fetch(`${this.baseURL}${path}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
...(this.accessToken && { Authorization: `Bearer ${this.accessToken}` }),
...headers,
},
body: JSON.stringify(body),
});

const data = await response.json();

if (!response.ok) {
throw new ResponseError(data);
}

return data as TData;
}

setAccessToken(token: string) {
this.accessToken = token;
}
Expand Down
16 changes: 16 additions & 0 deletions src/apis/topic/useHideTopic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useMutation } from '@tanstack/react-query';

import client from '@apis/fetch';

const hideTopic = (topicId: number) => {
return client.patch({
path: `/topics/${topicId}/hide?hide=true`,
body: {},
});
};

const useHideTopic = (topicId: number) => {
return useMutation({ mutationFn: () => hideTopic(topicId) });
};

export default useHideTopic;
4 changes: 4 additions & 0 deletions src/assets/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import ImageIcon from './image-icon.svg?react';
import KakaoIcon from './kakao.svg?react';
import LeftDoubleArrowIcon from './left-double-arrow.svg?react';
import MeatballIcon from './meatball.svg?react';
import PencilIcon from './pencil.svg?react';
import PlusBoxIcon from './plus-box.svg?react';
import ProfileIcon from './profile.svg?react';
import RefreshIcon from './refresh.svg?react';
Expand All @@ -42,6 +43,7 @@ import SelectedTextIcon from './text-icon-selected.svg?react';
import TextIcon from './text-icon.svg?react';
import ThumbsIcon from './thumbs.svg?react';
import TopicCreatBackgrounIcon from './topic-create-background.svg?react';
import TrashCanIcon from './trash-can.svg?react';
import TrashIcon from './trash.svg?react';
import UpDownChevronIcon from './up-down.svg?react';
import WriteBoxIcon from './write-box.svg?react';
Expand Down Expand Up @@ -72,6 +74,7 @@ export {
KakaoIcon,
LeftDoubleArrowIcon,
MeatballIcon,
PencilIcon,
NewAlarmIcon,
PlusBoxIcon,
ProfileIcon,
Expand All @@ -83,6 +86,7 @@ export {
SizeUpIcon,
ThumbsIcon,
TopicCreatBackgrounIcon,
TrashCanIcon,
UpDownChevronIcon,
WriteBoxIcon,
TextIcon,
Expand Down
6 changes: 6 additions & 0 deletions src/assets/icons/pencil.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/assets/icons/refresh.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/assets/icons/trash-can.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 37 additions & 38 deletions src/components/Home/Comment/Comment.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { TimeUnits, getDateDistance, getDateDistanceText } from '@toss/date';
import React from 'react';

import { useReactComment } from '@apis/comment/useComment';
import { useDeleteComment, useReactComment, useReportComment } from '@apis/comment/useComment';
import { Col, Row } from '@components/commons/Flex/Flex';
import ProfileImg from '@components/commons/ProfileImg/ProfileImg';
import Text from '@components/commons/Text/Text';
import useModal from '@hooks/useModal/useModal';
import useActionSheet from '@hooks/useModal/useActionSheet';
import { CommentResponse } from '@interfaces/api/comment';
import { Choice } from '@interfaces/api/topic';

import { useAuthStore } from '@store/auth';

import { colors } from '@styles/theme';

import { MeatballIcon, ReportIcon } from '@icons/index';
import { MeatballIcon, PencilIcon, ReportIcon, TrashCanIcon } from '@icons/index';

import Thumbs from './Thumbs';

Expand All @@ -23,8 +23,9 @@ interface CommentProps {
}

const Comment = React.memo(({ comment, choices }: CommentProps) => {
const { Modal, toggleModal } = useModal('action');
const reactMutation = useReactComment(comment.topicId, comment.commentId);
const reportMutation = useReportComment(comment.commentId);
const deleteMutation = useDeleteComment(comment.commentId);
const memberId = useAuthStore((store) => store.memberId);
const likeCount = Math.max(
comment.commentReaction.likeCount - comment.commentReaction.hateCount,
Expand All @@ -44,17 +45,17 @@ const Comment = React.memo(({ comment, choices }: CommentProps) => {
};

const handleCommentModify = () => {
// TODO: 수정하기 기능 구현
// TBD: 1차 스펙 아웃
toggleModal();
};

const handleCommentDelete = () => {
// TODO: 삭제하기 기능 구현
deleteMutation.mutate();
toggleModal();
};

const handleCommentReport = () => {
// TODO: 신고하기 기능 구현
reportMutation.mutate();
toggleModal();
};

Expand All @@ -66,6 +67,34 @@ const Comment = React.memo(({ comment, choices }: CommentProps) => {
reactMutation.mutate({ reaction: 'hate', enable: !comment.commentReaction.hated });
};

const { Modal: CommentModal, toggleModal } = useActionSheet({
actions:
memberId === comment.writer.id
? [
{
icon: <PencilIcon />,
label: '수정',
onClick: handleCommentModify,
},
{
icon: <TrashCanIcon />,
label: '삭제',
confirm: {
description: '내가 작성한 댓글을 삭제합니다.',
label: '삭제하기',
onConfirm: handleCommentDelete,
},
},
]
: [
{
icon: <ReportIcon />,
label: '신고하기',
onClick: handleCommentReport,
},
],
});

return (
<React.Fragment>
<Col padding={'14px 20px 24px'}>
Expand Down Expand Up @@ -119,37 +148,7 @@ const Comment = React.memo(({ comment, choices }: CommentProps) => {
</Row>
</Col>
</Col>
<Modal>
{memberId === comment.writer.id ? (
<Col gap={14}>
<button onClick={handleCommentModify}>
<Row alignItems={'center'} gap={14}>
<ReportIcon />
<Text size={16} weight={500}>
수정
</Text>
</Row>
</button>
<button onClick={handleCommentDelete}>
<Row alignItems={'center'} gap={14}>
<ReportIcon />
<Text size={16} weight={500}>
삭제
</Text>
</Row>
</button>
</Col>
) : (
<button onClick={handleCommentReport}>
<Row alignItems={'center'} gap={14}>
<ReportIcon />
<Text size={16} weight={500}>
신고하기
</Text>
</Row>
</button>
)}
</Modal>
<CommentModal />
</React.Fragment>
);
});
Expand Down
Loading

0 comments on commit d6fbb0d

Please sign in to comment.