diff --git a/src/App.tsx b/src/App.tsx
index 480fbe258997de84047b73e0bbbd2fe51ea91ab6..dcaf099c4c4aff4667086ccae7a9b33ff380b02f 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -5,6 +5,7 @@ import Layout from './components/Layout'
 import { BrowserRouter, Routes, Route } from "react-router-dom";
 import AboutPage from './pages/AboutPage';
 import AuthPage from './pages/AuthPage';
+import CatalogPage from './pages/CatalogPage';
 
 function App() {
   return (
@@ -30,6 +31,7 @@ function App() {
           <Route index element={<AboutPage />} />
           <Route path="login" element={<AuthPage />} />
           <Route path="register" element={<AuthPage/>}/>
+          <Route path="catalog" element={<CatalogPage />}/>
           {/* <Route path="myprofile" element={<MyProfile />} />
           <Route path="product" element={<Product />} /> */}
           {/* TODO: Make a not found page (like below) */}
diff --git a/src/components/NavigationBar/index.tsx b/src/components/NavigationBar/index.tsx
index 54002a4fcfa48880c7300e82a8c5157c6b2e19f4..cdd3fcfa826e0d14024a15873eab6969242c6439 100644
--- a/src/components/NavigationBar/index.tsx
+++ b/src/components/NavigationBar/index.tsx
@@ -36,7 +36,7 @@ const NavigationBar = () => {
                     </div>
                 </div>
                 <div className="sm:ml-auto btn-primary text-tertiary">
-                    <a>
+                    <a href="/catalog">
                         <BookOpenIcon className="h-6 w-6 inline"/>
                         <p className="text-inherit hidden min-[784px]:inline">Catalog</p>
                     </a>
diff --git a/src/pages/CatalogPage/index.tsx b/src/pages/CatalogPage/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..177f1659944dc50624b6475ea097f9623001ebf4
--- /dev/null
+++ b/src/pages/CatalogPage/index.tsx
@@ -0,0 +1,35 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+import CatalogItemListView from "./view/CatalogItemList";
+import { Item } from "../../types/product";
+
+const CatalogPage = () => {
+    // FIXME : Change dummyArr to array of items
+    const dummyArr: Item[] = [];
+    for (let index = 0; index < 11; index++) {
+        const elem: Item = {
+            id : index,
+            name : "product_name " + (index + 1),
+            picture_path : "no_picture",
+            description : "no_description",
+            price : 0,
+            quantity : 0,
+            seller_username : "no_seller " + (index + 1)
+        }
+        dummyArr.push(elem);
+    }
+    return (
+        <div className="py-16">
+            {/* <div id="filter-field">
+                
+            </div> */}
+            <div id="catalog" 
+            >
+                <CatalogItemListView
+                itemArray = {dummyArr}/>
+            </div>
+        </div>
+    )
+}
+
+export default CatalogPage
diff --git a/src/pages/CatalogPage/view/CatalogItem/index.tsx b/src/pages/CatalogPage/view/CatalogItem/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..5818f30eed423da13051af579b61f6528cd477f8
--- /dev/null
+++ b/src/pages/CatalogPage/view/CatalogItem/index.tsx
@@ -0,0 +1,40 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import { Item } from "../../../../types/product";
+
+const CatalogItemView = (itemData : any) => {
+    // get data from a list of items
+    const item : Item = {
+        id : itemData["id"],
+        name : itemData["name"],
+        picture_path : itemData["picture_path"],
+        description : itemData["description"],
+        price : itemData["price"],
+        quantity : itemData["quantity"],
+        seller_username : itemData["seller_username"],
+    }
+    return (
+        <div className="bg-slate-300 rounded-xl shadow-xl p-2">
+            <div className="bg-slate-400 aspect-square object-cover object-center">
+                <img src={item.picture_path?item.picture_path:''}
+                alt={item.name + " picture"}/>
+            </div>
+            <div className="mt-2">
+                <div>
+                    <p className="truncate font-bold">{item.name}</p>
+                </div>
+                <div>
+                    <p className="text-2xl">Rp{item.price}</p>
+                </div>
+                <div>
+                    <p className="text-sm text-right">Stock: {item.quantity}</p>
+                </div>
+                <div>
+                    <p className="text-xs">{item.seller_username}</p>
+                </div>
+            </div>
+        </div>
+    )
+}
+
+export default CatalogItemView
diff --git a/src/pages/CatalogPage/view/CatalogItemList/index.tsx b/src/pages/CatalogPage/view/CatalogItemList/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..fdfffa3e944e1880537045070532d42ae32188f3
--- /dev/null
+++ b/src/pages/CatalogPage/view/CatalogItemList/index.tsx
@@ -0,0 +1,25 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import CatalogItemView from "../CatalogItem";
+import { Item } from "../../../../types/product";
+
+const CatalogItemListView = ({itemArray} : {itemArray: Item[]}/* itemArray */) => {
+    return (
+        <div className="grid grid-cols-2 grid-rows-5 sm:grid-rows-2 sm:grid-cols-5 py-6 px-12 gap-4">
+            {itemArray.map((item: Item) => (
+            <CatalogItemView
+            key={item.id}
+            id={item.id}
+            name={item.name}
+            picture_path={item.picture_path}
+            description={item.description}
+            price={item.price}
+            quantity={item.quantity}
+            seller_username={item.seller_username}
+            />
+        ))}
+        </div>
+    )
+}
+
+export default CatalogItemListView
diff --git a/src/types/product.d.ts b/src/types/product.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..12ac1b1391584a20cd5f2221215468923fa3898f
--- /dev/null
+++ b/src/types/product.d.ts
@@ -0,0 +1,9 @@
+export type Item = {
+    id : number;
+    name : string;
+    picture_path : string;
+    description : string;
+    price : number;
+    quantity : number;
+    seller_username : string;
+}
\ No newline at end of file