diff --git a/next.config.ts b/next.config.ts
index f3e54dd56..053c0976b 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -29,6 +29,10 @@ const nextConfig: NextConfig = {
protocol: 'https',
hostname: 'flexible.img.hani.co.kr',
},
+ {
+ protocol: 'https',
+ hostname: 'image.hanatour.com',
+ },
],
},
};
diff --git a/src/app/(with-Header)/items/page.tsx b/src/app/(with-Header)/items/page.tsx
index 4a1a94e61..bb1953bf2 100644
--- a/src/app/(with-Header)/items/page.tsx
+++ b/src/app/(with-Header)/items/page.tsx
@@ -1,3 +1,9 @@
+import BestItemList from '@/components/Items/BestItemList';
+
export default function Items() {
- return
상품 페이지
;
+ return (
+
+
+
+ );
}
diff --git a/src/components/Items/BestItemList.tsx b/src/components/Items/BestItemList.tsx
new file mode 100644
index 000000000..4189ffcbb
--- /dev/null
+++ b/src/components/Items/BestItemList.tsx
@@ -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 (
+ <>
+ 베스트 상품
+
+ {data.list.map((item, index) => (
+
+ ))}
+
+ >
+ );
+}
diff --git a/src/components/Items/ItemCard.tsx b/src/components/Items/ItemCard.tsx
new file mode 100644
index 000000000..ea12d7093
--- /dev/null
+++ b/src/components/Items/ItemCard.tsx
@@ -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 (
+
+
+
{item.name}
+
{convertLocale(item.price)}
+
+
+
{item.favoriteCount}
+
+
+ );
+}
diff --git a/src/types.ts b/src/types.ts
index 95f7477e0..fe659e845 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -107,3 +107,21 @@ export interface SignupFailResponse {
}
export type ResponseWithAccessToken = T & { accessToken: string };
+
+export interface Item {
+ id: number;
+ name: string;
+ description: string;
+ price: number;
+ tags: string[];
+ images: string | null[];
+ ownerId: number;
+ favoriteCount: number;
+ createdAt: string;
+ updatedAt: string;
+}
+
+export interface ItemsResponse {
+ list: Item[];
+ totalCount: number;
+}
diff --git a/src/utils/convertLocale.ts b/src/utils/convertLocale.ts
new file mode 100644
index 000000000..d2caf32f2
--- /dev/null
+++ b/src/utils/convertLocale.ts
@@ -0,0 +1,3 @@
+export default function convertLocale(num: number) {
+ return `${num.toLocaleString()}원`;
+}