Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ const nextConfig: NextConfig = {
protocol: 'https',
hostname: 'flexible.img.hani.co.kr',
},
{
protocol: 'https',
hostname: 'image.hanatour.com',
},
],
},
};
Expand Down
8 changes: 7 additions & 1 deletion src/app/(with-Header)/items/page.tsx
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>
);
}
34 changes: 34 additions & 0 deletions src/components/Items/BestItemList.tsx
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]'
Copy link
Collaborator

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

매직넘버를 줄이는 게 좋다고 생각합니다! 좋은 의견 감사합니다.

display={`
${index === 2 ? 'hidden md:flex' : ''}
${index === 3 ? 'hidden lg:flex' : ''} `}
Comment on lines +27 to +28
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요런것도 일종의 매직넘버에요ㅎㅎ

/>
))}
</div>
</>
);
}
27 changes: 27 additions & 0 deletions src/components/Items/ItemCard.tsx
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}`}>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

display 만 따로 props로 받는것보단 차라리 className 을 받도록 처리하는건 어떨까요?ㅎ

추후 확장성을 위해서요~!!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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>
);
}
18 changes: 18 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗앗... 이거 괄호가 없으면 string 또는 null[] 이 타입으로 정의될꺼에요

그래서 (string | null)[] 로 해야할꺼에요ㅎㅎ~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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;
}
3 changes: 3 additions & 0 deletions src/utils/convertLocale.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function convertLocale(num: number) {
return `${num.toLocaleString()}원`;
}
Loading