LLC/src/app/[locale]/product/[slug]/page.jsx

270 lines
8.1 KiB
JavaScript

import { Home } from "lucide-react";
import { ChevronRight } from "lucide-react";
import { ShoppingCart } from "lucide-react";
import { getLocale, getMessages } from "next-intl/server";
import Link from "next/link";
import { notFound } from "next/navigation";
import BrandInfo from "src/components/Product/BrandInfo";
import ProductDescription from "src/components/Product/ProductDescription";
import ProductGallery from "src/components/Product/ProductGallery";
import ProductInfo from "src/components/Product/ProductInfo";
import ProductProperties from "src/components/Product/ProductProperties";
import ProductRelated from "src/components/Product/ProductRelated";
import graphql from "src/utils/graphql";
const gql = `
query Products($locale: I18NLocaleCode, $slug: String!) {
products(filters: { slug: { eqi: $slug } }, locale: $locale) {
documentId
title
price
summery
qt
images {
documentId
alternativeText
url
}
category {
documentId
title
slug
}
description
brand {
documentId
title
image {
alternativeText
documentId
url
}
slug
}
slug
discount
showPrice
seo {
id
metaTitle
metaDescription
keywords
metaRobots
metaViewport
canonicalURL
structuredData
metaImage {
documentId
alternativeText
url
}
openGraph {
id
ogTitle
ogDescription
ogUrl
ogType
ogImage {
documentId
alternativeText
url
}
}
}
properties {
id
key
value
}
}
}
`;
const gql_static = `
query Products($locale:I18NLocaleCode,$start:Int,$limit:Int) {
products(locale: $locale, pagination: { start: $start, limit: $limit }) {
slug
}
}
`
const gql_metadata = `
query Products($locale:I18NLocaleCode,$slug:String!) {
products(filters: { slug: { eqi: $slug } }, locale: $locale) {
title
seo {
id
metaTitle
metaDescription
metaRobots
canonicalURL
metaImage {
documentId
alternativeText
url
}
openGraph {
id
ogTitle
ogDescription
ogUrl
ogType
ogImage {
documentId
alternativeText
url
}
}
structuredData
}
}
}
`
export async function generateMetadata({ params }) {
const { locale, slug } = await params;
// Fetch product SEO data from Strapi GraphQL API
const data = await graphql(gql_metadata, {
locale,
slug,
});
const productSEO = data?.products?.[0]?.seo;
if (productSEO) {
return {
title: productSEO.metaTitle,
description: productSEO.metaDescription,
robots: productSEO.metaRobots || 'index, follow',
// canonical: productSEO.canonicalURL || `https://adhorizonintl.com/product/${slug}`,
alternates: {
canonical: productSEO.canonicalURL || `https://adhorizonintl.com/product/${slug}`,
languages: {
'en': `https://adhorizonintl.com/product/${slug}`,
'ar-OM': `https://adhorizonintl.com/ar-OM/product/${slug}`,
},
},
openGraph: {
title: productSEO.openGraph.ogTitle || productSEO.metaTitle,
description: productSEO.openGraph.ogDescription || productSEO.metaDescription,
url: productSEO.openGraph.ogUrl || `https://adhorizonintl.com/product/${slug}`,
type: productSEO.openGraph.ogType || 'website',
images: [
{
url: productSEO.openGraph.ogImage.url,
alt: productSEO.openGraph.ogImage.alternativeText || 'Product Image',
},
],
},
twitter: {
card: 'summary_large_image',
title: productSEO.metaTitle,
description: productSEO.metaDescription,
images: [productSEO.metaImage?.url],
},
// structuredData: productSEO.structuredData,
};
}
else {
return {
title: data?.products?.[0]?.title,
}
}
}
// export async function generateStaticParams() {
// const { products } = await graphql(gql_static, {
// "locale": "en",
// "start": 0,
// "limit": 1500
// })
// return products.map((product) =>
// ({ slug: product.slug })
// );
// }
const getProduct = async (slug) => {
const { products } = await graphql(gql, {
locale: "en",
slug,
});
return products[0];
};
export default async function ProductPage({ params }) {
const { slug } = await params
const product = await getProduct(slug);
if (!product) {
notFound();
}
const locale = await getLocale();
const t = await getMessages({ locale });
console.log(t)
return (
<div className="contain-none md:container mx-auto px-4 py-8">
<div className="flex flex-col lg:flex-row gap-8">
<ProductGallery images={product.images} />
<div className="flex flex-col gap-4 w-full ">
<div className={`flex items-center gap-2 mb-6 `}>
<Link href="/" className=" underline inline-flex gap-2">
<Home />
</Link>
{
product?.category?.slug &&
<>
<ChevronRight className={`size-4 ${locale !== "en" && "rotate-180"} `} />
<Link href={`/products/${product.category.slug}`} className=" underline">
{product.category.title}
</Link>
</>
}
{
product?.brand?.slug &&
<>
<ChevronRight className={`size-4 ${locale !== "en" && "rotate-180"} `} />
<Link href={`/products/${product.brand.slug}`} className=" underline">
{product.brand.title}
</Link>
</>
}
<ChevronRight className={`size-4 ${locale !== "en" && "rotate-180"} `} />
<span>{product.title}</span>
</div>
<div className="h-full flex justify-between flex-row w-full items-start">
<ProductInfo
title={product.title}
price={product.price}
discount={product.discount}
showPrice={product.showPrice}
category={product.category}
summery={product.summery}
brand={product.brand}
/>
</div>
</div>
</div>
<div className="mt-12">
<ProductProperties properties={product.properties} />
</div>
<div className="mt-12">
<ProductDescription description={product.description} />
</div>
<div className="mt-12">
<ProductRelated brand={product.brand} category={product.category} />
</div>
</div>
);
}