This content originally appeared on DEV Community and was authored by Mohammad Ezzeddin Pratama
In this tutorial, ill build a dynamic product page using Next.js and Prisma.ill fetch data based on the selected category and display it using a visually appealing card layout.
1. Setting Up Dynamic Routes
Next.js allows us to create dynamic routes easily. We'll set up a dynamic route that will render products based on the selected category.
Creating the Dynamic Route
First, create a new file under the app/products/[category]/page.tsx
directory. This file will handle rendering the products for the selected category.
app/products/[category]/page.tsx
import { notFound } from 'next/navigation';
import { type CategoryTypes } from '@prisma/client';
import React from 'react'
import prisma from '@/app/lib/db';
import ProductCard from '@/app/components/ProductCard';
async function getData(category: string) {
let input;
switch (category) {
case "template":
input = "template";
break;
case "uikit":
input = "uikit";
break;
case "icon":
input = "icon";
break;
case "all":
input = undefined;
break;
default:
return notFound();
}
const data = await prisma.product.findMany({
where: {
category: input as CategoryTypes,
},
select: {
id: true,
images: true,
smallDescription: true,
name: true,
price: true,
}
});
return data;
}
export default async function CategoryPage({ params }: { params: { category: string } }) {
const data = await getData(params.category);
return (
<section className='max-w-7xl mx-auto px-4 md:px-8'>
<div className="grid grid-cols-1 lg:grid-cols-3 sm:grid-cols-2 gap-10 mt-4">
{data.map((product) => (
<ProductCard
key={product.id}
images={product.images}
name={product.name}
smallDescription={product.smallDescription}
price={product.price}
id={product.id}
/>
))}
</div>
</section>
)
}
Explanation
-
Dynamic Routing: The
[category]
in the file name tells Next.js to treat this segment as a variable. Based on this variable, we'll fetch and display products. -
Fetching Data: The
getData
function retrieves products based on the category. It handles categories like "template", "uikit", "icon", and "all". -
Rendering Cards: The
ProductCard
component is used to display each product in a grid layout.
2. Creating the Product Card Component
To present the products, we need a ProductCard
component that displays product details in a card format.
app/components/ProductCard.tsx
import React from 'react'
import Image from 'next/image'
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from '@/components/ui/carousel';
import Link from 'next/link';
import { Button } from '@/components/ui/button';
interface iAppProps {
id: string;
name: string;
smallDescription: string;
description?: string;
price: number;
images: string[];
}
export default function ProductCard({ id, name, smallDescription, price, images }: iAppProps) {
return (
<div className='rounded-lg p-2 w-full h-full flex flex-col justify-between items-center bg-white shadow-md'>
<Carousel>
<CarouselContent>
{images.map((item, index) => (
<CarouselItem key={index}>
<div className='relative h-[230px] w-full'>
<Image
alt='Product image'
src={item}
width={230}
height={230}
quality={75}
className='shadow-md object-cover w-full h-full rounded-lg' />
</div>
</CarouselItem>
))}
</CarouselContent>
{images.length > 1 && (
<>
<CarouselPrevious className="ml-16" />
<CarouselNext className="mr-16" />
</>
)}
</Carousel>
<div className='flex flex-col gap-y-2 p-2 items-end justify-start text-left h-full'>
<div className='flex justify-between items-start mt-2 gap-x-3 w-full'>
<h1 className="text-md font-bold text-wrap">{name}</h1>
<h3 className="inline-flex items-center rounded-full bg-primary/10 px-2 py-1 text-sm font-medium text-primary ring-1 ring-inset ring-primary/10">$<span className="font-semibold">{price}</span></h3>
</div>
<p className='text-neutral-600 text-sm text-left line-clamp-2'>{smallDescription}</p>
<div className='items-end justify-end pt-2'>
<Button className='rounded-lg hover:shadow-lg hover:scale-105 transition-all duration-300 '>
<Link href={`/product/${id}`}>View Details</Link>
</Button>
</div>
</div>
</div>
)
}
Explanation
- Image Carousel: Displays multiple images for each product. Users can navigate through images using the carousel controls.
- Product Details: Shows the product's name, price, and a brief description.
- View Details Button: Links to a detailed product view page.
3. Adding Navigation Links
To enable navigation between different categories, create a NavbarLinks
component.
app/components/NavbarLinks.tsx
"use client"
import { cn } from '@/lib/utils'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import React from 'react'
export const navdata = [
{
id: 0,
name: "Home",
href: "/",
},
{
id: 1,
name: "Templates",
href: "/products/template",
},
{
id: 2,
name: "UI Kits",
href: "/products/uikit",
},
{
id: 3,
name: "Icons",
href: "/products/icon",
},
]
export default function NavbarLinks() {
const location = usePathname();
return (
<div className='hidden md:flex justify-center items-center col-span-6 gap-x-9 text-md md:text-sm text-neutral-600'>
{navdata.map((item) => {
return (
<Link key={item.id} href={item.href} className={cn(
location === item.href ? "bg-orange-100/60 font-medium bg-opacity-100 py-1 px-2 transition-all duration-300 rounded-full text-orange-400" : "hover:text-orange-400 duration-300",
)}>
<h1>{item.name}</h1>
</Link>
)
})}
</div>
)
}
Explanation
- Navigation Links: Provides links to different product categories. Highlights the currently active category based on the URL.
Conclusion
In this tutorial, we set up a dynamic route in Next.js to display products based on the selected category. We created a ProductCard
component to present products and added a navigation bar to switch between categories.
Feel free to adapt these components and routing strategies to fit your specific project needs. Happy coding!
This content originally appeared on DEV Community and was authored by Mohammad Ezzeddin Pratama
Mohammad Ezzeddin Pratama | Sciencx (2024-08-26T13:56:55+00:00) Fetching and Displaying Dynamic Product Data in Next.js with Prisma. Retrieved from https://www.scien.cx/2024/08/26/fetching-and-displaying-dynamic-product-data-in-next-js-with-prisma/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.