diff --git a/src/constants/queryKey.ts b/src/constants/queryKey.ts index dcd32f76..63b5a959 100644 --- a/src/constants/queryKey.ts +++ b/src/constants/queryKey.ts @@ -3,4 +3,12 @@ export const QUERYKEY = { TECH_STACKS: "techStacks", ALL_PROJECTS: "allProjects", BANNER_PROJECTS: "bannerProjects", + PROJECT_DETAIL: "projectDetail", + DELETE_PROJECT: "deleteProject", + + POST_LIKE: "postLike", + DELETE_LIKE: "deleteLike", + POST_COMMENT: "postComment", + EDIT_COMMENT: "editComment", + DELETE_COMMENT: "deleteComment", } diff --git a/src/mocks/index.ts b/src/mocks/index.ts index 39c58d61..b841410b 100644 --- a/src/mocks/index.ts +++ b/src/mocks/index.ts @@ -1,4 +1,4 @@ export const initMsw = async () => { - const { worker } = await import("./browser") - worker.start() + // const { worker } = await import("./browser") + // worker.start() } diff --git a/src/pages/ProjectDetailPage/ProjectDetailPage.tsx b/src/pages/ProjectDetailPage/ProjectDetailPage.tsx index cea198cc..b6dfec1c 100644 --- a/src/pages/ProjectDetailPage/ProjectDetailPage.tsx +++ b/src/pages/ProjectDetailPage/ProjectDetailPage.tsx @@ -3,9 +3,8 @@ import { Box, Flex, useMediaQuery } from "@chakra-ui/react" import FullScreenSpinner from "@components/LoadingComponents/FullScreenSpinner" import Comments from "./components/Comments/Comments" -import { withProjectId } from "./components/Comments/Hoc/withProjectId" -import { ProjectIdProps } from "./components/Comments/Hoc/withProjectId" import Content from "./components/Content/Content" +import { ProjectIdProps, withProjectId } from "./components/Hoc/withProjectId" import Summary from "./components/Summary/Summary" import { useProjectDetailQuery } from "./hooks/queries/useProjectDetailQuery" diff --git a/src/pages/ProjectDetailPage/components/Comments/CommentsForm/CommentsForm.tsx b/src/pages/ProjectDetailPage/components/Comments/CommentsForm/CommentsForm.tsx index 69dea9ea..c3c00644 100644 --- a/src/pages/ProjectDetailPage/components/Comments/CommentsForm/CommentsForm.tsx +++ b/src/pages/ProjectDetailPage/components/Comments/CommentsForm/CommentsForm.tsx @@ -1,4 +1,3 @@ -// TODO: 익명 처리 import { useCallback, useState } from "react" import { SubmitHandler, useForm } from "react-hook-form" import ResizeTextarea from "react-textarea-autosize" @@ -17,7 +16,7 @@ import { useUserInfoData } from "@services/caches/useUserInfoData" import { usePostCommentMutation } from "@pages/ProjectDetailPage/hooks/mutations/usePostCommentMutation" import { CommentFormValues } from "../../../types/commentFormValues" -import { ProjectIdProps, withProjectId } from "../Hoc/withProjectId" +import { ProjectIdProps, withProjectId } from "../../Hoc/withProjectId" interface CommentsFormProps extends ProjectIdProps { parentId?: number | null @@ -99,6 +98,7 @@ const CommentsForm = ({ isChecked={isAnonymous} size="lg" onChange={handleAnonymous} + color={isAnonymous ? "red.200" : "grey.500"} colorScheme="red"> 익명 diff --git a/src/pages/ProjectDetailPage/components/Comments/CommentsItem/CommentsItem.tsx b/src/pages/ProjectDetailPage/components/Comments/CommentsItem/CommentsItem.tsx index ca5e9575..ad40b653 100644 --- a/src/pages/ProjectDetailPage/components/Comments/CommentsItem/CommentsItem.tsx +++ b/src/pages/ProjectDetailPage/components/Comments/CommentsItem/CommentsItem.tsx @@ -1,4 +1,3 @@ -// TODO: 1. 포커스 자동 조정(register edit name 사용) import { UseFormRegisterReturn } from "react-hook-form" import { useNavigate } from "react-router-dom" diff --git a/src/pages/ProjectDetailPage/components/Comments/Hoc/withProjectId.tsx b/src/pages/ProjectDetailPage/components/Comments/Hoc/withProjectId.tsx deleted file mode 100644 index 46ad3764..00000000 --- a/src/pages/ProjectDetailPage/components/Comments/Hoc/withProjectId.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentType } from "react" -import { useParams } from "react-router-dom" - -export interface ProjectIdProps { - projectId: string -} - -export const withProjectId =

( - WrappedComponent: ComponentType

, -) => { - const ComponentWithProjectId = (props: Omit) => { - const { projectId } = useParams() - - if (!projectId) { - return null - } - return ( - - ) - } - return ComponentWithProjectId -} diff --git a/src/pages/ProjectDetailPage/components/Summary/SummaryContent/SummaryRight.tsx b/src/pages/ProjectDetailPage/components/Summary/SummaryContent/SummaryRight.tsx index 9baa788e..dbed7393 100644 --- a/src/pages/ProjectDetailPage/components/Summary/SummaryContent/SummaryRight.tsx +++ b/src/pages/ProjectDetailPage/components/Summary/SummaryContent/SummaryRight.tsx @@ -33,9 +33,9 @@ const SummaryRight = ({ overviewImageUrl }: SummaryRightProps) => { return ( - {overviewImageUrl.length > 0 ? ( + {overviewImageUrl.length > 1 ? ( (swiperRef.current = swiper)}> @@ -56,8 +56,7 @@ const SummaryRight = ({ overviewImageUrl }: SummaryRightProps) => { fallbackSrc={noImage} /> )} - - {isLargerThan1200 && overviewImageUrl.length > 0 && ( + {isLargerThan1200 && overviewImageUrl.length > 1 && ( <> void + projectId: string +} + +const ProjectDeleteCheckModal = ({ + isOpen, + onClose, + projectId, +}: ProjectDeleteCheckModalProps) => { + const { deleteProjectMutation } = useDeleteProjectMutation() + + const handleDeleteProject = () => { + onClose() + deleteProjectMutation(Number(projectId)) + } + + return ( + + + + 정말로 삭제하시겠습니까? + + 삭제된 게시물은 복구할 수 없습니다! + + + + + + + ) +} + +export default ProjectDeleteCheckModal diff --git a/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryControl.tsx b/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryControl.tsx new file mode 100644 index 00000000..3f486072 --- /dev/null +++ b/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryControl.tsx @@ -0,0 +1,70 @@ +import { CiMenuKebab } from "react-icons/ci" +import { useNavigate } from "react-router-dom" + +import { + Button, + IconButton, + Popover, + PopoverArrow, + PopoverBody, + PopoverContent, + PopoverTrigger, + VStack, +} from "@chakra-ui/react" + +interface SummaryControlProps { + onOpen: () => void +} + +const SummaryControl = ({ onOpen }: SummaryControlProps) => { + const navigate = useNavigate() + + const handleEditProject = () => { + navigate("/project/edit") + } + + return ( + + + } + aria-label="control" + fontSize="3rem" + /> + + + + + + + + + + + + ) +} + +export default SummaryControl diff --git a/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryControlButton.tsx b/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryControlButton.tsx new file mode 100644 index 00000000..0a386a86 --- /dev/null +++ b/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryControlButton.tsx @@ -0,0 +1,3 @@ +const SummaryControlButton = () => {} + +export default SummaryControlButton diff --git a/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryTop.tsx b/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryTop.tsx index 388fd4ac..192c9a9e 100644 --- a/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryTop.tsx +++ b/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryTop.tsx @@ -1,22 +1,24 @@ import { FaRegComment } from "react-icons/fa" import { IoMdHeart, IoMdHeartEmpty } from "react-icons/io" import { MdRemoveRedEye } from "react-icons/md" -import { PiClipboardText } from "react-icons/pi" -import { useLocation } from "react-router-dom" import { Link } from "react-scroll" -import { Flex, useMediaQuery } from "@chakra-ui/react" +import { Stack, VStack, useDisclosure, useMediaQuery } from "@chakra-ui/react" +import { useUserInfoData } from "@services/caches/useUserInfoData" import { useDeleteLikeMutation } from "@pages/ProjectDetailPage/hooks/mutations/useDeleteLikeMutation" import { usePostLikeMutation } from "@pages/ProjectDetailPage/hooks/mutations/usePostLikeMutation" import { ProjectIdProps, withProjectId } from "../../Hoc/withProjectId" +import ProjectDeleteCheckModal from "./ProjectDeleteCheckModal" +import SummaryControl from "./SummaryControl" import SummaryTopIcon from "./SummaryTopIcon" interface SummaryTopProps extends ProjectIdProps { likeCount: number viewCount: number commentCount: number + ownerId: number likeId: number | null } const SummaryTop = ({ @@ -24,69 +26,72 @@ const SummaryTop = ({ viewCount, commentCount, likeId, + ownerId, projectId, }: SummaryTopProps) => { const [isLargerThan1200] = useMediaQuery(["(min-width: 1200px)"]) - const location = useLocation() - const { VITE_BASE_URL } = import.meta.env - - const handleCopyClipBoard = async (text: string) => { - try { - await navigator.clipboard.writeText(text) - } catch (err) { - console.log(err) - } - } + const [isLargerThan768] = useMediaQuery(["(min-width: 768px)"]) const { postLikeMutation } = usePostLikeMutation() const { deleteLikeMutation } = useDeleteLikeMutation(Number(projectId)) + const { isOpen, onOpen, onClose } = useDisclosure() + const user = useUserInfoData() + return ( - - } - fontSize={isLargerThan1200 ? "2.7rem" : "2rem"} - /> + spacing="1.5rem" + align="flex-end"> + + {isLargerThan768 && ( + } + fontSize={isLargerThan1200 ? "2.7rem" : "2rem"} + /> + )} - : } - fontSize={isLargerThan1200 ? "2.7rem" : "2rem"} - onClick={(likeId: number | null) => { - if (likeId) { - deleteLikeMutation({ likeId }) - } else { - postLikeMutation({ projectId: Number(projectId) }) - } - }} - /> - } - aria-label="commentButton" - fontSize={isLargerThan1200 ? "2.3rem" : "1.8rem"} + count={likeCount} + likeId={likeId} + aria-label="likeButton" + icon={likeId ? : } + fontSize={isLargerThan1200 ? "2.7rem" : "2rem"} + onClick={(likeId: number | null) => { + if (likeId) { + deleteLikeMutation({ likeId }) + } else { + postLikeMutation({ projectId: Number(projectId) }) + } + }} + /> + {isLargerThan768 && ( + + } + aria-label="commentButton" + fontSize={isLargerThan1200 ? "2.3rem" : "1.8rem"} + /> + + )} + + {ownerId === user?.id && } + {isOpen && ( + - - - handleCopyClipBoard(`${VITE_BASE_URL}${location.pathname}`) - } - aria-label="clipboardButton" - fontSize={isLargerThan1200 ? "2.7rem" : "2rem"} - icon={} - /> - + )} + ) } export default withProjectId(SummaryTop) diff --git a/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryTopIcon.tsx b/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryTopIcon.tsx index 71383a9d..5ff3d3b0 100644 --- a/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryTopIcon.tsx +++ b/src/pages/ProjectDetailPage/components/Summary/SummaryTop/SummaryTopIcon.tsx @@ -33,12 +33,19 @@ const SummaryTopIcon = ({ return ( - {isLike ? : } + {isLike ? ( + + ) : ( + + )} {count} ) diff --git a/src/pages/ProjectDetailPage/constants/toastMessage.ts b/src/pages/ProjectDetailPage/constants/toastMessage.ts index 4e294628..fe2fc250 100644 --- a/src/pages/ProjectDetailPage/constants/toastMessage.ts +++ b/src/pages/ProjectDetailPage/constants/toastMessage.ts @@ -4,7 +4,7 @@ export const COMMON_MESSAGES = { export const GET_PROJECT_MESSAGES = { ERROR: { - FAIL: "프로젝트 정보를 불러 오는데 실패했습니다", // 404 + BAD_REQUEST: "프로젝트 정보를 불러 오는데 실패했습니다", UNCAUGHT: "일시적인 오류가 발생하였습니다.", }, } @@ -16,17 +16,25 @@ export const COMMENT_MESSAGES = { EDIT: "댓글이 수정되었습니다", }, ERROR: { - UNVALIDATE: "요청 정보가 유효하지 않습니다.", // 400 - UNAUTHORIZED: "해당 요청에 대한 권한이 없습니다.", // 403 - UNDEFINED: "존재하지 않는 댓글입니다.", // 404 + BAD_REQUEST: "요청 정보가 유효하지 않습니다.", + UNAUTHORIZED: "해당 요청에 대한 권한이 없습니다.", + NOT_FOUND: "존재하지 않는 댓글입니다.", UNCAUGHT: "일시적인 오류가 발생하였습니다.", }, } export const LIKE_MESSAGES = { ERROR: { - UNVALIDATE: "좋아요 요청에 실패했습니다.", // 400, 404 - DUPLICATE: "이미 좋아요를 눌렀습니다.", // 409 + BAD_REQUEST: "좋아요 요청에 실패했습니다.", + CONFLICT: "이미 좋아요를 눌렀습니다.", + UNCAUGHT: "일시적인 오류가 발생하였습니다.", + }, +} + +export const PROJECT__CONTROL_MESSAGES = { + ERROR: { + FORBIDDEN: "삭제 요청에 실패했습니다.", + NOT_FOUND: "해당 요청에 대한 권한이 없습니다.", UNCAUGHT: "일시적인 오류가 발생하였습니다.", }, } diff --git a/src/pages/ProjectDetailPage/hooks/mutations/useDeleteCommentMutation.ts b/src/pages/ProjectDetailPage/hooks/mutations/useDeleteCommentMutation.ts index 0cdb8103..d14ab82e 100644 --- a/src/pages/ProjectDetailPage/hooks/mutations/useDeleteCommentMutation.ts +++ b/src/pages/ProjectDetailPage/hooks/mutations/useDeleteCommentMutation.ts @@ -13,20 +13,18 @@ import { } from "@pages/ProjectDetailPage/constants/toastMessage" import { toastOptions } from "@pages/SignUpPage/constants/toastOptions" -import { QUERY_KEY_GET_PROJECT_DETAIL } from "../queries/useProjectDetailQuery" - -const QUERY_KEY_DELETE_COMMENT = "DELETE_COMMENT_234893204832" +import { QUERYKEY } from "@constants/queryKey" export const useDeleteCommentMutation = () => { const queryClient = useQueryClient() const toast = useToast(toastOptions) const { mutate: deleteCommentMutation, error } = useMutation({ - mutationKey: [QUERY_KEY_DELETE_COMMENT], + mutationKey: [QUERYKEY.DELETE_COMMENT], mutationFn: (commentId: number) => deleteComment({ commentId }), onSuccess: () => { queryClient.invalidateQueries({ - queryKey: [QUERY_KEY_GET_PROJECT_DETAIL], + queryKey: [QUERYKEY.PROJECT_DETAIL], }) }, }) @@ -40,7 +38,7 @@ export const useDeleteCommentMutation = () => { break } case 400: { - message = COMMENT_MESSAGES.ERROR.UNVALIDATE + message = COMMENT_MESSAGES.ERROR.BAD_REQUEST break } case 403: { @@ -48,7 +46,7 @@ export const useDeleteCommentMutation = () => { break } case 404: { - message = COMMENT_MESSAGES.ERROR.UNDEFINED + message = COMMENT_MESSAGES.ERROR.NOT_FOUND break } default: { diff --git a/src/pages/ProjectDetailPage/hooks/mutations/useDeleteLikeMutation.ts b/src/pages/ProjectDetailPage/hooks/mutations/useDeleteLikeMutation.ts index 3ddc14ad..fd43c2d7 100644 --- a/src/pages/ProjectDetailPage/hooks/mutations/useDeleteLikeMutation.ts +++ b/src/pages/ProjectDetailPage/hooks/mutations/useDeleteLikeMutation.ts @@ -15,23 +15,21 @@ import { } from "@pages/ProjectDetailPage/constants/toastMessage" import { toastOptions } from "@pages/SignUpPage/constants/toastOptions" -import { QUERY_KEY_GET_PROJECT_DETAIL } from "../queries/useProjectDetailQuery" - -const QUERY_KEY_POST_LIKE = "DELETE_LIKE_1328940382182" +import { QUERYKEY } from "@constants/queryKey" export const useDeleteLikeMutation = (projectId: number) => { const queryClient = useQueryClient() const toast = useToast(toastOptions) const { mutate: deleteLikeMutation, error } = useMutation({ - mutationKey: [QUERY_KEY_POST_LIKE], + mutationKey: [QUERYKEY.DELETE_LIKE], mutationFn: (data: deleteLikePayload) => deleteLike(data), onMutate: async () => { await queryClient.cancelQueries({ - queryKey: [QUERY_KEY_GET_PROJECT_DETAIL, projectId], + queryKey: [QUERYKEY.PROJECT_DETAIL, projectId], }) const previousLikeState = queryClient.getQueryData([ - QUERY_KEY_GET_PROJECT_DETAIL, + QUERYKEY.PROJECT_DETAIL, projectId, ]) @@ -42,7 +40,7 @@ export const useDeleteLikeMutation = (projectId: number) => { likeCount: previousLikeState.likeCount - 1, } queryClient.setQueryData( - [QUERY_KEY_GET_PROJECT_DETAIL, projectId], + [QUERYKEY.PROJECT_DETAIL, projectId], updatedLikeState, ) } @@ -50,16 +48,15 @@ export const useDeleteLikeMutation = (projectId: number) => { return { previousLikeState } }, - onError: (err, _, context) => { - console.log(err) + onError: (_, __, context) => { queryClient.setQueryData( - [QUERY_KEY_GET_PROJECT_DETAIL, projectId], + [QUERYKEY.PROJECT_DETAIL, projectId], context?.previousLikeState, ) }, onSettled: () => { queryClient.invalidateQueries({ - queryKey: [QUERY_KEY_GET_PROJECT_DETAIL, projectId], + queryKey: [QUERYKEY.PROJECT_DETAIL, projectId], }) }, }) @@ -74,7 +71,7 @@ export const useDeleteLikeMutation = (projectId: number) => { } case 400: case 404: { - message = LIKE_MESSAGES.ERROR.UNVALIDATE + message = LIKE_MESSAGES.ERROR.BAD_REQUEST break } default: { diff --git a/src/pages/ProjectDetailPage/hooks/mutations/useDeleteProjectMutation.ts b/src/pages/ProjectDetailPage/hooks/mutations/useDeleteProjectMutation.ts new file mode 100644 index 00000000..d8cd83d0 --- /dev/null +++ b/src/pages/ProjectDetailPage/hooks/mutations/useDeleteProjectMutation.ts @@ -0,0 +1,63 @@ +import { useEffect } from "react" +import { useNavigate } from "react-router-dom" + +import { useToast } from "@chakra-ui/react" +import { isAxiosError } from "axios" + +import { useMutation, useQueryClient } from "@tanstack/react-query" + +import { deleteProject } from "@apis/project/deleteProject" + +import { + COMMON_MESSAGES, + PROJECT__CONTROL_MESSAGES, +} from "@pages/ProjectDetailPage/constants/toastMessage" + +import { QUERYKEY } from "../../../../constants/queryKey" + +export const useDeleteProjectMutation = () => { + const navigate = useNavigate() + const toast = useToast() + const queryClient = useQueryClient() + + const { mutate: deleteProjectMutation, error } = useMutation({ + mutationKey: [QUERYKEY.DELETE_PROJECT], + mutationFn: (projectId: number) => deleteProject({ projectId }), + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: [QUERYKEY.ALL_PROJECTS], + }) + + navigate(-1) + }, + }) + + useEffect(() => { + if (isAxiosError(error)) { + let message = "" + switch (error.response?.status) { + case 500: { + message = COMMON_MESSAGES.SERVER + break + } + case 403: { + message = PROJECT__CONTROL_MESSAGES.ERROR.FORBIDDEN + break + } + case 404: { + message = PROJECT__CONTROL_MESSAGES.ERROR.NOT_FOUND + break + } + default: { + message = PROJECT__CONTROL_MESSAGES.ERROR.UNCAUGHT + } + } + toast({ + status: "error", + title: message, + }) + } + }, [error, toast]) + + return { deleteProjectMutation } +} diff --git a/src/pages/ProjectDetailPage/hooks/mutations/useEditCommentMutation.ts b/src/pages/ProjectDetailPage/hooks/mutations/useEditCommentMutation.ts index 45826e09..2601e492 100644 --- a/src/pages/ProjectDetailPage/hooks/mutations/useEditCommentMutation.ts +++ b/src/pages/ProjectDetailPage/hooks/mutations/useEditCommentMutation.ts @@ -14,20 +14,18 @@ import { } from "@pages/ProjectDetailPage/constants/toastMessage" import { toastOptions } from "@pages/SignUpPage/constants/toastOptions" -import { QUERY_KEY_GET_PROJECT_DETAIL } from "../queries/useProjectDetailQuery" - -const QUERY_KEY_EDIT_COMMENT = "EDIT_COMMENT_234893204832" +import { QUERYKEY } from "@constants/queryKey" export const useEditCommentMutation = () => { const queryClient = useQueryClient() const toast = useToast(toastOptions) const { mutate: editCommentMutation, error } = useMutation({ - mutationKey: [QUERY_KEY_EDIT_COMMENT], + mutationKey: [QUERYKEY.EDIT_COMMENT], mutationFn: (data: editCommentPayload) => editComment(data), onSuccess: () => { queryClient.invalidateQueries({ - queryKey: [QUERY_KEY_GET_PROJECT_DETAIL], + queryKey: [QUERYKEY.PROJECT_DETAIL], }) }, }) @@ -41,7 +39,7 @@ export const useEditCommentMutation = () => { break } case 400: { - message = COMMENT_MESSAGES.ERROR.UNVALIDATE + message = COMMENT_MESSAGES.ERROR.BAD_REQUEST break } case 403: { @@ -49,7 +47,7 @@ export const useEditCommentMutation = () => { break } case 404: { - message = COMMENT_MESSAGES.ERROR.UNDEFINED + message = COMMENT_MESSAGES.ERROR.NOT_FOUND break } default: { diff --git a/src/pages/ProjectDetailPage/hooks/mutations/usePostCommentMutation.ts b/src/pages/ProjectDetailPage/hooks/mutations/usePostCommentMutation.ts index ab224e51..435b87eb 100644 --- a/src/pages/ProjectDetailPage/hooks/mutations/usePostCommentMutation.ts +++ b/src/pages/ProjectDetailPage/hooks/mutations/usePostCommentMutation.ts @@ -14,20 +14,18 @@ import { } from "@pages/ProjectDetailPage/constants/toastMessage" import { toastOptions } from "@pages/SignUpPage/constants/toastOptions" -import { QUERY_KEY_GET_PROJECT_DETAIL } from "../queries/useProjectDetailQuery" - -const QUERY_KEY_POST_COMMENT = "POST_COMMENT_2384902384" +import { QUERYKEY } from "@constants/queryKey" export const usePostCommentMutation = () => { const queryClient = useQueryClient() const toast = useToast(toastOptions) const { mutate: sendCommentMutation, error } = useMutation({ - mutationKey: [QUERY_KEY_POST_COMMENT], + mutationKey: [QUERYKEY.POST_COMMENT], mutationFn: (data: postCommentPayload) => postComment(data), onSuccess: (_, { projectId }) => { queryClient.invalidateQueries({ - queryKey: [QUERY_KEY_GET_PROJECT_DETAIL, projectId], + queryKey: [QUERYKEY.PROJECT_DETAIL, projectId], }) toast({ status: "success", @@ -45,7 +43,7 @@ export const usePostCommentMutation = () => { break } case 400: { - message = COMMENT_MESSAGES.ERROR.UNVALIDATE + message = COMMENT_MESSAGES.ERROR.BAD_REQUEST break } case 403: { @@ -53,7 +51,7 @@ export const usePostCommentMutation = () => { break } case 404: { - message = COMMENT_MESSAGES.ERROR.UNDEFINED + message = COMMENT_MESSAGES.ERROR.NOT_FOUND break } default: { diff --git a/src/pages/ProjectDetailPage/hooks/mutations/usePostLikeMutation.ts b/src/pages/ProjectDetailPage/hooks/mutations/usePostLikeMutation.ts index 80a3c393..0f010d27 100644 --- a/src/pages/ProjectDetailPage/hooks/mutations/usePostLikeMutation.ts +++ b/src/pages/ProjectDetailPage/hooks/mutations/usePostLikeMutation.ts @@ -15,24 +15,22 @@ import { } from "@pages/ProjectDetailPage/constants/toastMessage" import { toastOptions } from "@pages/SignUpPage/constants/toastOptions" -import { QUERY_KEY_GET_PROJECT_DETAIL } from "../queries/useProjectDetailQuery" - -const QUERY_KEY_POST_LIKE = "POST_LIKE_234893204832" +import { QUERYKEY } from "@constants/queryKey" export const usePostLikeMutation = () => { const queryClient = useQueryClient() const toast = useToast(toastOptions) const { mutate: postLikeMutation, error } = useMutation({ - mutationKey: [QUERY_KEY_POST_LIKE], + mutationKey: [QUERYKEY.POST_LIKE], mutationFn: (data: postLikePayload) => postLike(data), onMutate: async ({ projectId }) => { await queryClient.cancelQueries({ - queryKey: [QUERY_KEY_GET_PROJECT_DETAIL], + queryKey: [QUERYKEY.PROJECT_DETAIL], }) const previousLikeState = queryClient.getQueryData([ - QUERY_KEY_GET_PROJECT_DETAIL, + QUERYKEY.PROJECT_DETAIL, projectId, ]) @@ -43,7 +41,7 @@ export const usePostLikeMutation = () => { likeCount: previousLikeState.likeCount + 1, } queryClient.setQueryData( - [QUERY_KEY_GET_PROJECT_DETAIL, projectId], + [QUERYKEY.PROJECT_DETAIL, projectId], updatedLikeState, ) } @@ -51,16 +49,15 @@ export const usePostLikeMutation = () => { return { previousLikeState } }, - onError: (err, _, context) => { - console.log(err) + onError: (_, __, context) => { queryClient.setQueryData( - [QUERY_KEY_GET_PROJECT_DETAIL], + [QUERYKEY.PROJECT_DETAIL], context?.previousLikeState, ) }, onSettled: (_, __, { projectId }) => { queryClient.invalidateQueries({ - queryKey: [QUERY_KEY_GET_PROJECT_DETAIL, projectId], + queryKey: [QUERYKEY.PROJECT_DETAIL, projectId], }) }, }) @@ -75,11 +72,11 @@ export const usePostLikeMutation = () => { } case 400: case 404: { - message = LIKE_MESSAGES.ERROR.UNVALIDATE + message = LIKE_MESSAGES.ERROR.BAD_REQUEST break } case 409: { - message = LIKE_MESSAGES.ERROR.DUPLICATE + message = LIKE_MESSAGES.ERROR.CONFLICT break } default: { diff --git a/src/pages/ProjectDetailPage/hooks/queries/useProjectDetailQuery.ts b/src/pages/ProjectDetailPage/hooks/queries/useProjectDetailQuery.ts index 731cfed9..dece4c62 100644 --- a/src/pages/ProjectDetailPage/hooks/queries/useProjectDetailQuery.ts +++ b/src/pages/ProjectDetailPage/hooks/queries/useProjectDetailQuery.ts @@ -13,11 +13,12 @@ import { } from "@pages/ProjectDetailPage/constants/toastMessage" import { toastOptions } from "@pages/SignUpPage/constants/toastOptions" -export const QUERY_KEY_GET_PROJECT_DETAIL = "GET_PROJECT_DETAIL_1389471984712" +import { QUERYKEY } from "@constants/queryKey" + export const useProjectDetailQuery = (projectId: number) => { const toast = useToast(toastOptions) const { data: projectDetailInfo, error } = useQuery({ - queryKey: [QUERY_KEY_GET_PROJECT_DETAIL, projectId], + queryKey: [QUERYKEY.PROJECT_DETAIL, projectId], queryFn: () => getProjectDetail({ projectId }), }) @@ -30,7 +31,7 @@ export const useProjectDetailQuery = (projectId: number) => { break } case 404: { - message = GET_PROJECT_MESSAGES.ERROR.FAIL + message = GET_PROJECT_MESSAGES.ERROR.BAD_REQUEST break } default: { diff --git a/src/pages/ProjectDetailPage/mocks/index.ts b/src/pages/ProjectDetailPage/mocks/index.ts index a7869e09..0e771834 100644 --- a/src/pages/ProjectDetailPage/mocks/index.ts +++ b/src/pages/ProjectDetailPage/mocks/index.ts @@ -6,16 +6,4 @@ export const projectDetailHandlers = [ rest.get("/api/v1/projects/:projectId", (_, res, ctx) => { return res(ctx.status(200), ctx.json(DUMMY_PROJECT_DETAIL)) }), - - // rest.post("/api/v1/projects/:projectId/comments", (req, res, ctx) => { - // DUMMY_PROJECT_DETAIL.projects.comments.push(req.body) - // return res(ctx.status(200)) - // }), - - // rest.delete("/api/v1/projects/:projectId/comments/:id", (req, res, ctx) => { - // const commentIdx = DUMMY_PROJECT_DETAIL.projects.comments.findIndex( - // (comment: Comment) => Number(comment.id) === Number(req.params.id), - // ) - // DUMMY_PROJECT_DETAIL.projects.comments.splice(commentIdx, 1) - // return res(ctx.status(200)) ] diff --git a/src/pages/ProjectDetailPage/store/CommentContext.tsx b/src/pages/ProjectDetailPage/store/CommentContext.tsx index c7339853..90467365 100644 --- a/src/pages/ProjectDetailPage/store/CommentContext.tsx +++ b/src/pages/ProjectDetailPage/store/CommentContext.tsx @@ -18,7 +18,6 @@ const CommentContext = createContext({ handleOffEdit: () => {}, handleDelete: () => {}, onSubmitEdit: () => {}, - // 좀 문제임 register: undefined, handleSubmit: undefined, })