Skip to content

Commit

Permalink
🧹 충돌 해결
Browse files Browse the repository at this point in the history
  • Loading branch information
juyeon-park committed Nov 22, 2023
2 parents 5734725 + 541f529 commit 9ad5697
Show file tree
Hide file tree
Showing 57 changed files with 979 additions and 640 deletions.
4 changes: 4 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -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',
Expand Down
2 changes: 1 addition & 1 deletion src/app/(root)/(routes)/(home)/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
37 changes: 34 additions & 3 deletions src/app/(root)/(routes)/cards/[cardId]/modify/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 (
<div>
<h2>Something went wrong!</h2>
<p>
<strong>Error:</strong> {error.message} ({error?.name})
</p>
<button
onClick={
// Attempt to recover by trying to re-render the segment
Expand Down
18 changes: 18 additions & 0 deletions src/app/(root)/(routes)/cards/[cardId]/modify/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import React from 'react'
import PageTitle from '@/components/domain/page-title'
import ApiEndPoint from '@/config/apiEndPoint'
import ErrorMessages from '@/config/errorMessages'
import { ForbiddenError } from '@/lib/errors'
import apiClient from '@/services/apiClient'
import { getCardInfo } from '@/services/card/card'
import { getServerCookie } from '@/utils/getServerCookie'
import { CardUploadFormValues } from '../../new/hooks/useCardUploadForm'
import CardModifyTemplate from './CardModifyTemplate'

Expand All @@ -13,12 +18,25 @@ type CardModifyPageProps = {
const getInitialCardInfo = async (
cardId: string,
): Promise<CardUploadFormValues> => {
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
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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<CategoryObjs['key']>(
(searchParams.get('category') as CategoryObjs['key']) || undefined,
)
const [priceRange, setPriceRange] = useState<PriceRangeObjs['key']>(
(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<HTMLDivElement | null>(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 (
<>
<div className="h-9 flex justify-between items-center mb-6">
<SearchInput setCardTitle={setCardTitle} />
<FilterFormDialog
category={category}
priceRange={priceRange}
setPriceRange={setPriceRange}
setCategory={setCatgegory}
/>
</div>
<div>
<ExceptionBoundary
isLoading={isLoading}
isError={isError}
isEmpty={isEmpty}
isFetchingNextPage={isFetchingNextPage}
>
<CardList data={data} />
</ExceptionBoundary>
</div>
<div ref={lastElementRef} />
</>
)
}
export default CardListContent
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import CardListContent from './CardListContent'

export default CardListContent
107 changes: 22 additions & 85 deletions src/app/(root)/(routes)/cards/components/card-list/CardList.tsx
Original file line number Diff line number Diff line change
@@ -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<Category>(
(searchParams.get('category') as Category) || '전체보기',
)
const [priceRange, setPriceRange] = useState<PriceRange>(
(searchParams.get('priceRange') as PriceRange) || '전체보기',
)

// TODO: 현재 API 명세에 status에 어떤 값을 줘야하는지에 대한 정의가 되어 있지 않기 때문에 임시로 상수 값을 전달함 => 추후에 실제 동작 값으로 고치기
const { data, fetchNextPage, isError, isFetchingNextPage, isLoading } =
useCardsQuery({
category: category,
priceRange: priceRange,
cardTitle: cardTitle,
})

const lastElementRef = useRef<HTMLDivElement | null>(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 (
<MaxWidthWrapper>
<div className="h-9 flex justify-between items-center mb-6">
<SearchInput setCardTitle={setCardTitle} />
<FilterFormDialog
category={category}
priceRange={priceRange}
setPriceRange={setPriceRange}
setCategory={setCatgegory}
/>
</div>
<div>
<ExceptionBoundary
isLoading={isLoading}
isError={isError}
isEmpty={isEmpty}
isFetchingNextPage={isFetchingNextPage}
>
<>
{data?.pages.map((currentPage: any, pageIndex) => (
<Fragment key={pageIndex}>
{currentPage.map((card: Card) => (
<div key={card.cardId} className="mb-6">
<TradeStatusCard card={card} />
</div>
))}
</Fragment>
))}
</>
</ExceptionBoundary>
</div>

<div ref={lastElementRef} />
</MaxWidthWrapper>
)
}
export default CardListContent
const CardList = ({
data,
}: {
data: InfiniteData<GetCardListRes, unknown> | undefined
}) => (
<>
{data?.pages.map(({ data: { cardList } }: GetCardListRes, pageIndex) => (
<Fragment key={pageIndex}>
{cardList.map((card: Card) => (
<div key={card.cardId} className="mb-6">
<TradeStatusCard card={card} />
</div>
))}
</Fragment>
))}
</>
)

export default CardList
Loading

0 comments on commit 9ad5697

Please sign in to comment.