Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 신고하기 API 하나로 통합 및 유저 신고기능 추가 #360

Merged
merged 4 commits into from
Oct 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ const App = () => {
path={navigatePath.BOOKMARK_REPORT}
element={<ReportPage mode="BOOKMARK" />}
/>
<Route
path={navigatePath.MEMBER_REPORT}
element={<ReportPage mode="MEMBER" />}
/>
<Route
path={navigatePath.USER}
element={<UserCreatePage mode="CREATE" />}
Expand Down
59 changes: 0 additions & 59 deletions src/bookmarks/api/bookmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import {
useQuery,
useQueryClient,
} from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import { AxiosError } from 'axios';
import dayjs from 'dayjs';
import 'dayjs/locale/ko';
import { GET_LIKE_BOOKMARK_LIST } from './like';
Expand Down Expand Up @@ -790,63 +788,6 @@ export const usePUTBookmarkQuery = ({
});
};

// 북마크 신고
interface POSTBookmarkReportRequest {
reporterId: number;
reportedId: number;
content: string;
}

const postBookmarkReportAPI = async (params: POSTBookmarkReportRequest) => {
const { data } = await client({
method: 'post',
url: '/reports/bookmarks',
data: params,
});

return data;
};

export interface POSTBookmarkReportMutation {
reporterId: number;
}

export const usePOSTBookmarkReportMutation = ({
reporterId,
}: POSTBookmarkReportMutation) => {
const queryClient = useQueryClient();
const toast = useToast();
const router = useNavigate();
return useMutation(postBookmarkReportAPI, {
onSuccess: () => {
queryClient.invalidateQueries(
GET_BOOKMARK_LIST(reporterId, '📖 전체', 0),
);
queryClient.invalidateQueries(
GET_BOOKMARK_LIST(reporterId, '👀 읽음', 0),
);
queryClient.invalidateQueries(
GET_BOOKMARK_LIST(reporterId, '🫣 읽지 않음', 0),
);
toast.fireToast({
message: '신고 되었습니다',
mode: 'SUCCESS',
});
router(-1);
},
onError: (e: AxiosError) => {
const errorCode = e.response?.status;
if (errorCode && errorCode === 409) {
toast.fireToast({
message: '이미 신고한 북마크에요',
mode: 'DELETE',
});
router(-1);
}
},
});
};

// TODO : 추후 테스트 코드 작성
const getKeyofObject = <T extends object>(obj: T, value: unknown) =>
(Object.keys(obj) as (keyof T)[]).find((key) => obj[key] === value);
47 changes: 0 additions & 47 deletions src/comment/api/Comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import {
refetchAllBookmarkQuery,
} from '@/bookmarks/api/bookmark';
import useToast from '@/common-ui/Toast/hooks/useToast';
import { useNavigate } from 'react-router-dom';
import { AxiosError } from 'axios';
import useAuthStore from '@/store/auth';
import useBookmarkStore from '@/store/bookmark';

Expand Down Expand Up @@ -213,48 +211,3 @@ export const useDELETECommentQuery = ({
},
});
};

// 댓글 신고
interface POSTCommentReportRequest {
reporterId: number;
reportedId: number;
content: string;
}

const postCommentReportAPI = async (params: POSTCommentReportRequest) => {
const { data } = await client({
method: 'post',
url: '/reports/comments',
data: params,
});

return data;
};

export interface POSTBookmarkReportMutation {
reporterId: number;
}

export const usePOSTReportCommentQuery = () => {
const toast = useToast();
const router = useNavigate();
return useMutation(postCommentReportAPI, {
onSuccess: () => {
toast.fireToast({
message: '신고 되었습니다',
mode: 'SUCCESS',
});
router(-1);
},
onError: (e: AxiosError) => {
const errorCode = e.response?.status;
if (errorCode && errorCode === 409) {
toast.fireToast({
message: '이미 신고한 북마크에요',
mode: 'DELETE',
});
router(-1);
}
},
});
};
7 changes: 6 additions & 1 deletion src/common-ui/Error/ApiErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ import { AxiosError } from 'axios';
import NetworkError from './NetworkError';
import { PostBridgeParams } from '@/common/service/hooks/useWebview';

type ErrorType = 'NO_USER_INFO' | 'PRIVATE_BOOKMARK' | 'DUPLICATED_NICKNAME';
type ErrorType =
| 'NO_USER_INFO'
| 'PRIVATE_BOOKMARK'
| 'DUPLICATED_NICKNAME'
| 'DUPLICATE_REPORT';

export const ErrorTypes: Record<ErrorType, string> = {
NO_USER_INFO: 'M001',
DUPLICATED_NICKNAME: 'M002',
PRIVATE_BOOKMARK: 'B002',
DUPLICATE_REPORT: 'R002',
} as const;

interface CustomData {
Expand Down
1 change: 1 addition & 0 deletions src/constants/navigatePath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const navigatePath = {
CATEGORY_LIST: '/category/list',
COMMENT_REPORT: '/comment/:id/report',
BOOKMARK_REPORT: '/bookmark/:id/report',
MEMBER_REPORT: '/member/:id/report',
COMMENT: '/comment',
LIKE_PAGE: '/likes',
INTRODUCE: '/introduce',
Expand Down
12 changes: 11 additions & 1 deletion src/pages/FriendBookmarkPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import BookmarkUserInfo from '@/bookmarks/ui/BookmarkUserInfo';
import useCategory from '@/bookmarks/service/hooks/home/useCategory';
import useReadList from '@/bookmarks/service/hooks/home/useReadList';
import getRem from '@/utils/getRem';
import { useParams } from 'react-router-dom';
import { useNavigate, useParams } from 'react-router-dom';
import Header from '@/common-ui/Header/Header';
import TriggerBottomSheet from '@/common-ui/BottomSheet/TriggerBottomSheet';
import IconButton from '@/common/ui/IconButton';
Expand All @@ -25,6 +25,7 @@ import useBookmarkStore from '@/store/bookmark';
import SkeletonBookmarkUserInfo from '@/bookmarks/ui/SkeletonBookmarkUserInfo';
import PullToRefresh from '@/common-ui/PullToRefresh';
import useHandleRefresh from '@/common/service/hooks/useHandleRefresh';
import { navigatePath } from '@/constants/navigatePath';

const FriendBookmarkPage = () => {
// FIRST RENDER
Expand All @@ -48,6 +49,12 @@ const FriendBookmarkPage = () => {

// USER INTERACTION
// 뒤로가기
// 1. 상단 more > 신고하기
const navigate = useNavigate();
const onClick_신고하기 = () => {
navigate(navigatePath.MEMBER_REPORT.replace(':id', String(friendId)));
};

// 1. 상단 more > 차단하기
const { mutate: postBlockMember } = usePOSTBlockMemberQuery({ memberId });
const onClick_차단하기 = () => {
Expand Down Expand Up @@ -82,6 +89,9 @@ const FriendBookmarkPage = () => {
as={<IconButton onClick={() => {}} name="more" size="s" />}
/>
<TriggerBottomSheet.BottomSheet>
<TriggerBottomSheet.Item onClick={onClick_신고하기}>
신고하기
</TriggerBottomSheet.Item>
{!!profileInfo?.isBlocked && (
<TriggerBottomSheet.Item onClick={onClick_차단해제}>
차단해제
Expand Down
30 changes: 11 additions & 19 deletions src/pages/ReportPage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { usePOSTBookmarkReportMutation } from '@/bookmarks/api/bookmark';
import BookmarkReportList from '@/bookmarks/ui/Report/BookmarkReportList';
import BookmarkReportWrite from '@/bookmarks/ui/Report/BookmarkReportWrite';
import { usePOSTReportCommentQuery } from '@/comment/api/Comment';
import BottomFixedButton from '@/common-ui/BottomFixedButton';
import Header from '@/common-ui/Header/Header';
import Text from '@/common-ui/Text';
import { REPORT_TYPE, usePostReportMutation } from '@/report/api/report';
import useAuthStore from '@/store/auth';
import getRem from '@/utils/getRem';
import styled from '@emotion/styled';
Expand All @@ -14,7 +13,7 @@ import { useParams } from 'react-router-dom';
export type ReportMode = 'CHECK' | 'WRITE';

interface ReportPageProps {
mode: 'BOOKMARK' | 'COMMENT';
mode: REPORT_TYPE;
}

const ReportPage = ({ mode }: ReportPageProps) => {
Expand All @@ -29,27 +28,20 @@ const ReportPage = ({ mode }: ReportPageProps) => {
};

// TODO : 신고하기 버튼 클릭 시 신고 API 호출
const { mutate: reportBookmark } = usePOSTBookmarkReportMutation({
const { mutate: reportBookmark } = usePostReportMutation({
reporterId: memberId,
reportType: mode,
});
const { mutate: reportComment } = usePOSTReportCommentQuery();

const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const content = reportMode === 'WRITE' ? reportText : selectedReport;
if (mode === 'BOOKMARK') {
reportBookmark({
reportedId: Number(id),
reporterId: memberId,
content,
});
}
if (mode === 'COMMENT') {
reportComment({
reportedId: Number(id),
reporterId: memberId,
content,
});
}
reportBookmark({
reportedId: Number(id),
reporterId: memberId,
content,
reportType: mode,
});
};

const buttonDisabled =
Expand Down
130 changes: 130 additions & 0 deletions src/report/api/report.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { GET_BOOKMARK_LIST } from '@/bookmarks/api/bookmark';
import {
CustomAxiosError,
ErrorTypes,
} from '@/common-ui/Error/ApiErrorBoundary';
import useToast from '@/common-ui/Toast/hooks/useToast';
import client from '@/common/service/client';
import {
QueryClient,
useMutation,
useQueryClient,
} from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';

export type REPORT_TYPE = 'BOOKMARK' | 'COMMENT' | 'MEMBER';

// 북마크 신고
interface POSTBookmarkReportRequest {
reporterId: number;
reportedId: number;
content: string;
reportType: REPORT_TYPE;
}

const postReportAPI = async (postData: POSTBookmarkReportRequest) => {
const { data } = await client({
method: 'post',
url: '/reports',
data: postData,
});

return data;
};

export interface POSTBookmarkReportMutation {
reporterId: number;
reportType: REPORT_TYPE;
}

export const usePostReportMutation = ({
reporterId,
reportType,
}: POSTBookmarkReportMutation) => {
const queryClient = useQueryClient();
const { fireToast } = useToast();
const router = useNavigate();
return useMutation(
postReportAPI,
refetchReportQuery(reporterId, reportType, queryClient, fireToast, router),
);
};

const refetchReportQuery = (
reporterId: number,
reportType: REPORT_TYPE,
queryClient: QueryClient,
fireToast: ReturnType<typeof useToast>['fireToast'],
router: ReturnType<typeof useNavigate>,
) => {
if (reportType === 'BOOKMARK') {
return {
onSuccess: () => {
// NOTE : 추후 어드민 페이지 개발 후 사용될 REFETCH 기능
queryClient.invalidateQueries(
GET_BOOKMARK_LIST(reporterId, '📖 전체', 0),
);
queryClient.invalidateQueries(
GET_BOOKMARK_LIST(reporterId, '👀 읽음', 0),
);
queryClient.invalidateQueries(
GET_BOOKMARK_LIST(reporterId, '🫣 읽지 않음', 0),
);
fireToast({
message: '신고 되었습니다',
mode: 'SUCCESS',
});
router(-1);
},
onError: (e: CustomAxiosError) => {
if (e.response?.data.code === ErrorTypes.PRIVATE_BOOKMARK) {
fireToast({
message: '이미 신고한 북마크에요',
mode: 'DELETE',
});
}
router(-1);
},
};
} else if (reportType === 'COMMENT') {
return {
onSuccess: () => {
fireToast({
message: '신고 되었습니다',
mode: 'SUCCESS',
});
router(-1);
},
onError: (e: CustomAxiosError) => {
if (e.response?.data.code === ErrorTypes.PRIVATE_BOOKMARK) {
fireToast({
message: '이미 신고한 댓글이에요',
mode: 'DELETE',
});
router(-1);
}
},
};
} else if (reportType === 'MEMBER') {
return {
onSuccess: () => {
fireToast({
message: '신고 되었습니다',
mode: 'SUCCESS',
});
router(-1);
},
onError: (e: CustomAxiosError) => {
if (e.response?.data.code === ErrorTypes.PRIVATE_BOOKMARK) {
fireToast({
message: '이미 신고한 북마크에요',
mode: 'DELETE',
});
router(-1);
}
},
};
} else {
throw new Error('reportType이 잘못되었습니다');
}
};
Loading
Loading