Type missmatch

The issue is on 89-90
 avatar
unknown
tsx
6 months ago
4.2 kB
6
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