diff --git a/next.config.js b/next.config.js
index 0900d4ff..175063cb 100644
--- a/next.config.js
+++ b/next.config.js
@@ -1,6 +1,10 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
+ domains: [
+ 'team-01-bucket.s3.ap-northeast-2.amazonaws.com',
+ 'dummyimage.com',
+ ],
remotePatterns: [
{
protocol: 'https',
diff --git a/src/app/(root)/(routes)/(home)/error.tsx b/src/app/(root)/(routes)/(home)/error.tsx
index 55de7d35..bec79a27 100644
--- a/src/app/(root)/(routes)/(home)/error.tsx
+++ b/src/app/(root)/(routes)/(home)/error.tsx
@@ -18,7 +18,7 @@ export default function ErrorPage({
const { toast } = useToast()
useEffect(() => {
// Log the error to an error reporting service
- console.log(error.digest, error.message, error.name)
+
if (error.message === ErrorMessages.Forbidden) {
console.log('ForbiddenError')
toast({
diff --git a/src/app/(root)/(routes)/cards/[cardId]/modify/error.tsx b/src/app/(root)/(routes)/cards/[cardId]/modify/error.tsx
index 2cdc24d0..afffdf69 100644
--- a/src/app/(root)/(routes)/cards/[cardId]/modify/error.tsx
+++ b/src/app/(root)/(routes)/cards/[cardId]/modify/error.tsx
@@ -2,6 +2,10 @@
// Error components must be Client Components
import { useEffect } from 'react'
+import { useRouter } from 'next/navigation'
+import AppPath from '@/config/appPath'
+import ErrorMessages from '@/config/errorMessages'
+import { useToast } from '@/hooks/useToast'
export default function Error({
error,
@@ -10,14 +14,41 @@ export default function Error({
error: Error & { digest?: string }
reset: () => void
}) {
+ const router = useRouter()
+ const { toast } = useToast()
useEffect(() => {
- // Log the error to an error reporting service
- console.error(error)
- }, [error])
+ console.log(error.digest, error.message, error.name)
+ if (error.message === ErrorMessages.Forbidden) {
+ console.log('ForbiddenError')
+ toast({
+ title: 'Forbidden',
+ description: ErrorMessages.Forbidden,
+ duration: 2000,
+ })
+ }
+ if (error.message === ErrorMessages.Unauthorized) {
+ router.push(AppPath.login())
+ toast({
+ title: 'Unauthorized',
+ description: ErrorMessages.Unauthorized,
+ duration: 2000,
+ })
+ }
+ if (error.message === ErrorMessages.NotFound) {
+ toast({
+ title: 'Not Found',
+ description: ErrorMessages.NotFound,
+ duration: 2000,
+ })
+ }
+ }, [error, router, toast])
return (
Something went wrong!
+
+ Error: {error.message} ({error?.name})
+
=> {
+ const token = getServerCookie()
const res = await getCardInfo(parseInt(cardId))
const imagesByForm = res.data.cardInfo.images.map((image) => {
return image.url
})
Object.assign(res.data.cardInfo, { images: imagesByForm })
+ const resUser = await apiClient.get(
+ ApiEndPoint.getValidateUser(),
+ {},
+ {
+ Authorization: `${token}`,
+ },
+ )
+
+ if (resUser.data.userInfo.userId !== res.data.userInfo.userId) {
+ throw new ForbiddenError(new Response(ErrorMessages.Forbidden))
+ }
+
return res.data.cardInfo as unknown as CardUploadFormValues
}
diff --git a/src/app/(root)/(routes)/cards/components/card-list-content/CardListContent.tsx b/src/app/(root)/(routes)/cards/components/card-list-content/CardListContent.tsx
new file mode 100644
index 00000000..0851fed2
--- /dev/null
+++ b/src/app/(root)/(routes)/cards/components/card-list-content/CardListContent.tsx
@@ -0,0 +1,76 @@
+'use client'
+
+import { useEffect, useRef, useState } from 'react'
+import { useSearchParams } from 'next/navigation'
+import ExceptionBoundary from '@/components/domain/exception-boundary'
+import { useCardsQuery } from '@/hooks/api/queries/useCardsQuery'
+import { useIntersectionObserver } from '@/hooks/useIntersectionObserver'
+import { CategoryObjs, PriceRangeObjs } from '@/types/card'
+import CardList from '../card-list/CardList'
+import FilterFormDialog from '../filter-form-dialog'
+import SearchInput from '../search-input'
+
+const CardListContent = () => {
+ const searchParams = useSearchParams()
+ const [cardTitle, setCardTitle] = useState(
+ searchParams.get('cardTitle' as string) || '',
+ )
+ const [category, setCatgegory] = useState(
+ (searchParams.get('category') as CategoryObjs['key']) || undefined,
+ )
+ const [priceRange, setPriceRange] = useState(
+ (searchParams.get('priceRange') as PriceRangeObjs['key']) || undefined,
+ )
+
+ // TODO: 현재 API 명세에 status에 어떤 값을 줘야하는지에 대한 정의가 되어 있지 않기 때문에 임시로 상수 값을 전달함 => 추후에 실제 동작 값으로 고치기
+ const { data, fetchNextPage, isError, isFetchingNextPage, isLoading } =
+ useCardsQuery({
+ category: category,
+ priceRange: priceRange,
+ cardTitle: cardTitle,
+ })
+
+ const lastElementRef = useRef(null)
+ const entry = useIntersectionObserver(lastElementRef, { threshold: 1.0 })
+
+ useEffect(() => {
+ if (isFetchingNextPage) {
+ return
+ }
+
+ if (entry?.isIntersecting) {
+ fetchNextPage()
+ }
+ }, [entry?.isIntersecting, fetchNextPage, isFetchingNextPage])
+
+ // TODO: 아이템이 없을시 어떤 UI를 보여줄지 차후에 결정
+
+ const isEmpty = data?.pages[0].data.cardList.length === 0
+ console.log('content', data)
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+ >
+ )
+}
+export default CardListContent
diff --git a/src/app/(root)/(routes)/cards/components/card-list-content/index.tsx b/src/app/(root)/(routes)/cards/components/card-list-content/index.tsx
new file mode 100644
index 00000000..37ab04a9
--- /dev/null
+++ b/src/app/(root)/(routes)/cards/components/card-list-content/index.tsx
@@ -0,0 +1,3 @@
+import CardListContent from './CardListContent'
+
+export default CardListContent
diff --git a/src/app/(root)/(routes)/cards/components/card-list/CardList.tsx b/src/app/(root)/(routes)/cards/components/card-list/CardList.tsx
index c0f6adf2..b4871dc9 100644
--- a/src/app/(root)/(routes)/cards/components/card-list/CardList.tsx
+++ b/src/app/(root)/(routes)/cards/components/card-list/CardList.tsx
@@ -1,88 +1,25 @@
-'use client'
-
-import { useEffect, useRef, Fragment, useState } from 'react'
-import { useSearchParams } from 'next/navigation'
+import { Fragment } from 'react'
+import { InfiniteData } from '@tanstack/react-query'
import TradeStatusCard from '@/components/domain/card/trade-status-card'
-import ExceptionBoundary from '@/components/domain/exception-boundary'
-import MaxWidthWrapper from '@/components/domain/max-width-wrapper'
-import { useCardsQuery } from '@/hooks/api/queries/useCardsQuery'
-import { useIntersectionObserver } from '@/hooks/useIntersectionObserver'
+import { GetCardListRes } from '@/services/card/card'
import { Card } from '@/types/card'
-import { Category, PriceRange } from '@/types/card'
-import FilterFormDialog from '../filter-form-dialog'
-import SearchInput from '../search-input'
-
-const CardListContent = () => {
- const searchParams = useSearchParams()
- const [cardTitle, setCardTitle] = useState(
- searchParams.get('cardTitle' as string) || '',
- )
- const [category, setCatgegory] = useState(
- (searchParams.get('category') as Category) || '전체보기',
- )
- const [priceRange, setPriceRange] = useState(
- (searchParams.get('priceRange') as PriceRange) || '전체보기',
- )
-
- // TODO: 현재 API 명세에 status에 어떤 값을 줘야하는지에 대한 정의가 되어 있지 않기 때문에 임시로 상수 값을 전달함 => 추후에 실제 동작 값으로 고치기
- const { data, fetchNextPage, isError, isFetchingNextPage, isLoading } =
- useCardsQuery({
- category: category,
- priceRange: priceRange,
- cardTitle: cardTitle,
- })
-
- const lastElementRef = useRef(null)
- const entry = useIntersectionObserver(lastElementRef, { threshold: 1.0 })
-
- useEffect(() => {
- if (isFetchingNextPage) {
- return
- }
-
- if (entry?.isIntersecting) {
- fetchNextPage()
- }
- }, [entry?.isIntersecting, fetchNextPage, isFetchingNextPage])
-
- // TODO: 아이템이 없을시 어떤 UI를 보여줄지 차후에 결정
-
- const isEmpty = data?.pages[0].length === 0
-
- return (
-
-
-
-
-
-
-
- <>
- {data?.pages.map((currentPage: any, pageIndex) => (
-
- {currentPage.map((card: Card) => (
-
-
-
- ))}
-
- ))}
- >
-
-
-
-
- )
-}
-export default CardListContent
+const CardList = ({
+ data,
+}: {
+ data: InfiniteData | undefined
+}) => (
+ <>
+ {data?.pages.map(({ data: { cardList } }: GetCardListRes, pageIndex) => (
+
+ {cardList.map((card: Card) => (
+
+
+
+ ))}
+
+ ))}
+ >
+)
+
+export default CardList
diff --git a/src/app/(root)/(routes)/cards/components/filter-form-dialog/FilterFormDialog.tsx b/src/app/(root)/(routes)/cards/components/filter-form-dialog/FilterFormDialog.tsx
index 896d5aba..9a8f307c 100644
--- a/src/app/(root)/(routes)/cards/components/filter-form-dialog/FilterFormDialog.tsx
+++ b/src/app/(root)/(routes)/cards/components/filter-form-dialog/FilterFormDialog.tsx
@@ -16,13 +16,14 @@ import {
SelectTrigger,
} from '@/components/ui/select'
import Assets from '@/config/assets'
-import { Category, PriceRange } from '@/types/card'
+import { CATEGORY_OBJS, PRICE_RANGE_OBJS } from '@/constants/card'
+import { CategoryObjs, PriceRangeObjs } from '@/types/card'
type FilterFormDialogProps = {
- priceRange: PriceRange
- category: Category
- setPriceRange: (priceRange: PriceRange) => void
- setCategory: (category: Category) => void
+ priceRange: PriceRangeObjs['key']
+ category: CategoryObjs['key']
+ setPriceRange: (priceRange: PriceRangeObjs['key']) => void
+ setCategory: (category: CategoryObjs['key']) => void
}
const FilterFormDialog = ({
@@ -39,20 +40,12 @@ const FilterFormDialog = ({
setIsOpen(false)
}
- const categories: Category[] = [
- '남성의류',
- '여성의류',
- '잡화ㆍ액세서리',
- '신발',
- '스포츠',
- '도서',
- '전자기기',
- '가구ㆍ인테리어',
- '가전',
- ]
-
// FIXME: 선택 안된 경우 값으로 변경
const hasNoFilter = priceRange !== undefined || category !== undefined
+ const priceRangeValue = PRICE_RANGE_OBJS.find(({ key }) => key === priceRange)
+ ?.value
+ const getCategoryValue = (categoryKey: CategoryObjs['key']) =>
+ CATEGORY_OBJS.find(({ key }) => key === categoryKey)?.value
return (
<>
@@ -89,19 +82,23 @@ const FilterFormDialog = ({
{
+ onValueChange={(value: PriceRangeObjs['key']) => {
setPriceRange(value)
}}
>
- {priceRange}
+
+ {priceRangeValue || '가격대를 선택해주세요'}
+
- 전체보기
- 10만원대
- 20만원대
- 30만원대
- 40만원대
- 50만원이상
+ {PRICE_RANGE_OBJS.map((currentPriceRange: PriceRangeObjs) => (
+
+ {currentPriceRange['value']}
+
+ ))}
@@ -113,19 +110,24 @@ const FilterFormDialog = ({
카테고리
- {categories.map((currentCategory: Category, index) => (
+ {CATEGORY_OBJS.map((currentCategory: CategoryObjs) => (
- setCategory(e.currentTarget.textContent as Category)
+ setCategory(
+ e.currentTarget.getAttribute(
+ 'data-category-key',
+ ) as CategoryObjs['key'],
+ )
}
>
- {currentCategory}
+ {getCategoryValue(currentCategory.key)}
))}
diff --git a/src/app/(root)/(routes)/cards/page.tsx b/src/app/(root)/(routes)/cards/page.tsx
index 08adf368..f07604ce 100644
--- a/src/app/(root)/(routes)/cards/page.tsx
+++ b/src/app/(root)/(routes)/cards/page.tsx
@@ -1,15 +1,16 @@
import { FunctionComponent } from 'react'
+import MaxWidthWrapper from '@/components/domain/max-width-wrapper'
import PageTitle from '@/components/domain/page-title'
-import CardList from './components/card-list'
+import CardListContent from './components/card-list-content'
interface CardListPageProps {}
const CardListPage: FunctionComponent = ({}) => {
return (
-
+
+
)
}
diff --git a/src/app/(root)/(routes)/mypage/components/UserInfo.tsx b/src/app/(root)/(routes)/mypage/components/UserInfo.tsx
index 4b5c16cd..18720d94 100644
--- a/src/app/(root)/(routes)/mypage/components/UserInfo.tsx
+++ b/src/app/(root)/(routes)/mypage/components/UserInfo.tsx
@@ -3,33 +3,52 @@
import React, { useState } from 'react'
import AvatarEditable from '@/components/domain/avatar-editable'
import TextEditable from '@/components/domain/text-editable'
-import { useAuth } from '@/contexts/AuthProvider'
+import { useToast } from '@/hooks/useToast'
+import { postImageFile } from '@/services/images'
import { putUserNickname, putUserProfile } from '@/services/user/user'
+import { User } from '@/types/user'
-const UserInfo = () => {
- const { currentUser } = useAuth()
+type UserInfoProps = {
+ user: User
+}
+
+const UserInfo = ({ user }: UserInfoProps) => {
+ const { toast } = useToast()
const [isProfileChanged, setIsProfileChanged] = useState(true)
const [isNicknameChanged, setIsNicknameChanged] = useState(true)
const fileChangeHandler = async (file: File) => {
setIsProfileChanged(true)
try {
- const _data = await putUserProfile({ file: file })
+ const resUpload = await postImageFile(file)
+ const resProfile = await putUserProfile(resUpload.data)
+ window.location.reload()
+ return resProfile.data
} catch (error) {
setIsProfileChanged(false)
console.log(error)
- // TODO: toast error message 추가
+ toast({
+ title: '프로필 이미지 변경 실패',
+ description: '프로필 이미지 변경에 실패했습니다.',
+ variant: 'destructive',
+ })
}
}
const nicknameChangeHandler = async (nickname: string) => {
setIsNicknameChanged(true)
try {
- const _data = await putUserNickname(nickname)
+ const res = await putUserNickname(nickname)
+ window.location.reload()
+ return res.data
} catch (error) {
setIsNicknameChanged(false)
console.log(error)
- //TODO: toast error message 추가
+ toast({
+ title: '닉네임 변경 실패',
+ description: '닉네임 변경에 실패했습니다.',
+ variant: 'destructive',
+ })
}
}
@@ -39,12 +58,12 @@ const UserInfo = () => {
)
diff --git a/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list-content/MyTradeHistoryListContent.tsx b/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list-content/MyTradeHistoryListContent.tsx
new file mode 100644
index 00000000..bf951512
--- /dev/null
+++ b/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list-content/MyTradeHistoryListContent.tsx
@@ -0,0 +1,45 @@
+'use client'
+
+import { useEffect, useRef, Fragment } from 'react'
+import ExceptionBoundary from '@/components/domain/exception-boundary'
+import { useMyTradeHistoryQuery } from '@/hooks/api/queries/useMyTradeHistoriesQuery'
+import { useIntersectionObserver } from '@/hooks/useIntersectionObserver'
+import MyTradeHistoryList from '../my-trade-history-list/MyTradeHistoryList'
+
+const MyTradeHistoryListContent = () => {
+ const { data, fetchNextPage, isLoading, isError, isFetchingNextPage } =
+ useMyTradeHistoryQuery()
+
+ const lastElementRef = useRef(null)
+ const entry = useIntersectionObserver(lastElementRef, { threshold: 1.0 })
+
+ useEffect(() => {
+ if (isFetchingNextPage) {
+ return
+ }
+
+ if (entry?.isIntersecting) {
+ fetchNextPage()
+ }
+ }, [entry?.isIntersecting, fetchNextPage, isFetchingNextPage])
+
+ const isEmpty = data?.pages[0].data.historyList.length === 0
+
+ return (
+ <>
+
+
+
+
+
+
+
+ >
+ )
+}
+export default MyTradeHistoryListContent
diff --git a/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list-content/index.tsx b/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list-content/index.tsx
new file mode 100644
index 00000000..e52acc8d
--- /dev/null
+++ b/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list-content/index.tsx
@@ -0,0 +1,3 @@
+import MyTradeHistoryListContent from './MyTradeHistoryListContent'
+
+export default MyTradeHistoryListContent
diff --git a/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list/MyTradeHistoryList.tsx b/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list/MyTradeHistoryList.tsx
index ead08b76..3395a5d8 100644
--- a/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list/MyTradeHistoryList.tsx
+++ b/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list/MyTradeHistoryList.tsx
@@ -1,59 +1,27 @@
-'use client'
-
-import { useEffect, useRef, Fragment } from 'react'
-import HistoryCard from '@/components/domain/card/trade-history-card'
-import ExceptionBoundary from '@/components/domain/exception-boundary'
-import MaxWidthWrapper from '@/components/domain/max-width-wrapper'
-import { useMyTradeHistoryQuery } from '@/hooks/api/queries/useMyTradeHistoriesQuery'
-import { useIntersectionObserver } from '@/hooks/useIntersectionObserver'
-import { MyHistoryRes } from '@/services/history/history'
-
-const MyCardList = () => {
- const { data, fetchNextPage, isLoading, isError, isFetchingNextPage } =
- useMyTradeHistoryQuery()
-
- const lastElementRef = useRef(null)
- const entry = useIntersectionObserver(lastElementRef, { threshold: 1.0 })
-
- useEffect(() => {
- if (isFetchingNextPage) {
- return
- }
-
- if (entry?.isIntersecting) {
- fetchNextPage()
- }
- }, [entry?.isIntersecting, fetchNextPage, isFetchingNextPage])
-
- const isEmpty = data?.pages[0].length === 0
-
- return (
-
-
-
- <>
- {data?.pages.map((currentPage, pageIndex) => (
-
- {currentPage.map((myHistory: MyHistoryRes) => (
-
-
-
- ))}
-
- ))}
- >
-
-
- {/*TODO: 로딩 부분에 대한 처리 논의 후 구체적으로 적용 할 것 =>
를 사용할지, isLoading으로 처리할지 논의 */}
-
-
-
-
- )
-}
-export default MyCardList
+import { Fragment } from 'react'
+import { InfiniteData } from '@tanstack/react-query'
+import TradeHistoryCard from '@/components/domain/card/trade-history-card'
+import { GetMyTradeHistoryListRes } from '@/services/history/history'
+import { TradeHistory } from '@/types/tradeHistory'
+
+const MyTradeHistoryList = ({
+ data,
+}: {
+ data: InfiniteData | undefined
+}) => (
+ <>
+ {data?.pages.map(
+ ({ data: { historyList } }: GetMyTradeHistoryListRes, pageIndex) => (
+
+ {historyList.map((myHistory: TradeHistory) => (
+
+
+
+ ))}
+
+ ),
+ )}
+ >
+)
+
+export default MyTradeHistoryList
diff --git a/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list/index.tsx b/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list/index.tsx
index fc4b2257..708901ca 100644
--- a/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list/index.tsx
+++ b/src/app/(root)/(routes)/mypage/histories/components/my-trade-history-list/index.tsx
@@ -1,3 +1,3 @@
-import HistoryList from './MyTradeHistoryList'
+import MyTradeHistoryList from './MyTradeHistoryList'
-export default HistoryList
+export default MyTradeHistoryList
diff --git a/src/app/(root)/(routes)/mypage/histories/page.tsx b/src/app/(root)/(routes)/mypage/histories/page.tsx
index cc1208ed..098b4300 100644
--- a/src/app/(root)/(routes)/mypage/histories/page.tsx
+++ b/src/app/(root)/(routes)/mypage/histories/page.tsx
@@ -1,17 +1,16 @@
import { FunctionComponent } from 'react'
+import MaxWidthWrapper from '@/components/domain/max-width-wrapper'
import PageTitle from '@/components/domain/page-title'
-import MyTradeHistoryList from './components/my-trade-history-list'
+import MyTradeHistoryList from './components/my-trade-history-list-content'
interface MyHistoryListPageProps {}
const MyHistoryListPage: FunctionComponent = ({}) => {
return (
-
+
)
}
diff --git a/src/app/(root)/(routes)/mypage/mycards/components/my-card-list-content/MyCardListContent.tsx b/src/app/(root)/(routes)/mypage/mycards/components/my-card-list-content/MyCardListContent.tsx
new file mode 100644
index 00000000..133f488c
--- /dev/null
+++ b/src/app/(root)/(routes)/mypage/mycards/components/my-card-list-content/MyCardListContent.tsx
@@ -0,0 +1,57 @@
+'use client'
+
+import { useEffect, useRef, useState } from 'react'
+import ExceptionBoundary from '@/components/domain/exception-boundary'
+import MaxWidthWrapper from '@/components/domain/max-width-wrapper'
+import { useMyCardsQuery } from '@/hooks/api/queries/useMyCardsQuery'
+import { useIntersectionObserver } from '@/hooks/useIntersectionObserver'
+import { TradeStatus } from '@/types/card'
+import MyCardList from '../my-card-list/MyCardList'
+import TradeStatusTabs from '../trade-status-tabs'
+
+const MyCardListContent = () => {
+ const [tradeStatus, setTradeStatus] = useState('TRADE_AVAILABLE')
+
+ const { data, fetchNextPage, isLoading, isError, isFetchingNextPage } =
+ useMyCardsQuery({
+ tradeStatus,
+ })
+
+ const lastElementRef = useRef(null)
+ const entry = useIntersectionObserver(lastElementRef, { threshold: 1.0 })
+
+ useEffect(() => {
+ if (isFetchingNextPage) {
+ return
+ }
+
+ if (entry?.isIntersecting) {
+ fetchNextPage()
+ }
+ }, [entry?.isIntersecting, fetchNextPage, isFetchingNextPage])
+
+ const isEmpty = data?.pages[0].data.cardList.length === 0
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+ >
+ )
+}
+export default MyCardListContent
diff --git a/src/app/(root)/(routes)/mypage/mycards/components/my-card-list-content/index.tsx b/src/app/(root)/(routes)/mypage/mycards/components/my-card-list-content/index.tsx
new file mode 100644
index 00000000..1489b118
--- /dev/null
+++ b/src/app/(root)/(routes)/mypage/mycards/components/my-card-list-content/index.tsx
@@ -0,0 +1,3 @@
+import MyCardListContent from './MyCardListContent'
+
+export default MyCardListContent
diff --git a/src/app/(root)/(routes)/mypage/mycards/components/my-card-list/MyCardList.tsx b/src/app/(root)/(routes)/mypage/mycards/components/my-card-list/MyCardList.tsx
index 21a69a2c..c82e950d 100644
--- a/src/app/(root)/(routes)/mypage/mycards/components/my-card-list/MyCardList.tsx
+++ b/src/app/(root)/(routes)/mypage/mycards/components/my-card-list/MyCardList.tsx
@@ -1,69 +1,23 @@
-'use client'
-
-import { useEffect, useRef, Fragment, useState } from 'react'
-import ExceptionBoundary from '@/components/domain/exception-boundary'
-import MaxWidthWrapper from '@/components/domain/max-width-wrapper'
-import { useMyCardsQuery } from '@/hooks/api/queries/useMyCardsQuery'
-import { useIntersectionObserver } from '@/hooks/useIntersectionObserver'
+import { Fragment } from 'react'
+import { InfiniteData } from '@tanstack/react-query'
+import { GetMyCardListRes } from '@/services/card/card'
import { Card } from '@/types/card'
-import { TradeStatus } from '@/types/card'
import MyCard from '../my-card'
-import TradeStatusTabs from '../trade-status-tabs'
-
-const MyCardList = () => {
- const [tradeStatus, setTradeStatus] = useState('TRADE_AVAILABLE')
-
- const { data, fetchNextPage, isLoading, isError, isFetchingNextPage } =
- useMyCardsQuery({
- tradeStatus,
- })
-
- const lastElementRef = useRef(null)
- const entry = useIntersectionObserver(lastElementRef, { threshold: 1.0 })
-
- useEffect(() => {
- if (isFetchingNextPage) {
- return
- }
-
- if (entry?.isIntersecting) {
- fetchNextPage()
- }
- }, [entry?.isIntersecting, fetchNextPage, isFetchingNextPage])
-
- const isEmpty = data?.pages[0].length === 0
-
- return (
-
-
-
-
-
-
- <>
- {data?.pages.map((currentPage, pageIndex) => (
-
- {currentPage.map((card: Card) => (
-
- ))}
-
- ))}
- >
-
- {/*TODO: 로딩 부분에 대한 처리 논의 후 구체적으로 적용 할 것 => 를 사용할지, isLoading으로 처리할지 논의 */}
-
+const MyCardList = ({
+ data,
+}: {
+ data: InfiniteData | undefined
+}) => (
+ <>
+ {data?.pages.map(({ data: { cardList } }: GetMyCardListRes, pageIndex) => (
+
+ {cardList.map((myCard: Card) => (
+
+ ))}
+
+ ))}
+ >
+)
-
-
- )
-}
export default MyCardList
diff --git a/src/app/(root)/(routes)/mypage/mycards/components/my-card/MyCard.tsx b/src/app/(root)/(routes)/mypage/mycards/components/my-card/MyCard.tsx
index ea4a164c..245b4169 100644
--- a/src/app/(root)/(routes)/mypage/mycards/components/my-card/MyCard.tsx
+++ b/src/app/(root)/(routes)/mypage/mycards/components/my-card/MyCard.tsx
@@ -18,7 +18,7 @@ const MoveToItemListPageButton = ({ priceRange }: { priceRange: string }) => (
)
const MoveToSuggestCheckPageButton = ({ cardId }: { cardId: number }) => (
-
+
{' '}
제안 확인
diff --git a/src/app/(root)/(routes)/mypage/mycards/page.tsx b/src/app/(root)/(routes)/mypage/mycards/page.tsx
index 8cd658ab..601d8a01 100644
--- a/src/app/(root)/(routes)/mypage/mycards/page.tsx
+++ b/src/app/(root)/(routes)/mypage/mycards/page.tsx
@@ -1,15 +1,16 @@
import { FunctionComponent } from 'react'
+import MaxWidthWrapper from '@/components/domain/max-width-wrapper'
import PageTitle from '@/components/domain/page-title'
-import MyCardList from './components/my-card-list'
+import MyCardListContent from './components/my-card-list-content'
interface MyCardListPageProps {}
const MyCardListPage: FunctionComponent = ({}) => {
return (
-
+
+
)
}
diff --git a/src/app/(root)/(routes)/mypage/page.tsx b/src/app/(root)/(routes)/mypage/page.tsx
index cc1cf823..72d67381 100644
--- a/src/app/(root)/(routes)/mypage/page.tsx
+++ b/src/app/(root)/(routes)/mypage/page.tsx
@@ -1,14 +1,31 @@
import React from 'react'
+import PageTitle from '@/components/domain/page-title'
+import ApiEndPoint from '@/config/apiEndPoint'
+import apiClient from '@/services/apiClient'
+import { User } from '@/types/user'
+import { getServerCookie } from '@/utils/getServerCookie'
import UserInfo from './components/UserInfo'
-const MyPage = () => {
+const getUserInfo = async (): Promise => {
+ const token = getServerCookie()
+ const res = await apiClient.get(
+ ApiEndPoint.getValidateUser(),
+ {},
+ {
+ Authorization: `${token}`,
+ },
+ )
+ return res.data.userInfo
+}
+
+const MyPage = async () => {
+ const userInfo = await getUserInfo()
+
return (
-
+
{/* TODO: 각 내용에 대한 라우팅 추가 */}
diff --git a/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-card-description-section/MyCardDescriptionSection.tsx b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-card-description-section/MyCardDescriptionSection.tsx
new file mode 100644
index 00000000..5fff3a7d
--- /dev/null
+++ b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-card-description-section/MyCardDescriptionSection.tsx
@@ -0,0 +1,70 @@
+import formatDistanceToNow from 'date-fns/formatDistanceToNow'
+import koLocale from 'date-fns/locale/ko'
+import Link from 'next/link'
+import Badge from '@/components/ui/badge'
+import { CardFlex, CardImage, CardText } from '@/components/ui/card'
+import AppPath from '@/config/appPath'
+import { CardDetail } from '@/types/card'
+
+const TradeAvailableBadge = () => 거래가능
+const ReservedBadge = () => 예약중
+
+type MyCardDescriptionSection = {
+ card: CardDetail
+}
+
+const MyCardDescriptionSection = ({
+ card: {
+ cardId,
+ thumbnail,
+ cardTitle,
+ status,
+ itemName,
+ priceRange,
+ createdAt,
+ },
+}: MyCardDescriptionSection) => (
+
+
+
+
+
+
+
+
+
+ {cardTitle}
+ {status === 'TRADE_AVAILABLE' ? (
+
+ ) : (
+
+ )}
+
+ {itemName}
+ {priceRange}
+
+ {formatDistanceToNow(new Date(createdAt), { locale: koLocale })}
+
+
+
+
+
+)
+
+export default MyCardDescriptionSection
diff --git a/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-card-description-section/index.tsx b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-card-description-section/index.tsx
new file mode 100644
index 00000000..01b4021d
--- /dev/null
+++ b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-card-description-section/index.tsx
@@ -0,0 +1,3 @@
+import MyCardDescriptionSection from './MyCardDescriptionSection'
+
+export default MyCardDescriptionSection
diff --git a/src/app/(root)/(routes)/mypage/suggestions/components/my-suggestion-card/MySuggestionCard.tsx b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-card/MySuggestionCard.tsx
similarity index 71%
rename from src/app/(root)/(routes)/mypage/suggestions/components/my-suggestion-card/MySuggestionCard.tsx
rename to src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-card/MySuggestionCard.tsx
index 6ad59098..a1427af3 100644
--- a/src/app/(root)/(routes)/mypage/suggestions/components/my-suggestion-card/MySuggestionCard.tsx
+++ b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-card/MySuggestionCard.tsx
@@ -1,26 +1,22 @@
import { formatDistanceToNow } from 'date-fns'
import koLocale from 'date-fns/locale/ko'
import Image from 'next/image'
-import { useSearchParams } from 'next/navigation'
+import { useParams } from 'next/navigation'
import Button from '@/components/ui/button'
import { CardFlex, CardText, Card, CardImage } from '@/components/ui/card/Card'
import Assets from '@/config/assets'
import { useMySuggestionUpdateMutation } from '@/hooks/api/mutations/useMySuggestionUpdateMutation'
-import { MySuggestionRes } from '@/services/suggestion/suggestion'
-import {
- DirectionType,
- SuggestionStatus,
- SuggestionType,
-} from '@/types/suggestion'
+import { Card as CardInfo } from '@/types/card'
+import { DirectionType, Suggestion, SuggestionType } from '@/types/suggestion'
const SuggestionButtons = ({
handleMySuggestionUpdate,
}: {
- handleMySuggestionUpdate: (suggestionStatus: SuggestionStatus) => void
+ handleMySuggestionUpdate: (isAccepted: boolean) => void
}) => (
<>
handleMySuggestionUpdate('ACCEPTED')}
+ onClick={() => handleMySuggestionUpdate(true)}
className="cursor-pointer"
align={'center'}
gap={'space'}
@@ -29,7 +25,7 @@ const SuggestionButtons = ({
수락
handleMySuggestionUpdate('REFUSED')}
+ onClick={() => handleMySuggestionUpdate(false)}
className="cursor-pointer"
align={'center'}
gap={'space'}
@@ -59,37 +55,35 @@ const WaitingButton = () => {
)
}
-type SuggestCheckCardProps = {
- mySuggestionListResponseData: MySuggestionRes & { pageInfo: number }
+type MySuggestionCardProps = {
+ mySuggestion: {
+ suggestionInfo: Suggestion
+ cardInfo: CardInfo
+ }
suggestionTypeState: SuggestionType
directionTypeState: DirectionType
}
const MySuggestionCard = ({
- mySuggestionListResponseData: {
- suggestionInfo: {
- suggestionId,
- suggestionStatus,
- directionType,
- createdAt,
- },
- cardInfo: { cardTitle, itemName, priceRange, thumbnail },
- pageInfo,
+ mySuggestion: {
+ suggestionInfo: { suggestionStatus, directionType, createdAt },
+ cardInfo: { cardId, cardTitle, itemName, priceRange, thumbnail },
},
suggestionTypeState,
directionTypeState,
-}: SuggestCheckCardProps) => {
- const searchParams = useSearchParams()
+}: MySuggestionCardProps) => {
+ const { myCardId } = useParams()
const { mutate } = useMySuggestionUpdateMutation(
suggestionTypeState,
directionTypeState,
- searchParams.get('cardId'),
+ myCardId,
)
- const handleMySuggestionUpdate = (
- suggestionId: string,
- suggestionStatus: SuggestionStatus,
- ) => {
- mutate({ suggestionId, suggestionStatus, currentPage: pageInfo })
+ const handleMySuggestionUpdate = (cardId: number, isAccepted: boolean) => {
+ mutate({
+ fromCardId: cardId,
+ toCardId: myCardId,
+ isAccepted,
+ })
}
return (
@@ -120,10 +114,8 @@ const MySuggestionCard = ({
{suggestionStatus === 'WAITING' ? (
directionType === 'RECEIVE' ? (
- handleMySuggestionUpdate(suggestionId, suggestionStatus)
+ handleMySuggestionUpdate={(isAccepted: boolean) =>
+ handleMySuggestionUpdate(cardId, isAccepted)
}
/>
) : (
diff --git a/src/app/(root)/(routes)/mypage/suggestions/components/my-suggestion-card/index.tsx b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-card/index.tsx
similarity index 100%
rename from src/app/(root)/(routes)/mypage/suggestions/components/my-suggestion-card/index.tsx
rename to src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-card/index.tsx
diff --git a/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-list-content/MySuggestionListContent.tsx b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-list-content/MySuggestionListContent.tsx
new file mode 100644
index 00000000..aa4f7a38
--- /dev/null
+++ b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-list-content/MySuggestionListContent.tsx
@@ -0,0 +1,63 @@
+'use client'
+
+import { useEffect, useRef, useState } from 'react'
+import { useParams } from 'next/navigation'
+import ExceptionBoundary from '@/components/domain/exception-boundary'
+import { useMySuggestionsQuery } from '@/hooks/api/queries/useMySuggestionsQuery'
+import { useIntersectionObserver } from '@/hooks/useIntersectionObserver'
+import { DirectionType, SuggestionType } from '@/types/suggestion'
+import MySuggestionList from '../my-suggestion-list/MySuggestionList'
+import SuggestionStatusTabs from '../suggestion-status-tabs'
+
+const MySuggestionListContent = () => {
+ const [suggestionTypeState, setSuggestionTypeState] =
+ useState('OFFER')
+ const [directionTypeState, setDirectionTypeState] =
+ useState('RECEIVE')
+ const { myCardId } = useParams()
+
+ const { data, fetchNextPage, isLoading, isError, isFetchingNextPage } =
+ useMySuggestionsQuery(suggestionTypeState, directionTypeState, myCardId)
+
+ const lastElementRef = useRef(null)
+ const entry = useIntersectionObserver(lastElementRef, { threshold: 1.0 })
+
+ useEffect(() => {
+ if (isFetchingNextPage) {
+ return
+ }
+
+ if (entry?.isIntersecting) {
+ fetchNextPage()
+ }
+ }, [entry?.isIntersecting, fetchNextPage, isFetchingNextPage])
+
+ const isEmpty = data?.pages[0].data.suggestionList.length === 0
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+ >
+ )
+}
+export default MySuggestionListContent
diff --git a/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-list-content/index.tsx b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-list-content/index.tsx
new file mode 100644
index 00000000..3395bec3
--- /dev/null
+++ b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-list-content/index.tsx
@@ -0,0 +1,3 @@
+import MySuggestionListContent from './MySuggestionListContent'
+
+export default MySuggestionListContent
diff --git a/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-list/MySuggestionList.tsx b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-list/MySuggestionList.tsx
new file mode 100644
index 00000000..0821787d
--- /dev/null
+++ b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-list/MySuggestionList.tsx
@@ -0,0 +1,37 @@
+import { Fragment } from 'react'
+import { InfiniteData } from '@tanstack/react-query'
+import { GetMySuggestionListRes } from '@/services/suggestion/suggestion'
+import { Card } from '@/types/card'
+import { DirectionType, Suggestion, SuggestionType } from '@/types/suggestion'
+import MySuggestionCard from '../my-suggestion-card'
+
+const MySuggestionList = ({
+ data,
+ suggestionTypeState,
+ directionTypeState,
+}: {
+ data: InfiniteData | undefined
+ suggestionTypeState: SuggestionType
+ directionTypeState: DirectionType
+}) => (
+ <>
+ {data?.pages.map(
+ ({ data: { suggestionList } }: GetMySuggestionListRes, pageIndex) => (
+
+ {suggestionList.map(
+ (mySuggestion: { cardInfo: Card; suggestionInfo: Suggestion }) => (
+
+ ),
+ )}
+
+ ),
+ )}
+ >
+)
+
+export default MySuggestionList
diff --git a/src/app/(root)/(routes)/mypage/suggestions/components/my-suggestion-list/index.tsx b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-list/index.tsx
similarity index 100%
rename from src/app/(root)/(routes)/mypage/suggestions/components/my-suggestion-list/index.tsx
rename to src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/my-suggestion-list/index.tsx
diff --git a/src/app/(root)/(routes)/mypage/suggestions/components/suggestion-status-tabs/SuggestionStatusTabs.tsx b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/suggestion-status-tabs/SuggestionStatusTabs.tsx
similarity index 100%
rename from src/app/(root)/(routes)/mypage/suggestions/components/suggestion-status-tabs/SuggestionStatusTabs.tsx
rename to src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/suggestion-status-tabs/SuggestionStatusTabs.tsx
diff --git a/src/app/(root)/(routes)/mypage/suggestions/components/suggestion-status-tabs/index.tsx b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/suggestion-status-tabs/index.tsx
similarity index 100%
rename from src/app/(root)/(routes)/mypage/suggestions/components/suggestion-status-tabs/index.tsx
rename to src/app/(root)/(routes)/mypage/suggestions/[myCardId]/components/suggestion-status-tabs/index.tsx
diff --git a/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/page.tsx b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/page.tsx
new file mode 100644
index 00000000..6b229fa7
--- /dev/null
+++ b/src/app/(root)/(routes)/mypage/suggestions/[myCardId]/page.tsx
@@ -0,0 +1,33 @@
+import MaxWidthWrapper from '@/components/domain/max-width-wrapper'
+import PageTitle from '@/components/domain/page-title'
+import { getCardInfo } from '@/services/card/card'
+import { CardDetail } from '@/types/card'
+import MyCardDescriptionSection from './components/my-card-description-section'
+import MySuggestionListContent from './components/my-suggestion-list-content'
+
+async function getMyCardInfo(cardId: string) {
+ try {
+ const res = await getCardInfo(Number(cardId))
+ return res.data.cardInfo
+ } catch (e) {
+ console.log(e)
+ }
+}
+
+const SuggestCheckListPage = async ({
+ params: { myCardId },
+}: {
+ params: { myCardId: string }
+}) => {
+ const myCard = await getMyCardInfo(myCardId)
+
+ return (
+
+
+
+
+
+ )
+}
+
+export default SuggestCheckListPage
diff --git a/src/app/(root)/(routes)/mypage/suggestions/components/my-suggestion-list/MySuggestionList.tsx b/src/app/(root)/(routes)/mypage/suggestions/components/my-suggestion-list/MySuggestionList.tsx
deleted file mode 100644
index fe6b9bbd..00000000
--- a/src/app/(root)/(routes)/mypage/suggestions/components/my-suggestion-list/MySuggestionList.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-'use client'
-
-import { useEffect, useRef, Fragment, useState } from 'react'
-import { useSearchParams } from 'next/navigation'
-import ExceptionBoundary from '@/components/domain/exception-boundary'
-import MaxWidthWrapper from '@/components/domain/max-width-wrapper'
-import { useMySuggestionsQuery } from '@/hooks/api/queries/useMySuggestionsQuery'
-import { useIntersectionObserver } from '@/hooks/useIntersectionObserver'
-import { MySuggestionRes } from '@/services/suggestion/suggestion'
-import { DirectionType, SuggestionType } from '@/types/suggestion'
-import MySuggestionCard from '../my-suggestion-card'
-import SuggestionStatusTabs from '../suggestion-status-tabs'
-
-const MySuggestionList = () => {
- const [suggestionTypeState, setSuggestionTypeState] =
- useState('OFFER')
- const [directionTypeState, setDirectionTypeState] =
- useState('RECEIVE')
- const searchParams = useSearchParams()
-
- const { data, fetchNextPage, isLoading, isError, isFetchingNextPage } =
- useMySuggestionsQuery(
- suggestionTypeState,
- directionTypeState,
- searchParams.get('cardId'),
- )
-
- const lastElementRef = useRef(null)
- const entry = useIntersectionObserver(lastElementRef, { threshold: 1.0 })
-
- useEffect(() => {
- if (isFetchingNextPage) {
- return
- }
-
- if (entry?.isIntersecting) {
- fetchNextPage()
- }
- }, [entry?.isIntersecting, fetchNextPage, isFetchingNextPage])
-
- const isEmpty = data?.pages[0].length === 0
-
- return (
-
-
-
-
-
-
- <>
- {data?.pages.map((currentPage, pageIndex) => (
-
- {currentPage.map(
- (
- mySuggestionListResponseData: MySuggestionRes & {
- pageInfo: number
- },
- ) => (
-
- ),
- )}
-
- ))}
- >
-
-
-
-
-
- )
-}
-export default MySuggestionList
diff --git a/src/app/(root)/(routes)/mypage/suggestions/page.tsx b/src/app/(root)/(routes)/mypage/suggestions/page.tsx
deleted file mode 100644
index 96ca2a5b..00000000
--- a/src/app/(root)/(routes)/mypage/suggestions/page.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { FunctionComponent } from 'react'
-import PageTitle from '@/components/domain/page-title'
-import { getCardInfo } from '@/services/card/card'
-// import MyItemSummaryCard from './components/my-item-summary-card'
-import MySuggestionList from './components/my-suggestion-list'
-
-interface SuggestCheckListPageProps {
- params: {
- itemId: string
- }
-}
-
-async function getItemValue(cardId: number) {
- try {
- const res = await getCardInfo(cardId)
- const data = await res
- data.data.cardInfo.thumbnail =
- 'https://cdn.cetizen.com/CDN/market/market_large_crop/202203/20220318/220318152808_1_2913635.jpg'
- data.data.cardInfo.createdAt = '2023-11-01T08:08:00'
- return data.data.cardInfo
- } catch (e) {
- console.log(e)
- }
-}
-
-const SuggestCheckListPage: FunctionComponent<
- SuggestCheckListPageProps
-> = async ({ params }: SuggestCheckListPageProps) => {
- const data = await getItemValue(3)
-
- return (
-
-
- {/*
*/}
- {JSON.stringify(data)}
-
-
- )
-}
-
-export default SuggestCheckListPage
diff --git a/src/components/domain/header/Header.tsx b/src/components/domain/header/Header.tsx
index 546da759..0606a4bd 100644
--- a/src/components/domain/header/Header.tsx
+++ b/src/components/domain/header/Header.tsx
@@ -8,14 +8,10 @@ import AppPath from '@/config/appPath'
import Assets from '@/config/assets'
import { useAuth } from '@/contexts/AuthProvider'
import Logo from '../logo'
-import { MenuButton, Avatar } from './components/Avatar'
-
-// type HeaderProps = {
-// isLogin?: boolean
-// }
+import { MenuButton, AvatarWithDropdown } from './components'
const Header = () => {
- const { isLoggedIn } = useAuth()
+ const { isLoggedIn, currentUser } = useAuth()
return (
@@ -31,7 +27,7 @@ const Header = () => {
{/** TODO: 알림 컴포넌트로 변경 */}
-
+
{/** TODO: 아바타 컴포넌트로 변경 */}
>
) : (
diff --git a/src/components/domain/header/components/Avatar.tsx b/src/components/domain/header/components/AvatarWithDropdown.tsx
similarity index 54%
rename from src/components/domain/header/components/Avatar.tsx
rename to src/components/domain/header/components/AvatarWithDropdown.tsx
index 3cb6f895..fcad532c 100644
--- a/src/components/domain/header/components/Avatar.tsx
+++ b/src/components/domain/header/components/AvatarWithDropdown.tsx
@@ -1,6 +1,6 @@
import Cookies from 'js-cookie'
-import Image from 'next/image'
-import Link from 'next/link'
+import { useRouter } from 'next/navigation'
+import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'
import Button from '@/components/ui/button'
import {
DropdownMenu,
@@ -10,32 +10,13 @@ import {
DropdownMenuItem,
} from '@/components/ui/dropdown-menu'
import AppPath from '@/config/appPath'
-import Assets from '@/config/assets'
import { Environment } from '@/config/environment'
+import { DEFAULT_PROFILE_IMG } from '@/constants/image'
import apiClient from '@/services/apiClient'
-//TODO: 공용 아바타 컴포넌트로 변경
+const AvatarWithDropdown = ({ imageUrl }: { imageUrl?: string }) => {
+ const router = useRouter()
-const MenuButton = () => {
- return (
-
-
-
-
-
-
-
-
-
- 홈으로
-
-
-
-
- )
-}
-
-const Avatar = () => {
const onClickLogout = () => {
Cookies.remove(Environment.tokenName())
apiClient.setDefaultHeader('Authorization', '')
@@ -45,10 +26,22 @@ const Avatar = () => {
return (
- 아바타
+
+
+
+ profile
+
+
+ {
+ router.push(AppPath.mypage())
+ }}
+ >
+ 내 정보
+
로그아웃
@@ -56,4 +49,4 @@ const Avatar = () => {
)
}
-export { MenuButton, Avatar }
+export default AvatarWithDropdown
diff --git a/src/components/domain/header/components/MenuButton.tsx b/src/components/domain/header/components/MenuButton.tsx
new file mode 100644
index 00000000..eb173b80
--- /dev/null
+++ b/src/components/domain/header/components/MenuButton.tsx
@@ -0,0 +1,33 @@
+import Image from 'next/image'
+import Link from 'next/link'
+import Button from '@/components/ui/button'
+import {
+ DropdownMenu,
+ DropdownMenuTrigger,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+} from '@/components/ui/dropdown-menu'
+import AppPath from '@/config/appPath'
+import Assets from '@/config/assets'
+
+const MenuButton = () => {
+ return (
+
+
+
+
+
+
+
+
+
+ 홈으로
+
+
+
+
+ )
+}
+
+export default MenuButton
diff --git a/src/components/domain/header/components/index.tsx b/src/components/domain/header/components/index.tsx
new file mode 100644
index 00000000..350a14be
--- /dev/null
+++ b/src/components/domain/header/components/index.tsx
@@ -0,0 +1,4 @@
+import AvatarWithDropdown from './AvatarWithDropdown'
+import MenuButton from './MenuButton'
+
+export { AvatarWithDropdown, MenuButton }
diff --git a/src/components/domain/image-uploader/ImageUploader.tsx b/src/components/domain/image-uploader/ImageUploader.tsx
index 5c0434d0..027f0ae4 100644
--- a/src/components/domain/image-uploader/ImageUploader.tsx
+++ b/src/components/domain/image-uploader/ImageUploader.tsx
@@ -86,7 +86,9 @@ const ImageUploader = ({
isDeletable={isImageDeletable}
isThumbnail={isThumbnail}
onDeleteHandler={() => {
+ console.log(images)
setImages(images.filter((_, i) => i !== index))
+ onFilesChanged(images.filter((_, i) => i !== index))
}}
/>
)
diff --git a/src/components/domain/max-width-wrapper/MaxWidthWrapper.tsx b/src/components/domain/max-width-wrapper/MaxWidthWrapper.tsx
index e6218920..57f82256 100644
--- a/src/components/domain/max-width-wrapper/MaxWidthWrapper.tsx
+++ b/src/components/domain/max-width-wrapper/MaxWidthWrapper.tsx
@@ -1,5 +1,9 @@
-const MaxWidthWrapper = ({ children }: { children: JSX.Element[] }) => {
- return {children}
+const MaxWidthWrapper = ({
+ children,
+}: {
+ children: JSX.Element[] | JSX.Element
+}) => {
+ return {children}
}
export default MaxWidthWrapper
diff --git a/src/components/domain/text-editable/TextEditable.tsx b/src/components/domain/text-editable/TextEditable.tsx
index e132f92e..4922e0d9 100644
--- a/src/components/domain/text-editable/TextEditable.tsx
+++ b/src/components/domain/text-editable/TextEditable.tsx
@@ -22,6 +22,7 @@ const TextEditable = ({
const [value, setValue] = useState(defaultText)
useEffect(() => {
+ console.log('이름', defaultText)
if (!changedSuccessfully) {
setValue(() => defaultText)
}
diff --git a/src/components/ui/card/Card.tsx b/src/components/ui/card/Card.tsx
index 70f5e840..e81c5a49 100644
--- a/src/components/ui/card/Card.tsx
+++ b/src/components/ui/card/Card.tsx
@@ -1,7 +1,6 @@
import * as React from 'react'
import { cva, type VariantProps } from 'class-variance-authority'
import Image from 'next/image'
-import COLORS from '@/styles/colors'
import { TYPOGRAPHY } from '@/styles/sizes'
import { cn } from '@/utils'
diff --git a/src/config/apiEndPoint.ts b/src/config/apiEndPoint.ts
index a7fcdf90..ea4751b3 100644
--- a/src/config/apiEndPoint.ts
+++ b/src/config/apiEndPoint.ts
@@ -1,32 +1,61 @@
-import { TradeStatus } from '@/types/card'
-import { DirectionType, SuggestionType } from '@/types/suggestion'
+import { GetCardListReq, GetMyCardListReq } from '@/services/card/card'
+import { GetMyTradeHistoryListReq } from '@/services/history/history'
+import { GetMySuggestionListReq } from '@/services/suggestion/suggestion'
+import { getQueryParams } from '@/utils/getQueryParams'
const ApiEndPoint = {
getValidateUser: () => '/users',
test: () => '/test',
getCardInfo: (cardId: number) => `/cards/${cardId}`,
deleteCard: (cardId: number) => `/cards/${cardId}`,
- getCardList: (cursorId: number) =>
- `/cards/?category&priceRange&cardTitle&cursorId=${cursorId}&status&size`, // TODO: category,priceRange,cardTitle,status,size 적용
- getMyCardList: (status: TradeStatus, cursorId: number) =>
- `/cards/${status}/my-cards?&size&cursorId=${cursorId}`, // TODO: status 적용
+ getCardList: ({
+ category,
+ priceRange,
+ cardTitle,
+ cursorId,
+ }: GetCardListReq) =>
+ `/cards/?${getQueryParams({
+ category,
+ priceRange,
+ cardTitle,
+ cursorId,
+ status: 'TRADE_AVAILABLE,RESERVED',
+ size: '5',
+ })}`,
+ getMyCardList: ({ tradeStatus, cursorId }: GetMyCardListReq) => {
+ return `/cards/${tradeStatus}/my-cards?${getQueryParams({
+ cursorId,
+ size: '5',
+ })}`
+ },
postDibs: (cardId: number) => `/dibs/${cardId}`,
deleteDibs: (cardId: number) => `/dibs/${cardId}`,
getAvailableCardSuggestionList: (cardId: number) =>
- `/cards/${cardId}/available-cards`,
- getMySuggestionList: (
- directionType: DirectionType,
- suggestionType: SuggestionType,
- cardId: string | null,
- cursorId: number,
- ) =>
- `/suggestions/${directionType}/${suggestionType}/${cardId}/?&size={}&cursorId=${cursorId}`, //TODO: 변수 적용
+ `cards/${cardId}/available-cards`,
+ getMySuggestionList: ({
+ directionType,
+ suggestionType,
+ cardId,
+ cursorId,
+ }: GetMySuggestionListReq) => {
+ return `/suggestions/${directionType}/${suggestionType}/${cardId}/?${getQueryParams(
+ {
+ cursorId,
+ size: '5',
+ },
+ )}`
+ },
+
putUserProfile: () => '/users/profile-image',
putUserNickname: () => '/users/nickname',
postSuggestion: (suggestionType: string) => `/suggestions/${suggestionType}`,
getMyDibsList: (cursorId: number) => `/dibs/?cursorId=${cursorId}`,
- getMyTradeHistoryList: (cursorId: number) =>
- `/complete-requests/user/?size&cursorId=${cursorId}`,
+ getMyTradeHistoryList: ({ cursorId }: GetMyTradeHistoryListReq) => {
+ return `/complete-requests/user/?${getQueryParams({
+ cursorId,
+ size: '5',
+ })}`
+ },
postImageFile: () => '/s3/upload/single',
postCard: () => '/cards',
putCard: (cardId: string) => `/cards/${cardId}`,
@@ -37,6 +66,7 @@ const ApiEndPoint = {
getRecentTradeHistoryList: (size: number) =>
`/complete-requests/?size=${size}`,
getPopularCardList: () => '/cards/popular',
+ putMySuggestionStatus: () => `/suggestions/decision`,
} as const
export default ApiEndPoint
diff --git a/src/config/appPath.ts b/src/config/appPath.ts
index a5c60269..cd258658 100644
--- a/src/config/appPath.ts
+++ b/src/config/appPath.ts
@@ -8,8 +8,8 @@ const AppPath = {
newCard: () => '/cards/new' as const,
cardDetail: (cardId: string) => `/cards/${cardId}` as const,
mypage: () => '/mypage' as const,
- myItems: () => '/mypage/my-items' as const,
- suggestChecks: () => '/mypage/suggest-checks' as const,
+ myCards: () => '/mypage/mycards' as const,
+ mySuggestions: () => '/mypage/suggestions' as const,
kakaoLogin: () =>
`${Environment.apiAddress()}/users/oauth2/authorize/kakao/login` as const,
googleLogin: () =>
diff --git a/src/hooks/api/mutations/useMySuggestionUpdateMutation.ts b/src/hooks/api/mutations/useMySuggestionUpdateMutation.ts
index 472a53ce..208153ff 100644
--- a/src/hooks/api/mutations/useMySuggestionUpdateMutation.ts
+++ b/src/hooks/api/mutations/useMySuggestionUpdateMutation.ts
@@ -1,59 +1,53 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
-import { MySuggestionRes } from '@/services/suggestion/suggestion'
import {
- DirectionType,
- SuggestionStatus,
- SuggestionType,
-} from '@/types/suggestion'
+ PutMySuggestionStatusReq,
+ putMySuggestionStatus,
+} from '@/services/suggestion/suggestion'
+import { DirectionType, SuggestionType } from '@/types/suggestion'
export const useMySuggestionUpdateMutation = (
suggestionType: SuggestionType,
directionType: DirectionType,
- cardId: string | null,
+ cardId: string | string[],
) => {
const queryClient = useQueryClient()
return useMutation({
- onMutate: async ({
- suggestionId,
- suggestionStatus,
- currentPage,
- }: {
- suggestionId: string
- suggestionStatus: SuggestionStatus
- currentPage: number
- }) => {
- await queryClient.cancelQueries({
+ mutationFn: async ({
+ fromCardId,
+ toCardId,
+ isAccepted,
+ }: PutMySuggestionStatusReq) => {
+ await putMySuggestionStatus({ fromCardId, toCardId, isAccepted })
+ },
+ onMutate: async (variables: any) => {
+ console.log('onMutate', variables)
+ // const oldMySuggestionList = queryClient.getQueryData([
+ // 'my-suggestions',
+ // suggestionType,
+ // directionType,
+ // myCardId,
+ // ])
+ // console.log(oldMySuggestionList)
+ // },
+ // onError: (error, variable, rollback) => {
+ // if (rollback) rollback()
+ // else console.log(error)
+ // },
+ // onSettled: () => {
+ // queryClient.invalidateQueries([
+ // 'my-suggestions',
+ // suggestionType,
+ // directionType,
+ // cardId,
+ // ])
+ // },
+ // TODO : 에러처리 및 각 종 Optimistic Update 관련 기능 처리하기
+ },
+
+ onSettled: () => {
+ queryClient.invalidateQueries({
queryKey: ['my-suggestions', suggestionType, directionType, cardId],
})
- console.log(
- suggestionType,
- directionType,
- cardId,
- suggestionId,
- currentPage,
- )
- const oldMySuggestionList = queryClient.getQueryData([
- 'my-suggestions',
- suggestionType,
- directionType,
- cardId,
- ])
-
- const newMySuggestionList: any = structuredClone(oldMySuggestionList)
- const currentPageMySuggstionList = newMySuggestionList.pages[currentPage]
- const currentMySuggestionList = currentPageMySuggstionList.find(
- (mySuggestion: MySuggestionRes) =>
- mySuggestion.suggestionInfo.suggestionId === suggestionId,
- )
- currentMySuggestionList.suggestionInfo.suggestionStatus = suggestionStatus
- console.log(newMySuggestionList)
-
- queryClient.setQueryData(
- ['my-suggestions', suggestionType, directionType, cardId],
- newMySuggestionList,
- )
- return { oldMySuggestionList, newMySuggestionList }
},
- // TODO : 에러처리 및 각 종 Optimistic Update 관련 기능 처리하기
})
}
diff --git a/src/hooks/api/queries/useCardsQuery.ts b/src/hooks/api/queries/useCardsQuery.ts
index b2a5db76..3096c9e9 100644
--- a/src/hooks/api/queries/useCardsQuery.ts
+++ b/src/hooks/api/queries/useCardsQuery.ts
@@ -1,10 +1,10 @@
import { useInfiniteQuery } from '@tanstack/react-query'
-import { getCardList } from '@/services/card/card'
-import { Category, PriceRange } from '@/types/card'
+import { GetCardListRes, getCardList } from '@/services/card/card'
+import { CategoryObjs, PriceRangeObjs } from '@/types/card'
export type UseCardsQueryParams = {
- category: Category
- priceRange: PriceRange
+ category: CategoryObjs['key']
+ priceRange: PriceRangeObjs['key']
cardTitle: string
}
@@ -16,19 +16,16 @@ export const useCardsQuery = ({
return useInfiniteQuery({
queryKey: ['cards', category, priceRange, cardTitle],
- queryFn: async ({ pageParam = 0 }) =>
+ queryFn: async ({ pageParam = undefined }) =>
await getCardList({
category,
priceRange,
cardTitle,
cursorId: pageParam,
}),
- initialPageParam: 0,
- getNextPageParam: (lastPage, allPages, lastPageParam) => {
- if (lastPage.length === 0) {
- return undefined
- }
- return lastPageParam + 1
+ initialPageParam: undefined,
+ getNextPageParam: (lastPage: GetCardListRes) => {
+ return lastPage.data.nextCursorId
},
})
}
diff --git a/src/hooks/api/queries/useMyCardsQuery.ts b/src/hooks/api/queries/useMyCardsQuery.ts
index bb88118f..7095462d 100644
--- a/src/hooks/api/queries/useMyCardsQuery.ts
+++ b/src/hooks/api/queries/useMyCardsQuery.ts
@@ -1,5 +1,5 @@
import { useInfiniteQuery } from '@tanstack/react-query'
-import { getMyCardList } from '@/services/card/card'
+import { GetMyCardListRes, getMyCardList } from '@/services/card/card'
import { TradeStatus } from '@/types/card'
export type UseMyCardsQueryParams = {
@@ -9,17 +9,14 @@ export type UseMyCardsQueryParams = {
export const useMyCardsQuery = ({ tradeStatus }: UseMyCardsQueryParams) => {
return useInfiniteQuery({
queryKey: ['my-cards', tradeStatus],
- queryFn: async ({ pageParam = 0 }) =>
+ queryFn: async ({ pageParam = undefined }) =>
await getMyCardList({
tradeStatus,
cursorId: pageParam,
}),
- initialPageParam: 0,
- getNextPageParam: (lastPage, allPages, lastPageParam) => {
- if (lastPage.length === 0) {
- return undefined
- }
- return lastPageParam + 1
+ initialPageParam: undefined,
+ getNextPageParam: (lastPage: GetMyCardListRes) => {
+ return lastPage.data.nextCursorId
},
})
}
diff --git a/src/hooks/api/queries/useMySuggestionsQuery.ts b/src/hooks/api/queries/useMySuggestionsQuery.ts
index 93a42360..97221d85 100644
--- a/src/hooks/api/queries/useMySuggestionsQuery.ts
+++ b/src/hooks/api/queries/useMySuggestionsQuery.ts
@@ -1,39 +1,24 @@
import { useInfiniteQuery } from '@tanstack/react-query'
import { getMySuggestionList } from '@/services/suggestion/suggestion'
-import { MySuggestionRes } from '@/services/suggestion/suggestion'
import { DirectionType, SuggestionType } from '@/types/suggestion'
export const useMySuggestionsQuery = (
suggestionType: SuggestionType,
directionType: DirectionType,
- cardId: string | null,
+ cardId: string | string[],
) => {
return useInfiniteQuery({
queryKey: ['my-suggestions', suggestionType, directionType, cardId],
- queryFn: async ({ pageParam = 0 }) => {
- const data: MySuggestionRes[] = await getMySuggestionList({
+ queryFn: async ({ pageParam = undefined }) =>
+ await getMySuggestionList({
suggestionType,
directionType,
cardId,
cursorId: pageParam,
- })
-
- const dataContainingPageInfo = data.map(
- (mySuggestion: MySuggestionRes) => ({
- ...mySuggestion,
- pageInfo: pageParam,
- }),
- )
-
- return dataContainingPageInfo
- },
-
- initialPageParam: 0,
- getNextPageParam: (lastPage, allPages, lastPageParam) => {
- if (lastPage.length === 0) {
- return undefined
- }
- return lastPageParam + 1
+ }),
+ initialPageParam: undefined,
+ getNextPageParam: (lastPage: any) => {
+ return lastPage.data.nextCursorId
},
})
}
diff --git a/src/hooks/api/queries/useMyTradeHistoriesQuery.ts b/src/hooks/api/queries/useMyTradeHistoriesQuery.ts
index 9a128a53..6232e5e6 100644
--- a/src/hooks/api/queries/useMyTradeHistoriesQuery.ts
+++ b/src/hooks/api/queries/useMyTradeHistoriesQuery.ts
@@ -1,19 +1,19 @@
import { useInfiniteQuery } from '@tanstack/react-query'
-import { getMyTradeHistoryList } from '@/services/history/history'
+import {
+ GetMyTradeHistoryListRes,
+ getMyTradeHistoryList,
+} from '@/services/history/history'
export const useMyTradeHistoryQuery = () => {
return useInfiniteQuery({
queryKey: ['my-trade-histories'],
- queryFn: async ({ pageParam = 0 }) =>
+ queryFn: async ({ pageParam = undefined }) =>
await getMyTradeHistoryList({
cursorId: pageParam,
}),
- initialPageParam: 0,
- getNextPageParam: (lastPage, allPages, lastPageParam) => {
- if (lastPage.length === 0) {
- return undefined
- }
- return lastPageParam + 1
+ initialPageParam: undefined,
+ getNextPageParam: (lastPage: GetMyTradeHistoryListRes) => {
+ return lastPage.data.nextCursorId
},
})
}
diff --git a/src/middleware.ts b/src/middleware.ts
index d6a21c74..d32be041 100644
--- a/src/middleware.ts
+++ b/src/middleware.ts
@@ -37,5 +37,5 @@ export async function middleware(request: NextRequest) {
// See "Matching Paths" below to learn more
export const config = {
- matcher: ['/test-auth-only'],
+ matcher: ['/mypage', '/cards/:path/modify', '/cards/new'],
}
diff --git a/src/services/card/card.ts b/src/services/card/card.ts
index 71e4cc4d..07b7a758 100644
--- a/src/services/card/card.ts
+++ b/src/services/card/card.ts
@@ -1,21 +1,15 @@
import { CardUploadFormValues } from '@/app/(root)/(routes)/cards/new/hooks/useCardUploadForm'
import ApiEndPoint from '@/config/apiEndPoint'
import type {
+ Card,
+ CategoryObjs,
CardDetail,
- Category,
- PriceRange,
TradeStatus,
+ PriceRangeObjs,
} from '@/types/card'
import { User } from '@/types/user'
import apiClient from '../apiClient'
-export type Getcards = {
- category: Category
- priceRange: PriceRange
- cardTitle: string
- cursorId: number
-}
-
type putCardReq = {
cardId: string
cardReq: CardUploadFormValues
@@ -57,14 +51,30 @@ const putCard = async ({ cardId, cardReq }: putCardReq) => {
return response
}
-// TODO: 현재 cardsHandler(가짜 API)는 필터에 대한 처리가 이루어져 있지 않으므로, cursorId만 넘겨주고 있음 => 실 API를 받을시 교체 작업 해주기
+export type GetCardListReq = {
+ category: CategoryObjs['key']
+ priceRange: PriceRangeObjs['key']
+ cardTitle: string
+ cursorId: string | undefined
+}
+export type GetCardListRes = {
+ code: string
+ message: string
+ data: {
+ cardList: Card[]
+ nextCursorId: string
+ }
+}
+
const getCardList = async ({
category,
priceRange,
cardTitle,
cursorId,
-}: Getcards) => {
- const response = await apiClient.get(ApiEndPoint.getCardList(cursorId))
+}: GetCardListReq) => {
+ const response: GetCardListRes = await apiClient.get(
+ ApiEndPoint.getCardList({ category, priceRange, cardTitle, cursorId }),
+ )
return response
}
export type CardInfoRes = {
@@ -73,23 +83,32 @@ export type CardInfoRes = {
data: { cardInfo: CardDetail; userInfo: User }
}
-const getCardInfo = async (cardId: number) => {
- const response: CardInfoRes = await apiClient.get(
- ApiEndPoint.getCardInfo(cardId),
- )
+const getCardInfo = async (
+ cardId: number,
+): Promise<{ data: { cardInfo: CardDetail; userInfo: User } }> => {
+ const response = await apiClient.get(ApiEndPoint.getCardInfo(cardId), {
+ cache: 'no-store',
+ })
+
return response
}
-const getMyCardList = async ({
- tradeStatus,
- cursorId,
-}: {
+export type GetMyCardListReq = {
tradeStatus: TradeStatus
- cursorId: number
-}) => {
- const response = await apiClient.get(
- ApiEndPoint.getMyCardList(tradeStatus, cursorId),
- {},
+ cursorId: string | undefined
+}
+export type GetMyCardListRes = {
+ code: string
+ message: string
+ data: {
+ cardList: Card[]
+ nextCursorId: string
+ }
+}
+
+const getMyCardList = async ({ tradeStatus, cursorId }: GetMyCardListReq) => {
+ const response: GetMyCardListRes = await apiClient.get(
+ ApiEndPoint.getMyCardList({ tradeStatus, cursorId }),
)
return response
}
diff --git a/src/services/history/history.ts b/src/services/history/history.ts
index 1e047297..97381b33 100644
--- a/src/services/history/history.ts
+++ b/src/services/history/history.ts
@@ -2,11 +2,23 @@ import ApiEndPoint from '@/config/apiEndPoint'
import { TradeHistory } from '@/types/tradeHistory'
import apiClient from '../apiClient'
-export type MyHistoryRes = TradeHistory
+export type GetMyTradeHistoryListReq = {
+ cursorId: string | undefined
+}
+export type GetMyTradeHistoryListRes = {
+ code: string
+ message: string
+ data: {
+ historyList: TradeHistory[]
+ nextCursorId: string
+ }
+}
-const getMyTradeHistoryList = async ({ cursorId }: { cursorId: number }) => {
- const response: MyHistoryRes[] = await apiClient.get(
- ApiEndPoint.getMyTradeHistoryList(cursorId),
+const getMyTradeHistoryList = async ({
+ cursorId,
+}: GetMyTradeHistoryListReq) => {
+ const response: GetMyTradeHistoryListRes = await apiClient.get(
+ ApiEndPoint.getMyTradeHistoryList({ cursorId }),
)
return response
}
diff --git a/src/services/suggestion/suggestion.ts b/src/services/suggestion/suggestion.ts
index 942e6d9d..10d39bba 100644
--- a/src/services/suggestion/suggestion.ts
+++ b/src/services/suggestion/suggestion.ts
@@ -40,16 +40,22 @@ const postSuggestion = async ({
return response
}
-type GetSuggestChecksParams = {
+export type GetMySuggestionListReq = {
suggestionType: SuggestionType
directionType: DirectionType
- cardId: string | null
- cursorId: number
+ cardId: string | string[]
+ cursorId: string | undefined
}
-
-export type MySuggestionRes = {
- cardInfo: Card
- suggestionInfo: Suggestion
+export type GetMySuggestionListRes = {
+ code: string
+ message: string
+ data: {
+ suggestionList: {
+ cardInfo: Card
+ suggestionInfo: Suggestion
+ }[]
+ nextCursorId: string
+ }
}
const getMySuggestionList = async ({
@@ -57,16 +63,59 @@ const getMySuggestionList = async ({
directionType,
cardId,
cursorId,
-}: GetSuggestChecksParams) => {
- const response: MySuggestionRes[] = await apiClient.get(
- ApiEndPoint.getMySuggestionList(
+}: GetMySuggestionListReq) => {
+ const response: GetMySuggestionListRes = await apiClient.get(
+ ApiEndPoint.getMySuggestionList({
directionType,
suggestionType,
cardId,
cursorId,
- ),
+ }),
)
return response
}
-export { getAvailableCardSuggestionList, getMySuggestionList, postSuggestion }
+export type PutMySuggestionStatusReq = {
+ fromCardId: number
+ toCardId: string | string[]
+ isAccepted: boolean
+}
+export type PutMySuggestionStatusRes = {
+ code: string
+ message: string
+ data: {
+ suggestionList: {
+ cardInfo: Card
+ suggestionInfo: Suggestion
+ }[]
+ nextCursorId: string
+ }
+}
+
+const putMySuggestionStatus = async ({
+ fromCardId,
+ toCardId,
+ isAccepted,
+}: PutMySuggestionStatusReq) => {
+ const response: PutMySuggestionStatusRes = await apiClient.put(
+ ApiEndPoint.putMySuggestionStatus(),
+ {
+ fromCardId,
+ toCardId,
+ isAccepted,
+ },
+ {},
+ {
+ 'Content-Type': 'application/json',
+ },
+ )
+
+ return response
+}
+
+export {
+ getAvailableCardSuggestionList,
+ getMySuggestionList,
+ postSuggestion,
+ putMySuggestionStatus,
+}
diff --git a/src/services/user/user.ts b/src/services/user/user.ts
index 200db439..595f7643 100644
--- a/src/services/user/user.ts
+++ b/src/services/user/user.ts
@@ -1,19 +1,16 @@
+import { revalidateTag } from 'next/cache'
import ApiEndPoint from '@/config/apiEndPoint'
import apiClient from '../apiClient'
-type putUserProfileReq = {
- file: File
-}
-
-const putUserProfile = async ({ file }: putUserProfileReq) => {
- const formData = new FormData()
- formData.append('profile', file)
+const putUserProfile = async (imageUrl: string) => {
const response = await apiClient.put(
ApiEndPoint.putUserProfile(),
- formData,
+ {
+ imageUrl,
+ },
{},
{
- 'Content-Type': 'multipart/form-data',
+ 'Content-Type': 'application/json',
},
)
@@ -21,9 +18,16 @@ const putUserProfile = async ({ file }: putUserProfileReq) => {
}
const putUserNickname = async (nickname: string) => {
- const response = await apiClient.put(ApiEndPoint.putUserNickname(), {
- nickname,
- })
+ const response = await apiClient.put(
+ ApiEndPoint.putUserNickname(),
+ {
+ nickname,
+ },
+ {},
+ {
+ 'Content-Type': 'application/json',
+ },
+ )
return response
}
diff --git a/src/types/card.ts b/src/types/card.ts
index 960fc4c7..3d67a992 100644
--- a/src/types/card.ts
+++ b/src/types/card.ts
@@ -2,8 +2,8 @@ import {
CATEGORY,
TRADE_TYPE,
CARD_TRADE_STATUS,
- PRICE_RANGE,
CATEGORY_OBJS,
+ PRICE_RANGE,
PRICE_RANGE_OBJS,
TRADE_STATUS_OBJS,
TRADE_TYPE_OBJS,
diff --git a/src/types/user.ts b/src/types/user.ts
index e8d50bb2..7106d951 100644
--- a/src/types/user.ts
+++ b/src/types/user.ts
@@ -2,7 +2,7 @@ interface User {
userId: number
accountId: string
nickname: string
- role: 'USER' | 'ADMIN'
+ role: 'ROLE_USER' | 'ROLE_ADMIN'
createdDate: string
modifiedDate: string
imageUrl?: string
diff --git a/src/utils/getQueryParams.ts b/src/utils/getQueryParams.ts
new file mode 100644
index 00000000..5cddbf18
--- /dev/null
+++ b/src/utils/getQueryParams.ts
@@ -0,0 +1,11 @@
+export const getQueryParams = (paramsObject: any) => {
+ const params = new URLSearchParams()
+
+ for (const [key, value] of Object.entries(paramsObject)) {
+ if (value) {
+ params.append(key, value.toString())
+ }
+ }
+
+ return params.toString()
+}