From b8bab3cbb4058828a95e4e08eeac8f109ffb6c15 Mon Sep 17 00:00:00 2001 From: jero_kang <81199414+inyeong-kang@users.noreply.github.com> Date: Thu, 17 Aug 2023 01:21:30 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B3=B8=EB=AC=B8=EA=B8=80=20=EA=B0=9C?= =?UTF-8?q?=ED=96=89=20=EC=A0=81=EC=9A=A9,=20=EB=AA=A8=EB=8B=AC=20?= =?UTF-8?q?=EC=99=B8=EB=B6=80=20=EB=88=84=EB=A5=B4=EB=A9=B4=20=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=20=EB=8B=AB=ED=9E=88=EA=B8=B0=20=EC=A0=81=EC=9A=A9,?= =?UTF-8?q?=20=EC=A6=90=EA=B2=A8=EC=B0=BE=EA=B8=B0=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=EC=BD=98=20=EC=88=98=EC=A0=95,=20API=20=ED=86=B5=EC=8B=A0=20?= =?UTF-8?q?=EC=8B=A4=ED=8C=A8=20=EC=8B=9C=20Toast=EC=97=90=20=EB=9D=84?= =?UTF-8?q?=EC=9A=B8=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EA=B0=80=EA=B3=B5=20?= =?UTF-8?q?(#440)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: (#417) 게시글 본문에 공백이 보이도록 css 수정 * fix: (#416) 글 수정 시 image url 가공 없이 전송 * fix: (#418) TwoButtonModal 외부를 누르면 닫히도록 수정 * feat: (#421) 작성자가 투표하는 경우 toast 띄우기 * refactor: (#424) 카테고리 토글 버튼을 별모양 아이콘으로 변경 * fix: (#433) API 통신 실패의 응답, 오류 메시지를 toast에 띄우기 * fix: (#416) 글 수정 시 선택지에서 기존의 이미지 보이도록 수정 * fix: (#416) 글수정 시 imageUrl 앞의 주소 제거 * fix: (#417) API 통신 실패 시 Toast가 무한으로 띄워지는 에러 해결 * fix: (#442) 투표가 된 게시글은 수정 페이지로 라우팅 못하게 early return 하기 * fix: (#417) 이미지 url 값 변경 * fix: (#443) 비회원이 즐겨찾기하는 경우 적절한 에러 메시지 띄우도록 수정 --- frontend/src/assets/star-filled.svg | 3 +++ frontend/src/assets/star-lined.svg | 3 +++ frontend/src/components/PostForm/index.tsx | 6 ++--- .../comment/CommentList/CommentItem/index.tsx | 6 ++++- .../CommentList/CommentTextForm/index.tsx | 2 +- .../common/Dashboard/CategoryToggle/index.tsx | 25 +++++++++++++------ .../common/Dashboard/CategoryToggle/style.ts | 9 +++---- frontend/src/components/common/Post/index.tsx | 5 +++- frontend/src/components/common/Post/style.ts | 1 + .../common/TwoButtonModal/index.tsx | 18 +++++++++++-- .../src/pages/post/CreatePostPage/index.tsx | 6 ++++- .../post/EditPostPage/EditPost/index.tsx | 8 ++++-- .../post/PostDetail/PostDetail/index.tsx | 1 + 13 files changed, 69 insertions(+), 24 deletions(-) create mode 100644 frontend/src/assets/star-filled.svg create mode 100644 frontend/src/assets/star-lined.svg diff --git a/frontend/src/assets/star-filled.svg b/frontend/src/assets/star-filled.svg new file mode 100644 index 000000000..2a9f62fbb --- /dev/null +++ b/frontend/src/assets/star-filled.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/star-lined.svg b/frontend/src/assets/star-lined.svg new file mode 100644 index 000000000..ac8cdaab5 --- /dev/null +++ b/frontend/src/assets/star-lined.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/components/PostForm/index.tsx b/frontend/src/components/PostForm/index.tsx index f058984e0..de2f28475 100644 --- a/frontend/src/components/PostForm/index.tsx +++ b/frontend/src/components/PostForm/index.tsx @@ -22,7 +22,7 @@ import Toast from '@components/common/Toast'; import WritingVoteOptionList from '@components/optionList/WritingVoteOptionList'; import { PATH } from '@constants/path'; -import { CATEGORY_COUNT_LIMIT, POST_CONTENT, POST_TITLE } from '@constants/post'; +import { CATEGORY_COUNT_LIMIT, IMAGE_BASE_URL, POST_CONTENT, POST_TITLE } from '@constants/post'; import { calculateDeadlineTime } from '@utils/post/calculateDeadlineTime'; import { checkWriter } from '@utils/post/checkWriter'; @@ -118,8 +118,8 @@ export default function PostForm({ data, mutate }: PostFormProps) { const formData = new FormData(); const imageUrlList = [ - contentImageHook.contentImage, - ...writingOptionHook.optionList.map(option => option.imageUrl), + contentImageHook.contentImage.replace(IMAGE_BASE_URL, ''), + ...writingOptionHook.optionList.map(option => option.imageUrl.replace(IMAGE_BASE_URL, '')), ]; if (e.target instanceof HTMLFormElement) { diff --git a/frontend/src/components/comment/CommentList/CommentItem/index.tsx b/frontend/src/components/comment/CommentList/CommentItem/index.tsx index ce12c53fe..9263351d3 100644 --- a/frontend/src/components/comment/CommentList/CommentItem/index.tsx +++ b/frontend/src/components/comment/CommentList/CommentItem/index.tsx @@ -77,7 +77,11 @@ export default function CommentItem({ comment, userType }: CommentItemProps) { }; useEffect(() => { - isError && error instanceof Error && openToast(error.message); + if (isError && error instanceof Error) { + const errorResponse = JSON.parse(error.message); + openToast(errorResponse.message); + return; + } }, [isError, error]); const USER_TYPE = COMMENT_USER_MENU[userType]; diff --git a/frontend/src/components/comment/CommentList/CommentTextForm/index.tsx b/frontend/src/components/comment/CommentList/CommentTextForm/index.tsx index 3c74b7373..6d1da5e2a 100644 --- a/frontend/src/components/comment/CommentList/CommentTextForm/index.tsx +++ b/frontend/src/components/comment/CommentList/CommentTextForm/index.tsx @@ -67,7 +67,7 @@ export default function CommentTextForm({ useEffect(() => { isEditError && editError instanceof Error && openToast(editError.message); - }, [isEditError, editError]); + }, [isEditError, editError, openToast]); return ( diff --git a/frontend/src/components/common/Dashboard/CategoryToggle/index.tsx b/frontend/src/components/common/Dashboard/CategoryToggle/index.tsx index 0376fafce..b4037376b 100644 --- a/frontend/src/components/common/Dashboard/CategoryToggle/index.tsx +++ b/frontend/src/components/common/Dashboard/CategoryToggle/index.tsx @@ -1,7 +1,8 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { Category } from '@type/category'; +import { AuthContext } from '@hooks/context/auth'; import { useCategoryFavoriteToggle } from '@hooks/query/category/useCategoryFavoriteToggle'; import { useToast } from '@hooks/useToast'; @@ -9,6 +10,8 @@ import Toast from '@components/common/Toast'; import chevronDown from '@assets/chevron-down.svg'; import chevronUp from '@assets/chevron-up.svg'; +import starFilled from '@assets/star-filled.svg'; +import startLined from '@assets/star-lined.svg'; import * as S from './style'; @@ -27,12 +30,22 @@ export default function CategoryToggle({ const { isToastOpen, openToast, toastMessage } = useToast(); const { mutate, isError, error } = useCategoryFavoriteToggle(); + const { loggedInfo } = useContext(AuthContext); + const handleToggleClick = () => { setIsToggleOpen(prevIsToggleOpen => !prevIsToggleOpen); }; useEffect(() => { - isError && error instanceof Error && openToast(error.message); + if (isError && error instanceof Error) { + if (!loggedInfo.isLoggedIn) { + openToast('즐겨찾기는 로그인 후 이용할 수 있습니다.'); + return; + } + const errorResponse = JSON.parse(error.message); + openToast(errorResponse.message); + return; + } }, [isError, error]); return ( @@ -50,11 +63,9 @@ export default function CategoryToggle({ {categoryList.length === 0 && 현재 카테고리가 없습니다} {categoryList.map(({ id, name, isFavorite }) => ( - mutate({ id, isFavorite })} - $isFavorite={isFavorite} - /> + mutate({ id, isFavorite })}> + + {name} ))} diff --git a/frontend/src/components/common/Dashboard/CategoryToggle/style.ts b/frontend/src/components/common/Dashboard/CategoryToggle/style.ts index f4aac9023..47c785dc5 100644 --- a/frontend/src/components/common/Dashboard/CategoryToggle/style.ts +++ b/frontend/src/components/common/Dashboard/CategoryToggle/style.ts @@ -40,14 +40,11 @@ export const CategoryItem = styled.div` align-items: center; `; -export const Circle = styled.button<{ $isFavorite: boolean }>` - width: 12px; - height: 12px; - border-radius: 50%; +export const Circle = styled.button` + width: 17px; + height: 17px; margin-right: 12px; - background-color: ${({ $isFavorite }) => ($isFavorite ? 'var(--primary-color)' : '#CCCCCC')}; - cursor: pointer; `; diff --git a/frontend/src/components/common/Post/index.tsx b/frontend/src/components/common/Post/index.tsx index e64bb6514..0f44d1691 100644 --- a/frontend/src/components/common/Post/index.tsx +++ b/frontend/src/components/common/Post/index.tsx @@ -59,7 +59,10 @@ export default function Post({ postInfo, isPreview }: PostProps) { return; } - if (writer.nickname === loggedInfo.userInfo?.nickname) return; + if (writer.nickname === loggedInfo.userInfo?.nickname) { + openToast('내가 쓴 글에는 투표를 할 수 없습니다.'); + return; + } if (voteInfo.selectedOptionId === newOptionId) return; diff --git a/frontend/src/components/common/Post/style.ts b/frontend/src/components/common/Post/style.ts index 98802b2d5..df7a5c798 100644 --- a/frontend/src/components/common/Post/style.ts +++ b/frontend/src/components/common/Post/style.ts @@ -100,6 +100,7 @@ export const Content = styled.p<{ $isPreview: boolean }>` font: var(--text-caption); text-overflow: ellipsis; word-break: break-word; + white-space: pre-wrap; overflow: hidden; diff --git a/frontend/src/components/common/TwoButtonModal/index.tsx b/frontend/src/components/common/TwoButtonModal/index.tsx index 45eca2713..96ec3693e 100644 --- a/frontend/src/components/common/TwoButtonModal/index.tsx +++ b/frontend/src/components/common/TwoButtonModal/index.tsx @@ -1,4 +1,4 @@ -import { PropsWithChildren } from 'react'; +import { PropsWithChildren, useEffect, useRef } from 'react'; import SquareButton from '@components/common/SquareButton'; @@ -21,11 +21,25 @@ export default function TwoButtonModal({ secondaryButton, children, }: CommentModalProps) { + const BackDropRef = useRef(null); + const { text: primaryText, handleClick: primaryClick } = primaryButton; const { text: secondaryText, handleClick: secondaryClick } = secondaryButton; + useEffect(() => { + const handler = (e: MouseEvent) => { + if (e.target === BackDropRef.current) { + secondaryClick(); + } + }; + + document.addEventListener('click', handler); + + return () => document.removeEventListener('click', handler); + }, [BackDropRef, secondaryClick]); + return ( - + {title} {children} diff --git a/frontend/src/pages/post/CreatePostPage/index.tsx b/frontend/src/pages/post/CreatePostPage/index.tsx index d031544cc..7f12c4c23 100644 --- a/frontend/src/pages/post/CreatePostPage/index.tsx +++ b/frontend/src/pages/post/CreatePostPage/index.tsx @@ -25,7 +25,11 @@ export default function CreatePostPage() { }, [isSuccess, navigate]); useEffect(() => { - isError && error instanceof Error && openToast(error.message); + if (isError && error instanceof Error) { + const errorResponse = JSON.parse(error.message); + openToast(errorResponse.message); + return; + } }, [isError, error]); return ( diff --git a/frontend/src/pages/post/EditPostPage/EditPost/index.tsx b/frontend/src/pages/post/EditPostPage/EditPost/index.tsx index 27752acf3..1e97bcce3 100644 --- a/frontend/src/pages/post/EditPostPage/EditPost/index.tsx +++ b/frontend/src/pages/post/EditPostPage/EditPost/index.tsx @@ -30,8 +30,12 @@ export default function EditPost() { }, [isSuccess, navigate, postId]); useEffect(() => { - isError && error instanceof Error && openToast(error.message); - }, [isError, error, openToast]); + if (isError && error instanceof Error) { + const errorResponse = JSON.parse(error.message); + openToast(errorResponse.message); + return; + } + }, [isError, error]); return ( <> diff --git a/frontend/src/pages/post/PostDetail/PostDetail/index.tsx b/frontend/src/pages/post/PostDetail/PostDetail/index.tsx index c5de2aee1..13f96bc47 100644 --- a/frontend/src/pages/post/PostDetail/PostDetail/index.tsx +++ b/frontend/src/pages/post/PostDetail/PostDetail/index.tsx @@ -55,6 +55,7 @@ export default function PostDetail() { moveWritePostPage: () => { if (postDataFallback.voteInfo.allPeopleCount) { openToast('투표한 사용자가 있어 글 수정이 불가합니다.'); + return; } navigate(`/posts/write/${postId}`);