From e07a30bedd5f5348af362cbe8585fac328a2bf04 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 3 Jan 2024 15:41:05 +0900 Subject: [PATCH 01/17] =?UTF-8?q?feat:=20post=20=EC=83=81=ED=83=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20query=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/post/apis.ts | 13 ++++++++++++- src/apis/post/queries.ts | 21 +++++++++++++++++++-- src/apis/post/types.ts | 4 ++-- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/apis/post/apis.ts b/src/apis/post/apis.ts index 51fa82e8..48734ca9 100644 --- a/src/apis/post/apis.ts +++ b/src/apis/post/apis.ts @@ -4,7 +4,9 @@ import type { CreatePostReq, CreatePostRes, GetPostsReq, - GetPostsRes + GetPostsRes, + UpdateTradeStatusReq, + UpdateTradeStatusRes } from './types' import { http } from '@utils/http' @@ -19,3 +21,12 @@ export const getCategories = () => export const getPosts = (params: GetPostsReq) => http.get('/posts', params) + +export const updateTradeStatus = ( + postId: number, + params: UpdateTradeStatusReq +) => + http.put( + `/posts/trade-status/${postId}`, + params + ) diff --git a/src/apis/post/queries.ts b/src/apis/post/queries.ts index 50f27c9d..6adde67c 100644 --- a/src/apis/post/queries.ts +++ b/src/apis/post/queries.ts @@ -1,6 +1,17 @@ import { useMutation, useQuery, useInfiniteQuery } from '@tanstack/react-query' -import { getPost, getCategories, createPost, getPosts } from './apis' -import type { CreatePostReq, GetPostsReq, GetPostsRes } from './types' +import { + getPost, + getCategories, + createPost, + getPosts, + updateTradeStatus +} from './apis' +import type { + CreatePostReq, + GetPostsReq, + GetPostsRes, + UpdateTradeStatusReq +} from './types' export const useCreatePostMutation = () => useMutation({ @@ -35,3 +46,9 @@ export const useGetInfinitePostsQuery = (params: GetPostsReq) => ? lastPage.posts[lastPage.posts.length - 1].id : undefined }) + +export const useUpdateTradeStatusMutation = (postId: number) => + useMutation({ + mutationFn: (params: UpdateTradeStatusReq) => + updateTradeStatus(postId, params) + }) diff --git a/src/apis/post/types.ts b/src/apis/post/types.ts index 06ba534b..ac12739c 100644 --- a/src/apis/post/types.ts +++ b/src/apis/post/types.ts @@ -5,6 +5,7 @@ import type { PostSummaries, ProductConditionCodes, SortOptionsShape, + TradeStatusCodes, TradeStatusType, TradeTypeCodes } from '@types' @@ -34,8 +35,7 @@ export type DeletePostRes = { // TODO: 정확한 타입 BE 확인 필요 export type UpdateTradeStatusReq = { - postId: number - request: TradeStatusType + tradeStatus: TradeStatusCodes } export type UpdateTradeStatusRes = number From 78d65bbec155fb0c8ed1daafa542687413b42dcc Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 3 Jan 2024 15:41:55 +0900 Subject: [PATCH 02/17] =?UTF-8?q?feat:=20post=20=EC=83=81=ED=83=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20api=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/post/[postId]/index.tsx | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/pages/post/[postId]/index.tsx b/src/pages/post/[postId]/index.tsx index a228b58a..ede8045f 100644 --- a/src/pages/post/[postId]/index.tsx +++ b/src/pages/post/[postId]/index.tsx @@ -3,12 +3,13 @@ import type { SerializedStyles } from '@emotion/react' import styled from '@emotion/styled' import { Carousel, Divider, Text, IconButton, SelectBox } from '@offer-ui/react' import type { GetServerSideProps } from 'next' -import type { ReactElement } from 'react' -import { useGetPostQuery } from '@apis/post' +import { useState, type ReactElement, useEffect } from 'react' import { getTimeDiffText, toLocaleCurrency } from '@utils/format' +import { useGetPostQuery, useUpdateTradeStatusMutation } from '@apis' import { UserProfile, PriceOfferCard, PostFieldList } from '@components' import { TRADE_STATUS } from '@constants' import { useAuth } from '@hooks' +import type { TradeStatusCodes, TradeStatusType } from '@types' type Props = { postId: number } export const getServerSideProps: GetServerSideProps = async ({ @@ -21,7 +22,9 @@ export const getServerSideProps: GetServerSideProps = async ({ const PostDetailPage = ({ postId }: Props): ReactElement => { const postQuery = useGetPostQuery(postId) + const tradeStatusMutation = useUpdateTradeStatusMutation(postId) const { user } = useAuth() + const [tradeStatus, setTradeStatus] = useState() const isSeller = user.id === postQuery.data?.seller.id const postImages = postQuery.data?.imageUrls.map((url, idx) => ({ @@ -29,6 +32,22 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { url })) + const handleChangeTradeStatus = async (status: TradeStatusType) => { + const nextStatusCode = status.code + + setTradeStatus(nextStatusCode) + + await tradeStatusMutation.mutateAsync({ + tradeStatus: nextStatusCode + }) + } + + useEffect(() => { + if (postQuery.data) { + setTradeStatus(postQuery.data.tradeStatus.code) + } + }, [postQuery.data]) + return (
@@ -41,11 +60,10 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { {isSeller ? ( <> { - // do something - }} + value={tradeStatus} + onChange={handleChangeTradeStatus} /> From 53860b910ae4998837d9eb68b1ed2dd20bb3c39b Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 3 Jan 2024 16:38:41 +0900 Subject: [PATCH 03/17] =?UTF-8?q?fix:=20=EC=98=A4=ED=8D=BC=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=20=EB=AC=B4=ED=95=9C=20=EB=A0=8C=EB=8D=94=EB=A7=81=20?= =?UTF-8?q?=EC=9D=B4=EC=8A=88=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/post/PriceOfferCard/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/post/PriceOfferCard/index.tsx b/src/components/post/PriceOfferCard/index.tsx index f7b5c45e..830ce54d 100644 --- a/src/components/post/PriceOfferCard/index.tsx +++ b/src/components/post/PriceOfferCard/index.tsx @@ -43,7 +43,7 @@ const PriceOfferCard = ({ status: Boolean(postQuery.data?.liked), count: postQuery.data?.totalLikeCount || 0 }) - }, [postQuery]) + }, [postQuery.data]) const offers = postOffersQuery.data?.offers.map(({ offerer, createdAt, ...offer }) => ({ From cac38e985bb4cc48d08776612a30025b96982d9b Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 3 Jan 2024 16:40:42 +0900 Subject: [PATCH 04/17] =?UTF-8?q?feat:=20more=20=ED=81=B4=EB=A6=AD?= =?UTF-8?q?=EC=8B=9C=20=EB=8B=A4=EC=9D=B4=EC=95=8C=EB=A1=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20=EC=88=98=EC=A0=95=20=ED=81=B4=EB=A6=AD?= =?UTF-8?q?=EC=8B=9C=20routing=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Dialog/index.tsx | 14 +++--- src/pages/post/[postId]/index.tsx | 66 ++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/components/common/Dialog/index.tsx b/src/components/common/Dialog/index.tsx index 2199312a..25ad6857 100644 --- a/src/components/common/Dialog/index.tsx +++ b/src/components/common/Dialog/index.tsx @@ -3,14 +3,12 @@ import type { DialogProps } from './types' const Dialog = ({ onClose, dialogPositionStyle, children }: DialogProps) => { return ( - <> - - - - {children} - - - + + + + {children} + + ) } diff --git a/src/pages/post/[postId]/index.tsx b/src/pages/post/[postId]/index.tsx index ede8045f..294cee5b 100644 --- a/src/pages/post/[postId]/index.tsx +++ b/src/pages/post/[postId]/index.tsx @@ -3,10 +3,11 @@ import type { SerializedStyles } from '@emotion/react' import styled from '@emotion/styled' import { Carousel, Divider, Text, IconButton, SelectBox } from '@offer-ui/react' import type { GetServerSideProps } from 'next' +import Link from 'next/link' import { useState, type ReactElement, useEffect } from 'react' -import { getTimeDiffText, toLocaleCurrency } from '@utils/format' +import { getTimeDiffText, toLocaleCurrency, toQueryString } from '@utils/format' import { useGetPostQuery, useUpdateTradeStatusMutation } from '@apis' -import { UserProfile, PriceOfferCard, PostFieldList } from '@components' +import { UserProfile, PriceOfferCard, PostFieldList, Dialog } from '@components' import { TRADE_STATUS } from '@constants' import { useAuth } from '@hooks' import type { TradeStatusCodes, TradeStatusType } from '@types' @@ -23,8 +24,9 @@ export const getServerSideProps: GetServerSideProps = async ({ const PostDetailPage = ({ postId }: Props): ReactElement => { const postQuery = useGetPostQuery(postId) const tradeStatusMutation = useUpdateTradeStatusMutation(postId) - const { user } = useAuth() const [tradeStatus, setTradeStatus] = useState() + const [isOpenDialog, setIsOpenDialog] = useState(false) + const { user } = useAuth() const isSeller = user.id === postQuery.data?.seller.id const postImages = postQuery.data?.imageUrls.map((url, idx) => ({ @@ -42,6 +44,14 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { }) } + const handleCloseDialog = () => { + setIsOpenDialog(false) + } + + const handleClickMore = () => { + setIsOpenDialog(true) + } + useEffect(() => { if (postQuery.data) { setTradeStatus(postQuery.data.tradeStatus.code) @@ -65,7 +75,31 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { value={tradeStatus} onChange={handleChangeTradeStatus} /> - + + + {isOpenDialog && ( + + + + 수정하기 + + 삭제하기 + + + )} + ) : ( @@ -184,6 +218,30 @@ const Content = styled.div` `} ` +const MoreButtonWrapper = styled.div` + position: relative; +` + +const DialogButtonContainer = styled.div` + display: flex; + flex-direction: column; + gap: 8px; + + width: 100%; +` + +const DialogButton = styled.button` + width: 100%; + padding: 4px 0; + border: none; + + background-color: transparent; + + text-align: left; + + cursor: pointer; +` + const ProductConditionSelectBox = styled(SelectBox)` margin: 33px 0 16px; From 1c0cc0734095873df14b8323d727223755372468 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 3 Jan 2024 17:12:31 +0900 Subject: [PATCH 05/17] =?UTF-8?q?feat:=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20query=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/post/apis.ts | 7 ++++++- src/apis/post/queries.ts | 9 ++++++++- src/apis/post/types.ts | 4 +--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/apis/post/apis.ts b/src/apis/post/apis.ts index 48734ca9..2b2bfd83 100644 --- a/src/apis/post/apis.ts +++ b/src/apis/post/apis.ts @@ -6,7 +6,9 @@ import type { GetPostsReq, GetPostsRes, UpdateTradeStatusReq, - UpdateTradeStatusRes + UpdateTradeStatusRes, + DeletePostReq, + DeletePostRes } from './types' import { http } from '@utils/http' @@ -30,3 +32,6 @@ export const updateTradeStatus = ( `/posts/trade-status/${postId}`, params ) + +export const deletePost = (postId: DeletePostReq) => + http.delete(`/posts/${postId}`) diff --git a/src/apis/post/queries.ts b/src/apis/post/queries.ts index 6adde67c..7a0c706a 100644 --- a/src/apis/post/queries.ts +++ b/src/apis/post/queries.ts @@ -4,10 +4,12 @@ import { getCategories, createPost, getPosts, - updateTradeStatus + updateTradeStatus, + deletePost } from './apis' import type { CreatePostReq, + DeletePostReq, GetPostsReq, GetPostsRes, UpdateTradeStatusReq @@ -52,3 +54,8 @@ export const useUpdateTradeStatusMutation = (postId: number) => mutationFn: (params: UpdateTradeStatusReq) => updateTradeStatus(postId, params) }) + +export const useDeletePostMutation = (postId: DeletePostReq) => + useMutation({ + mutationFn: () => deletePost(postId) + }) diff --git a/src/apis/post/types.ts b/src/apis/post/types.ts index ac12739c..e91811fa 100644 --- a/src/apis/post/types.ts +++ b/src/apis/post/types.ts @@ -26,9 +26,7 @@ export type UpdatePostReq = { } export type UpdatePostRes = PostDetail -export type DeletePostReq = { - postId: number -} +export type DeletePostReq = number export type DeletePostRes = { // TODO: 정확한 타입 BE 확인 필요 } From 448e3a6c42d049bf5306b32b70204378178c0e37 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 3 Jan 2024 17:16:54 +0900 Subject: [PATCH 06/17] =?UTF-8?q?feat:=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20api=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/post/[postId]/index.tsx | 241 ++++++++++++++++++------------ 1 file changed, 142 insertions(+), 99 deletions(-) diff --git a/src/pages/post/[postId]/index.tsx b/src/pages/post/[postId]/index.tsx index 294cee5b..f278f0b4 100644 --- a/src/pages/post/[postId]/index.tsx +++ b/src/pages/post/[postId]/index.tsx @@ -1,15 +1,33 @@ import { css } from '@emotion/react' import type { SerializedStyles } from '@emotion/react' import styled from '@emotion/styled' -import { Carousel, Divider, Text, IconButton, SelectBox } from '@offer-ui/react' +import { + Carousel, + Divider, + Text, + IconButton, + SelectBox, + Button +} from '@offer-ui/react' import type { GetServerSideProps } from 'next' import Link from 'next/link' -import { useState, type ReactElement, useEffect } from 'react' +import { useRouter } from 'next/router' +import { useState, type ReactElement } from 'react' import { getTimeDiffText, toLocaleCurrency, toQueryString } from '@utils/format' -import { useGetPostQuery, useUpdateTradeStatusMutation } from '@apis' -import { UserProfile, PriceOfferCard, PostFieldList, Dialog } from '@components' +import { + useDeletePostMutation, + useGetPostQuery, + useUpdateTradeStatusMutation +} from '@apis' +import { + UserProfile, + PriceOfferCard, + PostFieldList, + Dialog, + CommonModal +} from '@components' import { TRADE_STATUS } from '@constants' -import { useAuth } from '@hooks' +import { useAuth, useModal } from '@hooks' import type { TradeStatusCodes, TradeStatusType } from '@types' type Props = { postId: number } @@ -22,14 +40,17 @@ export const getServerSideProps: GetServerSideProps = async ({ }) const PostDetailPage = ({ postId }: Props): ReactElement => { - const postQuery = useGetPostQuery(postId) - const tradeStatusMutation = useUpdateTradeStatusMutation(postId) + const getPostQuery = useGetPostQuery(postId) + const updateTradeStatusMutation = useUpdateTradeStatusMutation(postId) + const deletePostMutation = useDeletePostMutation(postId) + const router = useRouter() const [tradeStatus, setTradeStatus] = useState() const [isOpenDialog, setIsOpenDialog] = useState(false) + const { isOpen, openModal, closeModal } = useModal() const { user } = useAuth() - const isSeller = user.id === postQuery.data?.seller.id - const postImages = postQuery.data?.imageUrls.map((url, idx) => ({ + const isSeller = user.id === getPostQuery.data?.seller.id + const postImages = getPostQuery.data?.imageUrls.map((url, idx) => ({ id: idx, url })) @@ -39,11 +60,17 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { setTradeStatus(nextStatusCode) - await tradeStatusMutation.mutateAsync({ + await updateTradeStatusMutation.mutateAsync({ tradeStatus: nextStatusCode }) } + const handleClickDelete = async () => { + await deletePostMutation.mutateAsync() + + router.replace('/') + } + const handleCloseDialog = () => { setIsOpenDialog(false) } @@ -52,98 +79,114 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { setIsOpenDialog(true) } - useEffect(() => { - if (postQuery.data) { - setTradeStatus(postQuery.data.tradeStatus.code) - } - }, [postQuery.data]) - return ( - -
-
- -
- + <> + +
- - {isSeller ? ( - <> - - - - {isOpenDialog && ( - - - - 수정하기 - - 삭제하기 - - - )} - - - ) : ( - - {postQuery.data?.tradeStatus.code} - - )} - - - {postQuery.data?.category.name || ''} - - - {postQuery.data?.title || ''} - - - {toLocaleCurrency(Number(postQuery.data?.price))} - - -
- -
- 상품 정보 - - - - {postQuery.data?.description} +
- - - -
- - -
+ +
+ + {isSeller ? ( + <> + + + + {isOpenDialog && ( + + + + 수정하기 + + + 삭제하기 + + + + )} + + + ) : ( + + {getPostQuery.data?.tradeStatus.code} + + )} + + + {getPostQuery.data?.category.name || ''} + + + {getPostQuery.data?.title || ''} + + + {toLocaleCurrency(Number(getPostQuery.data?.price))} + + +
+ +
+ 상품 정보 + + + + {getPostQuery.data?.description} +
+ + +
+
+ + +
+ + 삭제 + , + + ]} + description="삭제한 게시글은 복구할 수 없어요." + isOpen={isOpen} + title="게시글을 삭제하시겠어요?" + onClose={closeModal} + /> + ) } From 4469955e3ba06f680f620c162b60802efa09602e Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 3 Jan 2024 22:16:28 +0900 Subject: [PATCH 07/17] =?UTF-8?q?feat:=20post=20=EC=88=98=EC=A0=95=20query?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/post/apis.ts | 7 ++++++- src/apis/post/queries.ts | 12 ++++++++++-- src/apis/post/types.ts | 3 +-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/apis/post/apis.ts b/src/apis/post/apis.ts index 2b2bfd83..554be031 100644 --- a/src/apis/post/apis.ts +++ b/src/apis/post/apis.ts @@ -8,7 +8,9 @@ import type { UpdateTradeStatusReq, UpdateTradeStatusRes, DeletePostReq, - DeletePostRes + DeletePostRes, + UpdatePostReq, + UpdatePostRes } from './types' import { http } from '@utils/http' @@ -18,6 +20,9 @@ export const getPost = (id: number) => export const createPost = (param: CreatePostReq) => http.post('/posts', param) +export const updatePost = (postId: number, param: UpdatePostReq) => + http.put(`/posts/${postId}`, param) + export const getCategories = () => http.get('/categories') diff --git a/src/apis/post/queries.ts b/src/apis/post/queries.ts index 7a0c706a..0061dc3d 100644 --- a/src/apis/post/queries.ts +++ b/src/apis/post/queries.ts @@ -5,13 +5,15 @@ import { createPost, getPosts, updateTradeStatus, - deletePost + deletePost, + updatePost } from './apis' import type { CreatePostReq, DeletePostReq, GetPostsReq, GetPostsRes, + UpdatePostReq, UpdateTradeStatusReq } from './types' @@ -20,10 +22,16 @@ export const useCreatePostMutation = () => mutationFn: (param: CreatePostReq) => createPost(param) }) +export const useUpdatePostMutation = (postId: number) => + useMutation({ + mutationFn: (param: UpdatePostReq) => updatePost(postId, param) + }) + export const useGetPostQuery = (id: number) => useQuery({ queryKey: ['getPost', id], - queryFn: () => getPost(id) + queryFn: () => getPost(id), + enabled: Boolean(id) }) export const useGetCategoriesQuery = () => diff --git a/src/apis/post/types.ts b/src/apis/post/types.ts index e91811fa..d1befa42 100644 --- a/src/apis/post/types.ts +++ b/src/apis/post/types.ts @@ -6,7 +6,6 @@ import type { ProductConditionCodes, SortOptionsShape, TradeStatusCodes, - TradeStatusType, TradeTypeCodes } from '@types' @@ -18,7 +17,7 @@ export type UpdatePostReq = { price: number location: string productCondition: ProductConditionCodes - tradeStatus: TradeStatusType + tradeStatus: TradeStatusCodes tradeType: TradeTypeCodes thumbnailImageUrl: string imageUrls: string[] From 5ce8760da09ffe2a14a1ee5f51e1c2d1468fdfec Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Wed, 3 Jan 2024 22:18:00 +0900 Subject: [PATCH 08/17] =?UTF-8?q?feat:=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20api=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/post/[postId]/index.tsx | 1 + src/pages/post/index.tsx | 125 +++++++++++++++++++++++++----- 2 files changed, 105 insertions(+), 21 deletions(-) diff --git a/src/pages/post/[postId]/index.tsx b/src/pages/post/[postId]/index.tsx index f278f0b4..b9659edd 100644 --- a/src/pages/post/[postId]/index.tsx +++ b/src/pages/post/[postId]/index.tsx @@ -113,6 +113,7 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { 수정하기 diff --git a/src/pages/post/index.tsx b/src/pages/post/index.tsx index 3f733503..da182fe4 100644 --- a/src/pages/post/index.tsx +++ b/src/pages/post/index.tsx @@ -16,15 +16,21 @@ import type { SelectOnChangeHandler, InputProps } from '@offer-ui/react' +import type { GetServerSideProps } from 'next' import { useRouter } from 'next/router' import type { ReactElement, ChangeEventHandler } from 'react' -import { useState } from 'react' +import { useEffect, useState } from 'react' import { useCreateUploadImagesMutation } from '@apis/image' import type { CreatePostReq } from '@apis/post' -import { useGetCategoriesQuery, useCreatePostMutation } from '@apis/post' +import { + useGetCategoriesQuery, + useCreatePostMutation, + useUpdatePostMutation, + useGetPostQuery +} from '@apis/post' import { localeCurrencyToNumber } from '@utils/format' import { PostForm } from '@components' -import { TRADE_TYPES, PRODUCT_CONDITIONS } from '@constants' +import { TRADE_TYPES, PRODUCT_CONDITIONS, TRADE_STATUS } from '@constants' import { useResponsive } from '@hooks' type PostFormState = Partial< @@ -53,11 +59,24 @@ const isCompleteForm = ( ): postForm is Required => postFormKeys.every(key => Boolean(postForm[key])) -const PostPage = (): ReactElement => { +type Props = { editPostId: number; type: string } +export const getServerSideProps: GetServerSideProps = async ({ + query +}) => ({ + props: { + editPostId: Number(query.postId), + type: query.type as string + } +}) + +const PostPage = ({ type, editPostId }: Props): ReactElement => { const postMutation = useCreatePostMutation() + const getPostQuery = useGetPostQuery(editPostId) const uploadImagesQuery = useCreateUploadImagesMutation() const categoriesQuery = useGetCategoriesQuery() + const updatePostMutation = useUpdatePostMutation(editPostId) const router = useRouter() + const [postForm, setPostForm] = useState({}) const InputSize = useResponsive({ @@ -72,12 +91,27 @@ const PostPage = (): ReactElement => { }) } - const handleUpdateImageInfos: UploaderOnChangeHandler = ({ - images: imageInfos + const handleUpdateImageInfos: UploaderOnChangeHandler = async ({ + images }) => { + const imageFormData = new FormData() + + images.forEach( + info => info.file && imageFormData.append('files', info.file) + ) + + const { imageUrls } = await uploadImagesQuery.mutateAsync(imageFormData) + const imageInfos = postForm.imageInfos || [] + const newImageInfos = imageUrls.map((url, idx) => ({ + id: String(idx + imageInfos.length), + url + })) + + const nextImageInfos = [...imageInfos, ...newImageInfos] + setPostForm(prev => ({ ...prev, - imageInfos + imageInfos: nextImageInfos })) } @@ -95,26 +129,65 @@ const PostPage = (): ReactElement => { return } + let postId = editPostId const { imageInfos, price, ...post } = postForm - const imageFormData = new FormData() - - imageInfos.forEach( - info => info.file && imageFormData.append('files', info.file) - ) - - const { imageUrls } = await uploadImagesQuery.mutateAsync(imageFormData) - const [thumbnailImageUrl, ...images] = imageUrls || [] + const [thumbnailImageUrl, ...images] = imageInfos || [] + const imageUrls = images.map(info => info.url) - const res = await postMutation.mutateAsync({ + const nextPost = { ...post, - imageUrls: images, + imageUrls, price: localeCurrencyToNumber(price), - thumbnailImageUrl - }) + thumbnailImageUrl: thumbnailImageUrl.url + } + + if (type === 'update') { + await updatePostMutation.mutateAsync({ + ...nextPost, + tradeStatus: TRADE_STATUS[0].code + }) + } else { + const res = await postMutation.mutateAsync(nextPost) + postId = res.id + } - router.replace(`/post/${res.id}`) + router.replace(`/post/${postId}`) } + useEffect(() => { + if (getPostQuery.data) { + const { + category, + tradeType, + productCondition, + imageUrls, + thumbnailImageUrl, + price, + ...post + } = getPostQuery.data + const imageInfos = + imageUrls.map((url, idx) => ({ + id: String(idx + 1), + url + })) || [] + const thumbnailImageInfo = { + id: '0', + isRepresent: true, + url: thumbnailImageUrl || '' + } + const initialPostForm = { + category: category.code, + tradeType: tradeType.code, + productCondition: productCondition.code, + price: String(price), + imageInfos: [thumbnailImageInfo, ...imageInfos], + ...post + } + + setPostForm(initialPostForm) + } + }, [getPostQuery.data]) + return ( @@ -128,6 +201,7 @@ const PostPage = (): ReactElement => { name="title" placeholder="제목을 입력해주세요(40자 이내)" styleType="edit" + value={postForm.title} onChange={handleUpdatePostForm} /> @@ -154,6 +228,7 @@ const PostPage = (): ReactElement => { items={categoriesQuery.data || []} placeholder="선택" size="small" + value={postForm.category} onChange={handleUpdateCategory} /> @@ -162,6 +237,7 @@ const PostPage = (): ReactElement => { isPrice name="price" placeholder="시작가를 입력하세요" + value={postForm.price} width={InputSize} onChange={handleUpdatePostForm} /> @@ -170,6 +246,7 @@ const PostPage = (): ReactElement => { @@ -179,6 +256,7 @@ const PostPage = (): ReactElement => { direction="horizontal" formName="productCondition" items={PRODUCT_CONDITIONS} + selectedValue={postForm.productCondition} onChange={handleUpdatePostForm} /> @@ -187,6 +265,7 @@ const PostPage = (): ReactElement => { direction="horizontal" formName="tradeType" items={TRADE_TYPES} + selectedValue={postForm.tradeType} onChange={handleUpdatePostForm} /> @@ -196,7 +275,11 @@ const PostPage = (): ReactElement => { 상품 설명 - + From f88db0752dc5f5d7d3c9a9cfce62df1405a0ac37 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Thu, 4 Jan 2024 01:44:03 +0900 Subject: [PATCH 09/17] =?UTF-8?q?fix:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C=20=EA=B9=9C=EB=B9=A1=EA=B1=B0?= =?UTF-8?q?=EB=A6=AC=EB=8A=94=20=EC=9D=B4=EC=8A=88=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/post/index.tsx | 118 ++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 64 deletions(-) diff --git a/src/pages/post/index.tsx b/src/pages/post/index.tsx index da182fe4..555b04e1 100644 --- a/src/pages/post/index.tsx +++ b/src/pages/post/index.tsx @@ -10,25 +10,20 @@ import { Button, Divider } from '@offer-ui/react' -import type { - ImageInfo, - UploaderOnChangeHandler, - SelectOnChangeHandler, - InputProps -} from '@offer-ui/react' +import type { ImageInfo, InputProps } from '@offer-ui/react' import type { GetServerSideProps } from 'next' import { useRouter } from 'next/router' -import type { ReactElement, ChangeEventHandler } from 'react' +import type { ReactElement } from 'react' import { useEffect, useState } from 'react' -import { useCreateUploadImagesMutation } from '@apis/image' -import type { CreatePostReq } from '@apis/post' +import { localeCurrencyToNumber } from '@utils/format' +import type { CreatePostReq } from '@apis' import { useGetCategoriesQuery, useCreatePostMutation, useUpdatePostMutation, - useGetPostQuery -} from '@apis/post' -import { localeCurrencyToNumber } from '@utils/format' + useGetPostQuery, + useCreateUploadImagesMutation +} from '@apis' import { PostForm } from '@components' import { TRADE_TYPES, PRODUCT_CONDITIONS, TRADE_STATUS } from '@constants' import { useResponsive } from '@hooks' @@ -39,9 +34,8 @@ type PostFormState = Partial< price?: string imageInfos?: ImageInfo[] } -type HandleUpdatePostForm = ChangeEventHandler< - HTMLTextAreaElement | HTMLInputElement | HTMLFormElement -> +type PostFormStateKeys = KeyOf +type PostFormStateValues = ValueOf const postFormKeys: (keyof PostFormState)[] = [ 'title', @@ -59,20 +53,28 @@ const isCompleteForm = ( ): postForm is Required => postFormKeys.every(key => Boolean(postForm[key])) +const getImageFormData = (files: File[]) => { + const imageFormData = new FormData() + + files.forEach(file => imageFormData.append('files', file)) + + return imageFormData +} + type Props = { editPostId: number; type: string } export const getServerSideProps: GetServerSideProps = async ({ query }) => ({ props: { editPostId: Number(query.postId), - type: query.type as string + type: (query.type as string) || '' } }) const PostPage = ({ type, editPostId }: Props): ReactElement => { const postMutation = useCreatePostMutation() const getPostQuery = useGetPostQuery(editPostId) - const uploadImagesQuery = useCreateUploadImagesMutation() + const uploadImagesMutation = useCreateUploadImagesMutation() const categoriesQuery = useGetCategoriesQuery() const updatePostMutation = useUpdatePostMutation(editPostId) const router = useRouter() @@ -84,40 +86,10 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { tablet: '100%' }) - const handleUpdateCategory: SelectOnChangeHandler = ({ code }) => { - setPostForm({ - ...postForm, - category: code - }) - } - - const handleUpdateImageInfos: UploaderOnChangeHandler = async ({ - images - }) => { - const imageFormData = new FormData() - - images.forEach( - info => info.file && imageFormData.append('files', info.file) - ) - - const { imageUrls } = await uploadImagesQuery.mutateAsync(imageFormData) - const imageInfos = postForm.imageInfos || [] - const newImageInfos = imageUrls.map((url, idx) => ({ - id: String(idx + imageInfos.length), - url - })) - - const nextImageInfos = [...imageInfos, ...newImageInfos] - - setPostForm(prev => ({ - ...prev, - imageInfos: nextImageInfos - })) - } - - const handleUpdatePostForm: HandleUpdatePostForm = (e): void => { - const { name, value } = e.target - + const handleUpdatePostForm = ( + name: PostFormStateKeys, + value: PostFormStateValues + ): void => { setPostForm({ ...postForm, [name]: value @@ -129,16 +101,29 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { return } - let postId = editPostId const { imageInfos, price, ...post } = postForm - const [thumbnailImageUrl, ...images] = imageInfos || [] - const imageUrls = images.map(info => info.url) + const imageFiles = imageInfos + .filter(({ file }) => Boolean(file)) + .map(({ file }) => file) as File[] + let imageUrls = imageInfos.filter(({ file }) => !file).map(({ url }) => url) + let postId = editPostId + + if (imageFiles.length > 0) { + const imageFormData = getImageFormData(imageFiles) + + const { imageUrls: newImageUrls } = + await uploadImagesMutation.mutateAsync(imageFormData) + + imageUrls = imageUrls.concat(newImageUrls) + } + + const [thumbnailImageUrl, ...images] = imageUrls || [] const nextPost = { ...post, - imageUrls, + imageUrls: images, price: localeCurrencyToNumber(price), - thumbnailImageUrl: thumbnailImageUrl.url + thumbnailImageUrl: thumbnailImageUrl } if (type === 'update') { @@ -148,6 +133,7 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { }) } else { const res = await postMutation.mutateAsync(nextPost) + postId = res.id } @@ -202,7 +188,7 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { placeholder="제목을 입력해주세요(40자 이내)" styleType="edit" value={postForm.title} - onChange={handleUpdatePostForm} + onChange={e => handleUpdatePostForm('title', e.target.value)} /> {postForm.title?.length}/40 @@ -211,7 +197,9 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => {
+ handleUpdatePostForm('imageInfos', images) + } />
@@ -229,7 +217,7 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { placeholder="선택" size="small" value={postForm.category} - onChange={handleUpdateCategory} + onChange={({ code }) => handleUpdatePostForm('category', code)} /> @@ -239,7 +227,7 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { placeholder="시작가를 입력하세요" value={postForm.price} width={InputSize} - onChange={handleUpdatePostForm} + onChange={e => handleUpdatePostForm('price', e.target.value)} /> @@ -248,7 +236,7 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { placeholder="ex. 동작구 사당동" value={postForm.location} width={InputSize} - onChange={handleUpdatePostForm} + onChange={e => handleUpdatePostForm('location', e.target.value)} /> @@ -257,7 +245,9 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { formName="productCondition" items={PRODUCT_CONDITIONS} selectedValue={postForm.productCondition} - onChange={handleUpdatePostForm} + onChange={e => + handleUpdatePostForm('productCondition', e.target.value) + } /> @@ -266,7 +256,7 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { formName="tradeType" items={TRADE_TYPES} selectedValue={postForm.tradeType} - onChange={handleUpdatePostForm} + onChange={e => handleUpdatePostForm('tradeType', e.target.value)} /> @@ -278,7 +268,7 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { handleUpdatePostForm('description', e.target.value)} /> From 051e5cc5569330165094062d99df6e2eb9703ae2 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Thu, 4 Jan 2024 01:47:30 +0900 Subject: [PATCH 10/17] =?UTF-8?q?fix:=20=EA=B5=AC=EB=A7=A4=EC=9E=90=20?= =?UTF-8?q?=ED=83=9C=EA=B7=B8=20name=EC=9C=BC=EB=A1=9C=20=EB=B3=B4?= =?UTF-8?q?=EC=9D=B4=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/post/[postId]/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/post/[postId]/index.tsx b/src/pages/post/[postId]/index.tsx index b9659edd..f1736902 100644 --- a/src/pages/post/[postId]/index.tsx +++ b/src/pages/post/[postId]/index.tsx @@ -128,7 +128,7 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { ) : ( - {getPostQuery.data?.tradeStatus.code} + {getPostQuery.data?.tradeStatus.name} )} From 48d7f5abee60750cb2f3c6e480d74e8428020b91 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Thu, 4 Jan 2024 02:00:10 +0900 Subject: [PATCH 11/17] =?UTF-8?q?fix:=20=EA=B8=80=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EC=8B=9C=20=EA=B1=B0=EB=9E=98=20=EC=83=81=ED=83=9C=20=EC=9C=A0?= =?UTF-8?q?=EC=A7=80=EB=90=98=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/post/index.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pages/post/index.tsx b/src/pages/post/index.tsx index 555b04e1..6ef91413 100644 --- a/src/pages/post/index.tsx +++ b/src/pages/post/index.tsx @@ -72,10 +72,10 @@ export const getServerSideProps: GetServerSideProps = async ({ }) const PostPage = ({ type, editPostId }: Props): ReactElement => { - const postMutation = useCreatePostMutation() + const createPostMutation = useCreatePostMutation() const getPostQuery = useGetPostQuery(editPostId) - const uploadImagesMutation = useCreateUploadImagesMutation() - const categoriesQuery = useGetCategoriesQuery() + const createUploadImagesMutation = useCreateUploadImagesMutation() + const getCategoriesQuery = useGetCategoriesQuery() const updatePostMutation = useUpdatePostMutation(editPostId) const router = useRouter() @@ -112,7 +112,7 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { const imageFormData = getImageFormData(imageFiles) const { imageUrls: newImageUrls } = - await uploadImagesMutation.mutateAsync(imageFormData) + await createUploadImagesMutation.mutateAsync(imageFormData) imageUrls = imageUrls.concat(newImageUrls) } @@ -129,10 +129,10 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { if (type === 'update') { await updatePostMutation.mutateAsync({ ...nextPost, - tradeStatus: TRADE_STATUS[0].code + tradeStatus: getPostQuery.data?.tradeStatus.code || TRADE_STATUS[0].code }) } else { - const res = await postMutation.mutateAsync(nextPost) + const res = await createPostMutation.mutateAsync(nextPost) postId = res.id } @@ -213,7 +213,7 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { Date: Thu, 4 Jan 2024 02:28:50 +0900 Subject: [PATCH 12/17] =?UTF-8?q?fix:=20=EC=83=81=EC=84=B8=ED=8E=98=20?= =?UTF-8?q?=EC=8E=94=EB=84=A4=EC=9D=BC=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=B9=A0=EC=A7=80=EB=8A=94=20=EC=9D=B4=EC=8A=88=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/post/[postId]/index.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pages/post/[postId]/index.tsx b/src/pages/post/[postId]/index.tsx index f1736902..63eaf200 100644 --- a/src/pages/post/[postId]/index.tsx +++ b/src/pages/post/[postId]/index.tsx @@ -50,7 +50,11 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { const { user } = useAuth() const isSeller = user.id === getPostQuery.data?.seller.id - const postImages = getPostQuery.data?.imageUrls.map((url, idx) => ({ + const totalImages = [ + getPostQuery.data?.thumbnailImageUrl || '', + ...(getPostQuery.data?.imageUrls || []) + ] + const postImages = totalImages.map((url, idx) => ({ id: idx, url })) From 2519c4f6ee49ff2bc368d8ea02e18e0a3e3bae60 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Thu, 4 Jan 2024 16:56:37 +0900 Subject: [PATCH 13/17] =?UTF-8?q?feat:=20update=20->=20edit=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/post/[postId]/index.tsx | 2 +- src/pages/post/index.tsx | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/pages/post/[postId]/index.tsx b/src/pages/post/[postId]/index.tsx index 63eaf200..a25e4928 100644 --- a/src/pages/post/[postId]/index.tsx +++ b/src/pages/post/[postId]/index.tsx @@ -117,7 +117,7 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { 수정하기 diff --git a/src/pages/post/index.tsx b/src/pages/post/index.tsx index 6ef91413..71fc541b 100644 --- a/src/pages/post/index.tsx +++ b/src/pages/post/index.tsx @@ -149,7 +149,9 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { imageUrls, thumbnailImageUrl, price, - ...post + title, + description, + location } = getPostQuery.data const imageInfos = imageUrls.map((url, idx) => ({ @@ -161,13 +163,15 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { isRepresent: true, url: thumbnailImageUrl || '' } - const initialPostForm = { + const initialPostForm: PostFormState = { category: category.code, tradeType: tradeType.code, productCondition: productCondition.code, price: String(price), imageInfos: [thumbnailImageInfo, ...imageInfos], - ...post + title, + description, + location } setPostForm(initialPostForm) From 09c940a0d9e0b8a5ce5878219b394863b54979bb Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Sat, 13 Jan 2024 00:13:42 +0900 Subject: [PATCH 14/17] =?UTF-8?q?feat:=20req=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/post/apis.ts | 17 ++++++++++------- src/apis/post/queries.ts | 9 ++++----- src/apis/post/types.ts | 2 ++ src/pages/post/[postId]/index.tsx | 3 ++- src/pages/post/index.tsx | 3 ++- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/apis/post/apis.ts b/src/apis/post/apis.ts index 554be031..c5f1e127 100644 --- a/src/apis/post/apis.ts +++ b/src/apis/post/apis.ts @@ -20,8 +20,11 @@ export const getPost = (id: number) => export const createPost = (param: CreatePostReq) => http.post('/posts', param) -export const updatePost = (postId: number, param: UpdatePostReq) => - http.put(`/posts/${postId}`, param) +export const updatePost = ({ postId, ...params }: UpdatePostReq) => + http.put, UpdatePostRes>( + `/posts/${postId}`, + params + ) export const getCategories = () => http.get('/categories') @@ -29,11 +32,11 @@ export const getCategories = () => export const getPosts = (params: GetPostsReq) => http.get('/posts', params) -export const updateTradeStatus = ( - postId: number, - params: UpdateTradeStatusReq -) => - http.put( +export const updateTradeStatus = ({ + postId, + ...params +}: UpdateTradeStatusReq) => + http.put, UpdateTradeStatusRes>( `/posts/trade-status/${postId}`, params ) diff --git a/src/apis/post/queries.ts b/src/apis/post/queries.ts index 0061dc3d..00f2d169 100644 --- a/src/apis/post/queries.ts +++ b/src/apis/post/queries.ts @@ -22,9 +22,9 @@ export const useCreatePostMutation = () => mutationFn: (param: CreatePostReq) => createPost(param) }) -export const useUpdatePostMutation = (postId: number) => +export const useUpdatePostMutation = () => useMutation({ - mutationFn: (param: UpdatePostReq) => updatePost(postId, param) + mutationFn: (params: UpdatePostReq) => updatePost(params) }) export const useGetPostQuery = (id: number) => @@ -57,10 +57,9 @@ export const useGetInfinitePostsQuery = (params: GetPostsReq) => : undefined }) -export const useUpdateTradeStatusMutation = (postId: number) => +export const useUpdateTradeStatusMutation = () => useMutation({ - mutationFn: (params: UpdateTradeStatusReq) => - updateTradeStatus(postId, params) + mutationFn: (params: UpdateTradeStatusReq) => updateTradeStatus(params) }) export const useDeletePostMutation = (postId: DeletePostReq) => diff --git a/src/apis/post/types.ts b/src/apis/post/types.ts index d1befa42..f5e6a1de 100644 --- a/src/apis/post/types.ts +++ b/src/apis/post/types.ts @@ -12,6 +12,7 @@ import type { export type GetPostRes = PostDetail export type UpdatePostReq = { + postId: number title: string category: string price: number @@ -32,6 +33,7 @@ export type DeletePostRes = { // TODO: 정확한 타입 BE 확인 필요 export type UpdateTradeStatusReq = { + postId: number tradeStatus: TradeStatusCodes } export type UpdateTradeStatusRes = number diff --git a/src/pages/post/[postId]/index.tsx b/src/pages/post/[postId]/index.tsx index a25e4928..f83ab834 100644 --- a/src/pages/post/[postId]/index.tsx +++ b/src/pages/post/[postId]/index.tsx @@ -41,7 +41,7 @@ export const getServerSideProps: GetServerSideProps = async ({ const PostDetailPage = ({ postId }: Props): ReactElement => { const getPostQuery = useGetPostQuery(postId) - const updateTradeStatusMutation = useUpdateTradeStatusMutation(postId) + const updateTradeStatusMutation = useUpdateTradeStatusMutation() const deletePostMutation = useDeletePostMutation(postId) const router = useRouter() const [tradeStatus, setTradeStatus] = useState() @@ -65,6 +65,7 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { setTradeStatus(nextStatusCode) await updateTradeStatusMutation.mutateAsync({ + postId, tradeStatus: nextStatusCode }) } diff --git a/src/pages/post/index.tsx b/src/pages/post/index.tsx index 71fc541b..1d05eb4c 100644 --- a/src/pages/post/index.tsx +++ b/src/pages/post/index.tsx @@ -76,7 +76,7 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { const getPostQuery = useGetPostQuery(editPostId) const createUploadImagesMutation = useCreateUploadImagesMutation() const getCategoriesQuery = useGetCategoriesQuery() - const updatePostMutation = useUpdatePostMutation(editPostId) + const updatePostMutation = useUpdatePostMutation() const router = useRouter() const [postForm, setPostForm] = useState({}) @@ -128,6 +128,7 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { if (type === 'update') { await updatePostMutation.mutateAsync({ + postId, ...nextPost, tradeStatus: getPostQuery.data?.tradeStatus.code || TRADE_STATUS[0].code }) From 6bdc4933fd3e32f96c98f5bb784e65ffd7b678dd Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Sat, 13 Jan 2024 00:38:25 +0900 Subject: [PATCH 15/17] =?UTF-8?q?chore:=20=EA=B0=80=EB=8F=85=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=97=AC=EB=B0=B1=20=EB=B0=8F?= =?UTF-8?q?=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/post/[postId]/index.tsx | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/pages/post/[postId]/index.tsx b/src/pages/post/[postId]/index.tsx index f83ab834..437bbf1f 100644 --- a/src/pages/post/[postId]/index.tsx +++ b/src/pages/post/[postId]/index.tsx @@ -43,10 +43,12 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { const getPostQuery = useGetPostQuery(postId) const updateTradeStatusMutation = useUpdateTradeStatusMutation() const deletePostMutation = useDeletePostMutation(postId) - const router = useRouter() + const [tradeStatus, setTradeStatus] = useState() - const [isOpenDialog, setIsOpenDialog] = useState(false) - const { isOpen, openModal, closeModal } = useModal() + const router = useRouter() + + const tradeStatusDialog = useModal() + const deleteModal = useModal() const { user } = useAuth() const isSeller = user.id === getPostQuery.data?.seller.id @@ -76,14 +78,6 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { router.replace('/') } - const handleCloseDialog = () => { - setIsOpenDialog(false) - } - - const handleClickMore = () => { - setIsOpenDialog(true) - } - return ( <> @@ -106,15 +100,15 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { - {isOpenDialog && ( + {tradeStatusDialog.isOpen && ( + onClose={tradeStatusDialog.closeModal}> { })}`}> 수정하기 - + 삭제하기 @@ -183,14 +177,14 @@ const PostDetailPage = ({ postId }: Props): ReactElement => { key="cancel" size="large" styleType="ghost" - onClick={closeModal}> + onClick={deleteModal.closeModal}> 취소 ]} description="삭제한 게시글은 복구할 수 없어요." - isOpen={isOpen} + isOpen={deleteModal.isOpen} title="게시글을 삭제하시겠어요?" - onClose={closeModal} + onClose={deleteModal.closeModal} /> ) From 4849a84e6c8ad1ab54bc2c4fde55298099efab83 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Sat, 13 Jan 2024 00:39:19 +0900 Subject: [PATCH 16/17] =?UTF-8?q?feat:=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EB=B3=80=ED=99=98=20query=20=EC=AA=BD=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/post/queries.ts | 25 ++++++++++++++++++++++++- src/pages/post/index.tsx | 34 +--------------------------------- 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/src/apis/post/queries.ts b/src/apis/post/queries.ts index 00f2d169..af3eb835 100644 --- a/src/apis/post/queries.ts +++ b/src/apis/post/queries.ts @@ -31,7 +31,30 @@ export const useGetPostQuery = (id: number) => useQuery({ queryKey: ['getPost', id], queryFn: () => getPost(id), - enabled: Boolean(id) + enabled: typeof id === 'number', + select: data => ({ + ...data, + postForm: { + category: data.category.code, + tradeType: data.tradeType.code, + productCondition: data.productCondition.code, + price: String(data.price), + imageInfos: [ + { + id: '0', + isRepresent: true, + url: data.thumbnailImageUrl || '' + }, + ...(data.imageUrls.map((url, idx) => ({ + id: String(idx + 1), + url + })) || []) + ], + title: data.title, + description: data.description, + location: data.location + } + }) }) export const useGetCategoriesQuery = () => diff --git a/src/pages/post/index.tsx b/src/pages/post/index.tsx index 1d05eb4c..d378478f 100644 --- a/src/pages/post/index.tsx +++ b/src/pages/post/index.tsx @@ -143,39 +143,7 @@ const PostPage = ({ type, editPostId }: Props): ReactElement => { useEffect(() => { if (getPostQuery.data) { - const { - category, - tradeType, - productCondition, - imageUrls, - thumbnailImageUrl, - price, - title, - description, - location - } = getPostQuery.data - const imageInfos = - imageUrls.map((url, idx) => ({ - id: String(idx + 1), - url - })) || [] - const thumbnailImageInfo = { - id: '0', - isRepresent: true, - url: thumbnailImageUrl || '' - } - const initialPostForm: PostFormState = { - category: category.code, - tradeType: tradeType.code, - productCondition: productCondition.code, - price: String(price), - imageInfos: [thumbnailImageInfo, ...imageInfos], - title, - description, - location - } - - setPostForm(initialPostForm) + setPostForm(getPostQuery.data.postForm) } }, [getPostQuery.data]) From b059b8fd8ba09b140a2fea002d43908fc4ae84e6 Mon Sep 17 00:00:00 2001 From: shinhyojeong Date: Mon, 15 Jan 2024 14:05:53 +0900 Subject: [PATCH 17/17] =?UTF-8?q?design:=20UserProfile=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=20=EB=B3=80=EA=B2=BD=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/post/UserProfile/index.tsx | 16 +++++++++------- src/components/post/UserProfile/types.ts | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/components/post/UserProfile/index.tsx b/src/components/post/UserProfile/index.tsx index 8be92600..25321329 100644 --- a/src/components/post/UserProfile/index.tsx +++ b/src/components/post/UserProfile/index.tsx @@ -27,14 +27,16 @@ const UserProfile = ({ {level} - - {location} - {isOfferProfile && ` · ${tradeType}`} - {isOfferProfile && ( - - {date} - + <> + + {location} + {` · ${tradeType}`} + + + {date} + + )} diff --git a/src/components/post/UserProfile/types.ts b/src/components/post/UserProfile/types.ts index 01c8f47f..483b9346 100644 --- a/src/components/post/UserProfile/types.ts +++ b/src/components/post/UserProfile/types.ts @@ -3,7 +3,7 @@ import type { TradeTypeNames } from '@types' export type UserProfileProps = { image?: string nickName: string - location: string + location?: string type: 'offer' | 'basic' level: number date?: string