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

[BUG] 모바일 비회원일 때 신고 버튼을 눌르면 알 수 없는 에러 메세지입니다라고 떠요 #781

Merged
merged 4 commits into from
Oct 19, 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: 3 additions & 1 deletion frontend/src/components/ReportModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ export default function ReportModal({
const { selectedOption, handleOptionChange } = useSelect<ReportMessage>(defaultReportMessage);

const handlePrimaryButtonClick = () => {
!isReportLoading && handleReportClick(selectedOption);
if (isReportLoading) return;

handleReportClick(selectedOption);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 가독성이 높아졌네요👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로딩이 끝나야만 action을 null로 세팅하도록 해서
말씀하신 이슈를 해결해볼 수 있을거 같아요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 그럼 네트워크가 느린 사용자가 신고를 하고 기다리다가 오래 걸려서 취소를 누르면 나가지지 않게 될 것 같은데 제가 이해한 바가 맞을까요?? 아님 다르게 작동하나요??

handleCancelClick();
};

Expand Down
55 changes: 9 additions & 46 deletions frontend/src/components/comment/CommentList/CommentItem/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useContext, useState } from 'react';
import { useState } from 'react';
import { useParams } from 'react-router-dom';

import { Comment } from '@type/comment';
Expand All @@ -7,10 +7,8 @@ import { ReportMessage, ReportRequest } from '@type/report';

import { useToggle } from '@hooks';

import { ToastContext } from '@hooks/context/toast';
import { useDeleteComment } from '@hooks/query/comment/useDeleteComment';

import { reportContent } from '@api/report';
import { useReportContent } from '@hooks/query/report/useReportContent';

import CommentTextForm from '@components/comment/CommentList/CommentTextForm';
import DeleteModal from '@components/common/DeleteModal';
Expand All @@ -30,18 +28,15 @@ interface CommentItemProps {
}

export default function CommentItem({ comment, userType }: CommentItemProps) {
const [isReportCommentLoading, setIsReportCommentLoading] = useState(false);
const [isReportNicknameLoading, setIsReportNicknameLoading] = useState(false);

const { addMessage } = useContext(ToastContext);
const { isOpen, toggleComponent, closeComponent } = useToggle();
const { id, member, content, createdAt, isEdit } = comment;
const [action, setAction] = useState<CommentAction | null>(null);

const params = useParams() as { postId: string };
const postId = Number(params.postId);

const { mutate, isLoading: isCommentDeleting } = useDeleteComment(postId, id);
const { mutate: deleteComment, isLoading: isCommentDeleting } = useDeleteComment(postId, id);
const { mutate: reportContent, isLoading: isContentReporting } = useReportContent();

const handleMenuClick = (menu: CommentAction) => {
closeComponent();
Expand All @@ -50,52 +45,20 @@ export default function CommentItem({ comment, userType }: CommentItemProps) {

const handleCommentReportClick = async (reason: ReportMessage) => {
const reportData: ReportRequest = { type: 'COMMENT', id, reason };
setIsReportCommentLoading(true);

await reportContent(reportData)
.then(res => {
addMessage('댓글을 신고했습니다.');
})
.catch(e => {
if (e instanceof Error) {
const errorResponse = JSON.parse(e.message);
addMessage(errorResponse.message);
return;
}
addMessage('댓글 신고를 실패했습니다.');
})
.finally(() => {
setIsReportCommentLoading(false);
});
reportContent(reportData);
};

const handleNicknameReportClick = async (reason: ReportMessage) => {
const reportData: ReportRequest = { type: 'NICKNAME', id: member.id, reason };
setIsReportNicknameLoading(true);

await reportContent(reportData)
.then(res => {
addMessage('작성자 닉네임을 신고했습니다.');
})
.catch(e => {
if (e instanceof Error) {
const errorResponse = JSON.parse(e.message);
addMessage(errorResponse.message);
return;
}
addMessage('작성자 닉네임 신고를 실패했습니다.');
})
.finally(() => {
setIsReportNicknameLoading(false);
});
reportContent(reportData);
};

const handleCancelClick = () => {
setAction(null);
};

const handleDeleteClick = () => {
mutate();
deleteComment();
};

const USER_TYPE = COMMENT_USER_MENU[userType];
Expand Down Expand Up @@ -158,15 +121,15 @@ export default function CommentItem({ comment, userType }: CommentItemProps) {
reportType="NICKNAME"
handleReportClick={handleNicknameReportClick}
handleCancelClick={handleCancelClick}
isReportLoading={isReportNicknameLoading}
isReportLoading={isContentReporting}
/>
)}
{action === COMMENT_ACTION.COMMENT_REPORT && (
<ReportModal
reportType="COMMENT"
handleReportClick={handleCommentReportClick}
handleCancelClick={handleCancelClick}
isReportLoading={isReportCommentLoading}
isReportLoading={isContentReporting}
/>
)}
</S.Container>
Expand Down
8 changes: 7 additions & 1 deletion frontend/src/hooks/query/report/useReportAction.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { useContext } from 'react';

import { useMutation, useQueryClient } from '@tanstack/react-query';

import { ReportActionRequest } from '@type/report';

import { ToastContext } from '@hooks/context/toast';

import { reportAction } from '@api/report';

import { QUERY_KEY } from '@constants/queryKey';

export const useReportAction = () => {
const queryClient = useQueryClient();
const { addMessage } = useContext(ToastContext);

const { mutate, isLoading, isSuccess, isError, error } = useMutation({
mutationFn: async (reportActionData: ReportActionRequest) =>
Expand All @@ -16,7 +21,8 @@ export const useReportAction = () => {
queryClient.invalidateQueries({ queryKey: [QUERY_KEY.REPORT] });
},
onError: () => {
window.console.error('신고 조치를 실패했습니다.');
const message = error instanceof Error ? error.message : '신고 조치를 실패했습니다.';
addMessage(message);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

복붙 때문인지 에러메시지 값이 이상해졌는데 복구해주실 수 있나요🤔

},
});

Expand Down
30 changes: 30 additions & 0 deletions frontend/src/hooks/query/report/useReportContent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useContext } from 'react';

import { useMutation, useQueryClient } from '@tanstack/react-query';

import { ReportRequest } from '@type/report';

import { ToastContext } from '@hooks/context/toast';

import { reportContent } from '@api/report';

import { QUERY_KEY } from '@constants/queryKey';

export const useReportContent = () => {
const queryClient = useQueryClient();
const { addMessage } = useContext(ToastContext);

const { mutate, isLoading } = useMutation({
mutationFn: async (reportData: ReportRequest) => await reportContent(reportData),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [QUERY_KEY.REPORT] });
addMessage('신고를 완료하였습니다.');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

신고의 경우에는 성공했을 때 사용자에게 알려주는 것 너무 좋은데여🔥

},
onError: error => {
const message = error instanceof Error ? error.message : '개인정보 등록을 실패했습니다.';
addMessage(message);
},
});

return { mutate, isLoading };
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { LoadingType } from '../types';

import { useContext, useState } from 'react';

import { PostAction } from '@type/menu';
import { ReportMessage } from '@type/report';

import { AuthContext } from '@hooks/context/auth';
Expand Down Expand Up @@ -39,9 +40,9 @@ export default function BottomButtonPart({
const { moveWritePostPage, moveVoteStatisticsPage } = movePage;
const { setEarlyClosePost, deletePost, reportPost, reportNickname } = controlPost;
const { isDeletePostLoading, isReportPostLoading, isReportNicknameLoading } = isEventLoading;
const [action, setAction] = useState<string | null>(null);
const [action, setAction] = useState<PostAction | null>(null);

const handleActionButtonClick = (action: string) => {
const handleActionButtonClick = (action: PostAction) => {
if (!loggedInfo.isLoggedIn) {
openToast('로그인 후에 기능을 이용해주세요.');
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const handleEvent = {
reportPost: (reason: string) => {},
reportNickname: (reason: string) => {},
},
openToast: () => {},
};

export const isWriterAndIsClosedCase: Story = {
Expand Down
24 changes: 15 additions & 9 deletions frontend/src/pages/post/PostDetailPage/InnerHeaderPart/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useState } from 'react';
import { useContext, useState } from 'react';
import { useNavigate } from 'react-router-dom';

import { PostAction, MenuItem } from '@type/menu';
import { ReportMessage } from '@type/report';

import { useToggle } from '@hooks';
import { AuthContext, useToggle } from '@hooks';

import DeleteModal from '@components/common/DeleteModal';
import HeaderTextButton from '@components/common/HeaderTextButton';
Expand Down Expand Up @@ -32,6 +32,7 @@ interface PostDetailPageChildProps {
reportPost: (reason: ReportMessage) => void;
reportNickname: (reason: ReportMessage) => void;
};
openToast: (text: string) => void;
};
isEventLoading: Record<LoadingType, boolean>;
}
Expand All @@ -44,20 +45,25 @@ const menuList: MenuItem<PostAction>[] = [
export default function InnerHeaderPart({
isWriter,
isClosed,
handleEvent: { movePage, controlPost },
handleEvent: { movePage, controlPost, openToast },
isEventLoading,
}: PostDetailPageChildProps) {
const navigate = useNavigate();

const { loggedInfo } = useContext(AuthContext);
const { moveWritePostPage, moveVoteStatisticsPage } = movePage;
const { setEarlyClosePost, deletePost, reportPost, reportNickname } = controlPost;
const { isOpen, toggleComponent, closeComponent } = useToggle();
const [action, setAction] = useState<PostAction | null>(null);

const { isDeletePostLoading, isReportNicknameLoading, isReportPostLoading } = isEventLoading;
const { isOpen: isMenuOpen, toggleComponent, closeComponent } = useToggle();
const [action, setAction] = useState<PostAction | null>(null);

const handleMenuClick = (action: PostAction) => {
closeComponent();

if (!loggedInfo.isLoggedIn) {
openToast('로그인 후에 기능을 이용해주세요.');
return;
}

Comment on lines +62 to +65
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

버그 해결 완료 👍👍👍

setAction(action);
};

Expand All @@ -80,12 +86,12 @@ export default function InnerHeaderPart({
{!isWriter ? (
<>
<HeaderTextButton
aria-label={isOpen ? '게시글 신고 메뉴 닫기' : '게시글 신고 메뉴 열기'}
aria-label={isMenuOpen ? '게시글 신고 메뉴 닫기' : '게시글 신고 메뉴 열기'}
onClick={toggleComponent}
>
신고
</HeaderTextButton>
{isOpen && (
{isMenuOpen && (
<S.MenuWrapper>
<Menu menuList={menuList} handleMenuClick={handleMenuClick} />
</S.MenuWrapper>
Expand Down
48 changes: 10 additions & 38 deletions frontend/src/pages/post/PostDetailPage/PostDetail/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Suspense, useContext, useEffect, useState } from 'react';
import { Suspense, useContext, useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';

import { PostInfo } from '@type/post';
Expand All @@ -7,8 +7,7 @@ import { ReportMessage, ReportRequest } from '@type/report';
import { AuthContext, useDeletePost, useEarlyClosePost, usePostDetail } from '@hooks';

import { ToastContext } from '@hooks/context/toast';

import { reportContent } from '@api/report';
import { useReportContent } from '@hooks/query/report/useReportContent';

import ErrorBoundary from '@pages/ErrorBoundary';

Expand All @@ -30,9 +29,6 @@ import * as S from './style';
export default function PostDetail() {
const navigate = useNavigate();

const [isReportPostLoading, setIsReportPostLoading] = useState(false);
const [isReportNicknameLoading, setIsReportNicknameLoading] = useState(false);

const params = useParams() as { postId: string };
const postId = Number(params.postId);

Expand All @@ -47,6 +43,7 @@ export default function PostDetail() {
isLoading: isDeletePostLoading,
} = useDeletePost(postId, loggedInfo.isLoggedIn);
const { mutate: earlyClosePost } = useEarlyClosePost(postId);
const { mutate: reportContent, isLoading: isContentReporting } = useReportContent();

const postDataFallback = postData ?? ({} as PostInfo);

Expand Down Expand Up @@ -81,41 +78,16 @@ export default function PostDetail() {
deletePost();
},
reportPost: async (reason: ReportMessage) => {
setIsReportPostLoading(true);
const reportData: ReportRequest = { type: 'POST', id: postId, reason };

await reportContent(reportData)
.then(res => {
addMessage('게시물을 신고했습니다.');
})
.catch(error => {
const message = error instanceof Error ? error.message : '게시글 신고를 실패했습니다.';
addMessage(message);
})
.finally(() => {
setIsReportPostLoading(false);
});
reportContent(reportData);
},
reportNickname: async (reason: ReportMessage) => {
setIsReportNicknameLoading(true);
const reportData: ReportRequest = {
type: 'NICKNAME',
id: postDataFallback.writer.id,
reason,
};

await reportContent(reportData)
.then(res => {
addMessage('작성자 닉네임을 신고했습니다.');
})
.catch(error => {
const message =
error instanceof Error ? error.message : '작성자 닉네임 신고를 실패했습니다.';
addMessage(message);
})
.finally(() => {
setIsReportNicknameLoading(false);
});
reportContent(reportData);
},
copyPostURL: () => {
const currentURL = window.location.href;
Expand Down Expand Up @@ -143,11 +115,11 @@ export default function PostDetail() {
<InnerHeaderPart
isClosed={isClosed}
isWriter={isWriter}
handleEvent={{ movePage, controlPost }}
handleEvent={{ movePage, controlPost, openToast: addMessage }}
isEventLoading={{
isDeletePostLoading,
isReportPostLoading,
isReportNicknameLoading,
isReportPostLoading: isContentReporting,
isReportNicknameLoading: isContentReporting,
}}
/>
</NarrowTemplateHeader>
Expand All @@ -165,8 +137,8 @@ export default function PostDetail() {
handleEvent={{ movePage, controlPost, openToast: addMessage }}
isEventLoading={{
isDeletePostLoading,
isReportPostLoading,
isReportNicknameLoading,
isReportPostLoading: isContentReporting,
isReportNicknameLoading: isContentReporting,
}}
/>
</S.MainContainer>
Expand Down
Loading