From 2a3577825af2ec14988544a2b0d15b7a603d7547 Mon Sep 17 00:00:00 2001 From: Nuruzzaman Chowdhury Date: Tue, 12 Aug 2025 02:50:43 +0600 Subject: [PATCH 1/7] Header Done --- .gitignore => client/.gitignore | 0 README.md => client/README.md | 0 eslint.config.mjs => client/eslint.config.mjs | 0 next.config.ts => client/next.config.ts | 0 package.json => client/package.json | 13 +++--- pnpm-lock.yaml => client/pnpm-lock.yaml | 12 ++++++ .../postcss.config.mjs | 0 {public => client/public}/cards.png | Bin {public => client/public}/featured.png | Bin {public => client/public}/klarna.png | Bin {public => client/public}/logo.png | Bin {public => client/public}/products/1g.png | Bin {public => client/public}/products/1gr.png | Bin {public => client/public}/products/1p.png | Bin {public => client/public}/products/2g.png | Bin {public => client/public}/products/2gr.png | Bin {public => client/public}/products/3b.png | Bin {public => client/public}/products/3bl.png | Bin {public => client/public}/products/3gr.png | Bin {public => client/public}/products/4p.png | Bin {public => client/public}/products/4w.png | Bin {public => client/public}/products/5bl.png | Bin {public => client/public}/products/5o.png | Bin {public => client/public}/products/5r.png | Bin {public => client/public}/products/6g.png | Bin {public => client/public}/products/6w.png | Bin {public => client/public}/products/7g.png | Bin {public => client/public}/products/7p.png | Bin {public => client/public}/products/8b.png | Bin {public => client/public}/products/8gr.png | Bin {public => client/public}/stripe.png | Bin {src => client/src}/app/favicon.ico | Bin {src => client/src}/app/globals.css | 0 {src => client/src}/app/layout.tsx | 8 +++- {src => client/src}/app/page.tsx | 0 client/src/components/Footer.tsx | 5 +++ client/src/components/Navbar.tsx | 38 ++++++++++++++++++ client/src/components/SearchBar.tsx | 17 ++++++++ tsconfig.json => client/tsconfig.json | 0 39 files changed, 86 insertions(+), 7 deletions(-) rename .gitignore => client/.gitignore (100%) rename README.md => client/README.md (100%) rename eslint.config.mjs => client/eslint.config.mjs (100%) rename next.config.ts => client/next.config.ts (100%) rename package.json => client/package.json (78%) rename pnpm-lock.yaml => client/pnpm-lock.yaml (99%) rename postcss.config.mjs => client/postcss.config.mjs (100%) rename {public => client/public}/cards.png (100%) rename {public => client/public}/featured.png (100%) rename {public => client/public}/klarna.png (100%) rename {public => client/public}/logo.png (100%) rename {public => client/public}/products/1g.png (100%) rename {public => client/public}/products/1gr.png (100%) rename {public => client/public}/products/1p.png (100%) rename {public => client/public}/products/2g.png (100%) rename {public => client/public}/products/2gr.png (100%) rename {public => client/public}/products/3b.png (100%) rename {public => client/public}/products/3bl.png (100%) rename {public => client/public}/products/3gr.png (100%) rename {public => client/public}/products/4p.png (100%) rename {public => client/public}/products/4w.png (100%) rename {public => client/public}/products/5bl.png (100%) rename {public => client/public}/products/5o.png (100%) rename {public => client/public}/products/5r.png (100%) rename {public => client/public}/products/6g.png (100%) rename {public => client/public}/products/6w.png (100%) rename {public => client/public}/products/7g.png (100%) rename {public => client/public}/products/7p.png (100%) rename {public => client/public}/products/8b.png (100%) rename {public => client/public}/products/8gr.png (100%) rename {public => client/public}/stripe.png (100%) rename {src => client/src}/app/favicon.ico (100%) rename {src => client/src}/app/globals.css (100%) rename {src => client/src}/app/layout.tsx (72%) rename {src => client/src}/app/page.tsx (100%) create mode 100644 client/src/components/Footer.tsx create mode 100644 client/src/components/Navbar.tsx create mode 100644 client/src/components/SearchBar.tsx rename tsconfig.json => client/tsconfig.json (100%) diff --git a/.gitignore b/client/.gitignore similarity index 100% rename from .gitignore rename to client/.gitignore diff --git a/README.md b/client/README.md similarity index 100% rename from README.md rename to client/README.md diff --git a/eslint.config.mjs b/client/eslint.config.mjs similarity index 100% rename from eslint.config.mjs rename to client/eslint.config.mjs diff --git a/next.config.ts b/client/next.config.ts similarity index 100% rename from next.config.ts rename to client/next.config.ts diff --git a/package.json b/client/package.json similarity index 78% rename from package.json rename to client/package.json index 6f968124..252efff7 100644 --- a/package.json +++ b/client/package.json @@ -9,19 +9,20 @@ "lint": "next lint" }, "dependencies": { + "lucide-react": "^0.539.0", + "next": "15.4.5", "react": "19.1.0", - "react-dom": "19.1.0", - "next": "15.4.5" + "react-dom": "19.1.0" }, "devDependencies": { - "typescript": "^5", + "@eslint/eslintrc": "^3", + "@tailwindcss/postcss": "^4", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", - "@tailwindcss/postcss": "^4", - "tailwindcss": "^4", "eslint": "^9", "eslint-config-next": "15.4.5", - "@eslint/eslintrc": "^3" + "tailwindcss": "^4", + "typescript": "^5" } } diff --git a/pnpm-lock.yaml b/client/pnpm-lock.yaml similarity index 99% rename from pnpm-lock.yaml rename to client/pnpm-lock.yaml index fbeef25e..273088b9 100644 --- a/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + lucide-react: + specifier: ^0.539.0 + version: 0.539.0(react@19.1.0) next: specifier: 15.4.5 version: 15.4.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -1347,6 +1350,11 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lucide-react@0.539.0: + resolution: {integrity: sha512-VVISr+VF2krO91FeuCrm1rSOLACQUYVy7NQkzrOty52Y8TlTPcXcMdQFj9bYzBgXbWCiywlwSZ3Z8u6a+6bMlg==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} @@ -3200,6 +3208,10 @@ snapshots: dependencies: js-tokens: 4.0.0 + lucide-react@0.539.0(react@19.1.0): + dependencies: + react: 19.1.0 + magic-string@0.30.17: dependencies: '@jridgewell/sourcemap-codec': 1.5.4 diff --git a/postcss.config.mjs b/client/postcss.config.mjs similarity index 100% rename from postcss.config.mjs rename to client/postcss.config.mjs diff --git a/public/cards.png b/client/public/cards.png similarity index 100% rename from public/cards.png rename to client/public/cards.png diff --git a/public/featured.png b/client/public/featured.png similarity index 100% rename from public/featured.png rename to client/public/featured.png diff --git a/public/klarna.png b/client/public/klarna.png similarity index 100% rename from public/klarna.png rename to client/public/klarna.png diff --git a/public/logo.png b/client/public/logo.png similarity index 100% rename from public/logo.png rename to client/public/logo.png diff --git a/public/products/1g.png b/client/public/products/1g.png similarity index 100% rename from public/products/1g.png rename to client/public/products/1g.png diff --git a/public/products/1gr.png b/client/public/products/1gr.png similarity index 100% rename from public/products/1gr.png rename to client/public/products/1gr.png diff --git a/public/products/1p.png b/client/public/products/1p.png similarity index 100% rename from public/products/1p.png rename to client/public/products/1p.png diff --git a/public/products/2g.png b/client/public/products/2g.png similarity index 100% rename from public/products/2g.png rename to client/public/products/2g.png diff --git a/public/products/2gr.png b/client/public/products/2gr.png similarity index 100% rename from public/products/2gr.png rename to client/public/products/2gr.png diff --git a/public/products/3b.png b/client/public/products/3b.png similarity index 100% rename from public/products/3b.png rename to client/public/products/3b.png diff --git a/public/products/3bl.png b/client/public/products/3bl.png similarity index 100% rename from public/products/3bl.png rename to client/public/products/3bl.png diff --git a/public/products/3gr.png b/client/public/products/3gr.png similarity index 100% rename from public/products/3gr.png rename to client/public/products/3gr.png diff --git a/public/products/4p.png b/client/public/products/4p.png similarity index 100% rename from public/products/4p.png rename to client/public/products/4p.png diff --git a/public/products/4w.png b/client/public/products/4w.png similarity index 100% rename from public/products/4w.png rename to client/public/products/4w.png diff --git a/public/products/5bl.png b/client/public/products/5bl.png similarity index 100% rename from public/products/5bl.png rename to client/public/products/5bl.png diff --git a/public/products/5o.png b/client/public/products/5o.png similarity index 100% rename from public/products/5o.png rename to client/public/products/5o.png diff --git a/public/products/5r.png b/client/public/products/5r.png similarity index 100% rename from public/products/5r.png rename to client/public/products/5r.png diff --git a/public/products/6g.png b/client/public/products/6g.png similarity index 100% rename from public/products/6g.png rename to client/public/products/6g.png diff --git a/public/products/6w.png b/client/public/products/6w.png similarity index 100% rename from public/products/6w.png rename to client/public/products/6w.png diff --git a/public/products/7g.png b/client/public/products/7g.png similarity index 100% rename from public/products/7g.png rename to client/public/products/7g.png diff --git a/public/products/7p.png b/client/public/products/7p.png similarity index 100% rename from public/products/7p.png rename to client/public/products/7p.png diff --git a/public/products/8b.png b/client/public/products/8b.png similarity index 100% rename from public/products/8b.png rename to client/public/products/8b.png diff --git a/public/products/8gr.png b/client/public/products/8gr.png similarity index 100% rename from public/products/8gr.png rename to client/public/products/8gr.png diff --git a/public/stripe.png b/client/public/stripe.png similarity index 100% rename from public/stripe.png rename to client/public/stripe.png diff --git a/src/app/favicon.ico b/client/src/app/favicon.ico similarity index 100% rename from src/app/favicon.ico rename to client/src/app/favicon.ico diff --git a/src/app/globals.css b/client/src/app/globals.css similarity index 100% rename from src/app/globals.css rename to client/src/app/globals.css diff --git a/src/app/layout.tsx b/client/src/app/layout.tsx similarity index 72% rename from src/app/layout.tsx rename to client/src/app/layout.tsx index f7fa87eb..21b0c2e6 100644 --- a/src/app/layout.tsx +++ b/client/src/app/layout.tsx @@ -1,6 +1,8 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; +import Navbar from "@/components/Navbar"; +import Footer from "@/components/Footer"; const geistSans = Geist({ variable: "--font-geist-sans", @@ -27,7 +29,11 @@ export default function RootLayout({ - {children} +
+ + {children} +
+
); diff --git a/src/app/page.tsx b/client/src/app/page.tsx similarity index 100% rename from src/app/page.tsx rename to client/src/app/page.tsx diff --git a/client/src/components/Footer.tsx b/client/src/components/Footer.tsx new file mode 100644 index 00000000..d62b37e3 --- /dev/null +++ b/client/src/components/Footer.tsx @@ -0,0 +1,5 @@ +const Footer = () => { + return
Footer
; +}; + +export default Footer; diff --git a/client/src/components/Navbar.tsx b/client/src/components/Navbar.tsx new file mode 100644 index 00000000..8429e052 --- /dev/null +++ b/client/src/components/Navbar.tsx @@ -0,0 +1,38 @@ +import Image from "next/image"; +import Link from "next/link"; +import SearchBar from "./SearchBar"; +import { Bell, Home, ShoppingCart } from "lucide-react"; + +const Navbar = () => { + return ( + + ); +}; + +export default Navbar; diff --git a/client/src/components/SearchBar.tsx b/client/src/components/SearchBar.tsx new file mode 100644 index 00000000..46b4317f --- /dev/null +++ b/client/src/components/SearchBar.tsx @@ -0,0 +1,17 @@ +import { Search } from "lucide-react"; + +const SearchBar = () => { + return ( +
+ + +
+ ); +}; + +export default SearchBar; diff --git a/tsconfig.json b/client/tsconfig.json similarity index 100% rename from tsconfig.json rename to client/tsconfig.json From c81671b3b9d03b4f21c0bf6866e3bee13c4ac1a1 Mon Sep 17 00:00:00 2001 From: Nuruzzaman Chowdhury Date: Wed, 13 Aug 2025 01:10:17 +0600 Subject: [PATCH 2/7] footer and hero section --- client/src/app/page.tsx | 10 +- client/src/components/Categories.tsx | 8 ++ client/src/components/Footer.tsx | 46 ++++++++- client/src/components/ProductCard.tsx | 11 +++ client/src/components/ProductList.tsx | 130 ++++++++++++++++++++++++++ client/src/types.ts | 12 +++ 6 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 client/src/components/Categories.tsx create mode 100644 client/src/components/ProductCard.tsx create mode 100644 client/src/components/ProductList.tsx create mode 100644 client/src/types.ts diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx index 3d365a49..51fbc3a2 100644 --- a/client/src/app/page.tsx +++ b/client/src/app/page.tsx @@ -1,6 +1,14 @@ +import ProductList from "@/components/ProductList" +import Image from "next/image" + const Homepage = () => { return ( -
Homepage
+
+
+ Featured Product +
+ +
) } diff --git a/client/src/components/Categories.tsx b/client/src/components/Categories.tsx new file mode 100644 index 00000000..b149c695 --- /dev/null +++ b/client/src/components/Categories.tsx @@ -0,0 +1,8 @@ +'use client' +const Categories = () => { + return ( +
Categories
+ ) +} + +export default Categories \ No newline at end of file diff --git a/client/src/components/Footer.tsx b/client/src/components/Footer.tsx index d62b37e3..24558fe7 100644 --- a/client/src/components/Footer.tsx +++ b/client/src/components/Footer.tsx @@ -1,5 +1,49 @@ +import Image from "next/image"; +import Link from "next/link"; + + const Footer = () => { - return
Footer
; + return ( +
+
+ + Trend Next +

+ Devnuru. +

+ +

@ 2025 Devnuru

+

All rights reserved.

+
+
+

Links

+ Homepage + Contact + Terms of Service + Privacy Policy +
+
+

Links

+ All Products + New Arrivals + Best Sellers + Sale +
+
+

Links

+ About + Contact + Blog + Affiliate Programs +
+
+ ); }; export default Footer; diff --git a/client/src/components/ProductCard.tsx b/client/src/components/ProductCard.tsx new file mode 100644 index 00000000..0f975ff5 --- /dev/null +++ b/client/src/components/ProductCard.tsx @@ -0,0 +1,11 @@ +'use client'; + +import { ProductType } from "@/types"; + +const ProductCard = ({product}:{product:ProductType}) => { + return ( +
ProductCard
+ ) +} + +export default ProductCard \ No newline at end of file diff --git a/client/src/components/ProductList.tsx b/client/src/components/ProductList.tsx new file mode 100644 index 00000000..a245c0ff --- /dev/null +++ b/client/src/components/ProductList.tsx @@ -0,0 +1,130 @@ +import { ProductsType } from "@/types"; +import Categories from "./Categories"; +import ProductCard from "./ProductCard"; + +// Temporary +const products:ProductsType = [ + { + id: 1, + name: "Adidas CoreFit T-Shirt", + shortDescription: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + description: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + price: 39.9, + sizes: ["s", "m", "l", "xl", "xxl"], + colors: ["gray", "purple", "green"], + images: { + gray: "/products/1g.png", + purple: "/products/1p.png", + green: "/products/1gr.png", + }, + }, + { + id: 2, + name: "Puma Ultra Warm Zip", + shortDescription: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + description: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + price: 59.9, + sizes: ["s", "m", "l", "xl"], + colors: ["gray", "green"], + images: { gray: "/products/2g.png", green: "/products/2gr.png" }, + }, + { + id: 3, + name: "Nike Air Essentials Pullover", + shortDescription: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + description: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + price: 69.9, + sizes: ["s", "m", "l"], + colors: ["green", "blue", "black"], + images: { + green: "/products/3gr.png", + blue: "/products/3b.png", + black: "/products/3bl.png", + }, + }, + { + id: 4, + name: "Nike Dri Flex T-Shirt", + shortDescription: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + description: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + price: 29.9, + sizes: ["s", "m", "l"], + colors: ["white", "pink"], + images: { white: "/products/4w.png", pink: "/products/4p.png" }, + }, + { + id: 5, + name: "Under Armour StormFleece", + shortDescription: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + description: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + price: 49.9, + sizes: ["s", "m", "l"], + colors: ["red", "orange", "black"], + images: { + red: "/products/5r.png", + orange: "/products/5o.png", + black: "/products/5bl.png", + }, + }, + { + id: 6, + name: "Nike Air Max 270", + shortDescription: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + description: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + price: 59.9, + sizes: ["40", "42", "43", "44"], + colors: ["gray", "white"], + images: { gray: "/products/6g.png", white: "/products/6w.png" }, + }, + { + id: 7, + name: "Nike Ultraboost Pulse ", + shortDescription: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + description: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + price: 69.9, + sizes: ["40", "42", "43"], + colors: ["gray", "pink"], + images: { gray: "/products/7g.png", pink: "/products/7p.png" }, + }, + { + id: 8, + name: "Levi’s Classic Denim", + shortDescription: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + description: + "Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit. Lorem ipsum dolor sit amet consect adipisicing elit lorem ipsum dolor sit.", + price: 59.9, + sizes: ["s", "m", "l"], + colors: ["blue", "green"], + images: { blue: "/products/8b.png", green: "/products/8gr.png" }, + }, +]; + +const ProductList = () => { + return ( +
+ +
+ {products.map((product) => ( + + ))} +
+
+ ) +} + +export default ProductList \ No newline at end of file diff --git a/client/src/types.ts b/client/src/types.ts new file mode 100644 index 00000000..46b6294e --- /dev/null +++ b/client/src/types.ts @@ -0,0 +1,12 @@ +export type ProductType = { + id: string | number; + name: string; + shortDescription: string; + description: string; + price: number; + sizes: string[]; + colors: string[]; + images: Record +}; + +export type ProductsType = ProductType[]; \ No newline at end of file From 8dbe2dda3dc4bf6239dee70e399ac064f4bd4d0c Mon Sep 17 00:00:00 2001 From: Nuruzzaman Chowdhury Date: Wed, 20 Aug 2025 16:06:45 +0600 Subject: [PATCH 3/7] category and search params --- client/src/components/Categories.tsx | 95 ++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 5 deletions(-) diff --git a/client/src/components/Categories.tsx b/client/src/components/Categories.tsx index b149c695..ab2ca781 100644 --- a/client/src/components/Categories.tsx +++ b/client/src/components/Categories.tsx @@ -1,8 +1,93 @@ -'use client' +"use client"; + +import { + Footprints, + Glasses, + Briefcase, + Shirt, + ShoppingBasket, + Hand, + Venus, +} from "lucide-react"; +import { usePathname, useRouter, useSearchParams } from "next/navigation"; + +const categories = [ + { + name: "All", + icon: , + slug: "all", + }, + { + name: "T-shirts", + icon: , + slug: "t-shirts", + }, + { + name: "Shoes", + icon: , + slug: "shoes", + }, + { + name: "Accessories", + icon: , + slug: "accessories", + }, + { + name: "Bags", + icon: , + slug: "bags", + }, + { + name: "Dresses", + icon: , + slug: "dresses", + }, + { + name: "Jackets", + icon: , + slug: "jackets", + }, + { + name: "Gloves", + icon: , + slug: "gloves", + }, +]; + const Categories = () => { + + const searchParams = useSearchParams(); + const router = useRouter() + const pathname = usePathname() + + + const selectedCategory = searchParams.get("category"); + + // console.log(selectedCategory); + + const handleChange = (value:string | null) => { + const params = new URLSearchParams(searchParams); + params.set("category", value || "all"); + router.push(`${pathname}?${params.toString()}`, {scroll:false}) + } + + + + return ( -
Categories
- ) -} +
+ {categories.map((category) => ( +
handleChange(category.slug)} + > + {category.icon} + {category.name} +
+ ))} +
+ ); +}; -export default Categories \ No newline at end of file +export default Categories; From 6417bde2ba9132325813ad214efd7d26fd3d1b5a Mon Sep 17 00:00:00 2001 From: Nuruzzaman Chowdhury Date: Tue, 9 Sep 2025 18:07:11 +0600 Subject: [PATCH 4/7] products page added --- client/src/app/page.tsx | 26 ++++--- client/src/app/products/page.tsx | 18 +++++ client/src/components/ProductCard.tsx | 101 ++++++++++++++++++++++++-- client/src/components/ProductList.tsx | 4 +- 4 files changed, 133 insertions(+), 16 deletions(-) create mode 100644 client/src/app/products/page.tsx diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx index 51fbc3a2..8ea54b7d 100644 --- a/client/src/app/page.tsx +++ b/client/src/app/page.tsx @@ -1,15 +1,23 @@ -import ProductList from "@/components/ProductList" -import Image from "next/image" +import ProductList from "@/components/ProductList"; +import Image from "next/image"; + +const Homepage = async ({ + searchParams, +}: { + searchParams: Promise<{ category: string }>; +}) => { + + + const category = (await searchParams).category; -const Homepage = () => { return ( -
+
- Featured Product + Featured Product
- +
- ) -} + ); +}; -export default Homepage \ No newline at end of file +export default Homepage; diff --git a/client/src/app/products/page.tsx b/client/src/app/products/page.tsx new file mode 100644 index 00000000..306d1cd1 --- /dev/null +++ b/client/src/app/products/page.tsx @@ -0,0 +1,18 @@ +import ProductList from "@/components/ProductList" + +const productPage = async ({ + searchParams, +}: { + searchParams: Promise<{ category: string }>; +}) => { + + + const category = (await searchParams).category; + return ( +
+ +
+ ) +} + +export default productPage \ No newline at end of file diff --git a/client/src/components/ProductCard.tsx b/client/src/components/ProductCard.tsx index 0f975ff5..fca440b5 100644 --- a/client/src/components/ProductCard.tsx +++ b/client/src/components/ProductCard.tsx @@ -1,11 +1,100 @@ -'use client'; +"use client"; import { ProductType } from "@/types"; +import { ShoppingCart } from "lucide-react"; +import Image from "next/image"; +import Link from "next/link"; +import { useState } from "react"; + +const ProductCard = ({ product }: { product: ProductType }) => { + const [productTypes, setProductTypes] = useState({ + size: product.sizes[0], + color: product.colors[0], + }); + + const handleProductType = ({ + type, + value, + }: { + type: "size" | "color"; + value: string; + }) => { + setProductTypes((prev) => ({ + ...prev, + [type]: value, + })); + }; -const ProductCard = ({product}:{product:ProductType}) => { return ( -
ProductCard
- ) -} +
+ +
+ {product.name} +
+ + {/* Product Details */} +
+

{product.name}

+

{product.shortDescription}

+ {/* Product Types */} +
+ {/* SIZES */} +
+ Size + +
+ + {/* COLORS */} +
+ Color +
+ {product.colors.map((color) => ( +
+ handleProductType({ type: "color", value: color }) + } + > +
+
+ ))} +
+
+
+ + {/* PRICE AND ADD TO CART BUTTON */} +
+

${product.price.toFixed(2)}

+ +
+
+
+ ); +}; -export default ProductCard \ No newline at end of file +export default ProductCard; diff --git a/client/src/components/ProductList.tsx b/client/src/components/ProductList.tsx index a245c0ff..b2e1f5c7 100644 --- a/client/src/components/ProductList.tsx +++ b/client/src/components/ProductList.tsx @@ -1,6 +1,7 @@ import { ProductsType } from "@/types"; import Categories from "./Categories"; import ProductCard from "./ProductCard"; +import Link from "next/link"; // Temporary const products:ProductsType = [ @@ -114,7 +115,7 @@ const products:ProductsType = [ }, ]; -const ProductList = () => { +const ProductList = ({category}:{category:string}) => { return (
@@ -123,6 +124,7 @@ const ProductList = () => { ))}
+ View all product
) } From 26efaa8c76564d7fe2e2d01d71d856575f783671 Mon Sep 17 00:00:00 2001 From: Nuruzzaman Chowdhury Date: Tue, 9 Sep 2025 18:07:25 +0600 Subject: [PATCH 5/7] products page added --- client/src/components/ProductList.tsx | 29 ++++++++++++++++----------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/client/src/components/ProductList.tsx b/client/src/components/ProductList.tsx index b2e1f5c7..77aa9fa6 100644 --- a/client/src/components/ProductList.tsx +++ b/client/src/components/ProductList.tsx @@ -4,7 +4,7 @@ import ProductCard from "./ProductCard"; import Link from "next/link"; // Temporary -const products:ProductsType = [ +const products: ProductsType = [ { id: 1, name: "Adidas CoreFit T-Shirt", @@ -115,18 +115,23 @@ const products:ProductsType = [ }, ]; -const ProductList = ({category}:{category:string}) => { +const ProductList = ({ category }: { category: string }) => { return (
- -
- {products.map((product) => ( - - ))} -
- View all product + +
+ {products.map((product) => ( + + ))} +
+ + View all product +
- ) -} + ); +}; -export default ProductList \ No newline at end of file +export default ProductList; From 24ca0eca54e320675d3b74adea7b7da5a0713d06 Mon Sep 17 00:00:00 2001 From: Nuruzzaman Chowdhury Date: Wed, 10 Sep 2025 00:50:28 +0600 Subject: [PATCH 6/7] products page added --- client/src/app/page.tsx | 2 +- client/src/app/products/page.tsx | 2 +- client/src/components/Filter.tsx | 25 +++++++++++++++++++++++++ client/src/components/ProductList.tsx | 4 +++- 4 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 client/src/components/Filter.tsx diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx index 8ea54b7d..5bdc09ed 100644 --- a/client/src/app/page.tsx +++ b/client/src/app/page.tsx @@ -15,7 +15,7 @@ const Homepage = async ({
Featured Product
- +
); }; diff --git a/client/src/app/products/page.tsx b/client/src/app/products/page.tsx index 306d1cd1..8016efac 100644 --- a/client/src/app/products/page.tsx +++ b/client/src/app/products/page.tsx @@ -10,7 +10,7 @@ const productPage = async ({ const category = (await searchParams).category; return (
- +
) } diff --git a/client/src/components/Filter.tsx b/client/src/components/Filter.tsx new file mode 100644 index 00000000..cfe2a2fe --- /dev/null +++ b/client/src/components/Filter.tsx @@ -0,0 +1,25 @@ +"use client" + +import { usePathname, useRouter, useSearchParams } from "next/navigation"; + + +const Filter = () => { + const searchParams = useSearchParams(); + const router = useRouter(); + const pathname = usePathname(); + + + return ( +
+ Sort by: + +
+); +}; + +export default Filter; diff --git a/client/src/components/ProductList.tsx b/client/src/components/ProductList.tsx index 77aa9fa6..a152bdda 100644 --- a/client/src/components/ProductList.tsx +++ b/client/src/components/ProductList.tsx @@ -2,6 +2,7 @@ import { ProductsType } from "@/types"; import Categories from "./Categories"; import ProductCard from "./ProductCard"; import Link from "next/link"; +import Filter from "./Filter"; // Temporary const products: ProductsType = [ @@ -115,10 +116,11 @@ const products: ProductsType = [ }, ]; -const ProductList = ({ category }: { category: string }) => { +const ProductList = ({ category, params }: { category: string, params:"homepage" | "products" }) => { return (
+ {params === "products" && }
{products.map((product) => ( From 741adf87d4d93ca628854692b4b34d3a60c83570 Mon Sep 17 00:00:00 2001 From: Nuruzzaman Chowdhury Date: Wed, 10 Sep 2025 01:08:12 +0600 Subject: [PATCH 7/7] filter added --- client/src/components/Filter.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/client/src/components/Filter.tsx b/client/src/components/Filter.tsx index cfe2a2fe..9f84741b 100644 --- a/client/src/components/Filter.tsx +++ b/client/src/components/Filter.tsx @@ -8,11 +8,17 @@ const Filter = () => { const router = useRouter(); const pathname = usePathname(); + const handleFilter = (value: string) => { + const params = new URLSearchParams(searchParams); + params.set("sort", value); + router.push(`${pathname}?${params.toString()}`, {scroll:false}) + } + return ( -
+
Sort by: - handleFilter(e.target.value)}>