-
Notifications
You must be signed in to change notification settings - Fork 37
[김도균] Sprint12 #329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "Next-\uAE40\uB3C4\uADE0-sprint12"
[김도균] Sprint12 #329
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,9 @@ | ||
import BestItemList from '@/components/Items/BestItemList'; | ||
|
||
export default function Items() { | ||
return <div className='mt-[90px]'>상품 페이지</div>; | ||
return ( | ||
<div className='mt-[90px]'> | ||
<BestItemList /> | ||
</div> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { ItemsResponse } from '@/types'; | ||
import ItemCard from './ItemCard'; | ||
|
||
const REVALIDATE_SEC = 60; | ||
const ITEM_CNT = 4; | ||
|
||
export default async function BestItemList() { | ||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/products?orderBy=favorite&pageSize=${ITEM_CNT}`, { | ||
next: { | ||
revalidate: REVALIDATE_SEC, | ||
}, | ||
}); | ||
|
||
if (!response.ok) throw new Error('게시글 불러올 수 없음'); | ||
const data: ItemsResponse = await response.json(); | ||
|
||
return ( | ||
<> | ||
<h2 className='max-w-[1176px] mx-auto text-2xl font-bold mb-2'>베스트 상품</h2> | ||
<div className='flex items-center gap-4 justify-center '> | ||
{data.list.map((item, index) => ( | ||
<ItemCard | ||
key={item.id} | ||
item={{ ...item, imageUrl: item.images[0] }} | ||
className='w-[282px] object-cover h-[282px]' | ||
display={` | ||
${index === 2 ? 'hidden md:flex' : ''} | ||
${index === 3 ? 'hidden lg:flex' : ''} `} | ||
Comment on lines
+27
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 요런것도 일종의 매직넘버에요ㅎㅎ |
||
/> | ||
))} | ||
</div> | ||
</> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import convertLocale from '@/utils/convertLocale'; | ||
import Image from 'next/image'; | ||
|
||
interface ItmeCardProps { | ||
item: { | ||
imageUrl: string | null; | ||
name: string; | ||
price: number; | ||
favoriteCount: number; | ||
}; | ||
className?: string; | ||
display?: string; | ||
} | ||
|
||
export default function ItemCard({ item, className, display }: ItmeCardProps) { | ||
return ( | ||
<div className={`flex flex-col gap-4 ${display}`}> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. display 만 따로 props로 받는것보단 차라리 className 을 받도록 처리하는건 어떨까요?ㅎ 추후 확장성을 위해서요~!! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. className으로 일괄 처리해주는 방식이 더 깔끔해 보입니다, 참고하겠습니다! |
||
<Image src={item.imageUrl ?? '/assets/images/Img_reply_empty.svg'} alt='상품 이미지' width={282} height={282} className={`rounded-2xl ${className}`} /> | ||
<h2>{item.name}</h2> | ||
<p className='font-bold text-xl'>{convertLocale(item.price)}</p> | ||
<div className='flex items-center gap-2'> | ||
<Image src='/assets/icons/heart_empty.svg' alt='좋아요 아이콘' width={16} height={16} /> | ||
<p>{item.favoriteCount}</p> | ||
</div> | ||
</div> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -107,3 +107,21 @@ export interface SignupFailResponse { | |
} | ||
|
||
export type ResponseWithAccessToken<T> = T & { accessToken: string }; | ||
|
||
export interface Item { | ||
id: number; | ||
name: string; | ||
description: string; | ||
price: number; | ||
tags: string[]; | ||
images: string | null[]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 앗앗... 이거 괄호가 없으면 string 또는 null[] 이 타입으로 정의될꺼에요 그래서 (string | null)[] 로 해야할꺼에요ㅎㅎ~ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 헉... 깜빡했습니다. 좋은 지적 감사합니다. |
||
ownerId: number; | ||
favoriteCount: number; | ||
createdAt: string; | ||
updatedAt: string; | ||
} | ||
|
||
export interface ItemsResponse { | ||
list: Item[]; | ||
totalCount: number; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default function convertLocale(num: number) { | ||
return `${num.toLocaleString()}원`; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
약간 고정값들이 너무 많이 나오는것같아요
보통 magic number라고 하는데, 가급적이면 이런건 따로 상수로 뽑아서 만들어두시는게 좋아요ㅎㅎ!
https://jake-seo-dev.tistory.com/155
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
매직넘버를 줄이는 게 좋다고 생각합니다! 좋은 의견 감사합니다.