Type missmatch
The issue is on 89-90unknown
tsx
a year ago
4.2 kB
7
Indexable
import Image from "next/image"
import Link from "next/link"
import configPromise from '@payload-config'
import { Card, CardContent } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import ProductImageGallery from "@/components/ProductImageGallery"
import { draftMode } from "next/headers"
import { getPayloadHMR } from "@payloadcms/next/utilities"
import { cache } from "react"
import { generateMeta } from "@/utilities/generateMeta"
import { PayloadRedirects } from "../PayloadRedirects"
import { Product, Category, PackagingOption } from "@/payload-types"
import RichText from "../RichText"
export async function generateStaticParams() {
const payload = await getPayloadHMR({ config: configPromise })
const products = await payload.find({
collection: 'products',
draft: false,
limit: 1000,
overrideAccess: false,
})
const params = products.docs.map(({ slug }) => {
return { slug }
})
return params
}
type Args = {
params: Promise<{
slug?: string
}>
}
const generateUrl = (slug: string): string => {
return `/products/${slug}`
}
export default async function ProductPage({ params: paramsPromise }: Args) {
const { slug = '' } = await paramsPromise
const product = await queryProductBySlug({ slug })
if (!product) return <PayloadRedirects url={generateUrl(slug)} />
const productImagesUrls = (product: Product): string[] => {
return product.images?.flatMap((image) => image.image?.url) || [];
};
return (
<div className="container mx-auto px-4 py-8">
<div className="grid md:grid-cols-2 gap-8 mb-16">
<ProductImageGallery images={productImagesUrls(product)} />
<div className="flex flex-col justify-center">
<div>
<h1 className="text-3xl font-bold mb-2">{product.title}</h1>
{product?.categories && (
product.categories.map(({ title }, i) => (
<Badge key={i} className="mb-4 mr-2">{title}</Badge>
))
)}
<RichText content={product.content} enableGutter={false} className="text-muted-foreground mb-6" />
<div className="border-t border-stone-400 mt-6"></div>
</div>
</div>
</div>
{product.relatedProducts && product.relatedProducts.length && (
<section className="mb-16">
<h2 className="text-2xl font-bold mb-6">Related Products</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
{product.relatedProducts.map((product: Product, i) => (
<Link href={generateUrl(product.slug || '')} key={i}>
<Card key={product.id} className="overflow-hidden">
<div className="relative aspect-square">
<Image
src={product.images[0].image?.url}
alt={product.images[0].image?.url || product?.title}
layout="fill"
objectFit="cover"
/>
</div>
<CardContent className="p-4">
<h3 className="font-semibold mb-2">Related Product {product.title}</h3>
{product?.category?.title && (
<Badge className="mb-4">{product?.category?.title}</Badge>
)}
</CardContent>
</Card>
</Link>
))}
</div>
</section>
)}
</div>
)
}
export async function generateMetadata({ params: paramsPromise }: Args): Promise<Metadata> {
const { slug = '' } = await paramsPromise
const product = await queryProductBySlug({ slug })
return generateMeta({ doc: product })
}
const queryProductBySlug = cache(async ({ slug }: { slug: string }) => {
const { isEnabled: draft } = await draftMode()
const payload = await getPayloadHMR({ config: configPromise })
const result = await payload.find({
collection: 'products',
draft,
limit: 1,
overrideAccess: draft,
where: {
slug: {
equals: slug,
},
},
})
return result.docs?.[0] || null
})
Editor is loading...
Leave a Comment