fix: category pages integration
This commit is contained in:
parent
66fdb977e9
commit
e9c800ab95
@ -2,14 +2,24 @@ import { BeforeFooterBlock } from "@/components/Blocks/BeforeFooter";
|
|||||||
import { BlogCardItemSkeleton } from "@/components/Blogs/BlogCardItem";
|
import { BlogCardItemSkeleton } from "@/components/Blogs/BlogCardItem";
|
||||||
import Blogs from "@/components/Blogs/Blogs";
|
import Blogs from "@/components/Blogs/Blogs";
|
||||||
import HeroOther from "@/components/HeroOther";
|
import HeroOther from "@/components/HeroOther";
|
||||||
|
import { fetchBlogCategoryBySlug } from "@/services/payload/blog";
|
||||||
import { getDefaultMetadata } from "@/utils/metadata";
|
import { getDefaultMetadata } from "@/utils/metadata";
|
||||||
import { sanitizePageNumber } from "@/utils/sanitize";
|
import { sanitizePageNumber } from "@/utils/sanitize";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
// import { headers } from "next/headers";
|
import { headers } from "next/headers";
|
||||||
|
import { notFound } from "next/navigation";
|
||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
|
|
||||||
export async function generateMetadata(): Promise<Metadata> {
|
export async function generateMetadata({ params }: { params: Promise<{ path: string[0] }> }): Promise<Metadata> {
|
||||||
|
const path = (await params)?.path;
|
||||||
|
const paramsCategory = path?.[0] ?? "";
|
||||||
const metadata = await getDefaultMetadata();
|
const metadata = await getDefaultMetadata();
|
||||||
|
|
||||||
|
const category = await fetchBlogCategoryBySlug(paramsCategory);
|
||||||
|
if (!!category?.data) {
|
||||||
|
metadata.title = `${category.data.name} Archives - ${metadata.openGraph?.siteName}`;
|
||||||
|
}
|
||||||
|
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,19 +31,92 @@ export default async function CategoryPage({
|
|||||||
searchParams?: Promise<{ page?: string; s?: string }>;
|
searchParams?: Promise<{ page?: string; s?: string }>;
|
||||||
}) {
|
}) {
|
||||||
const path = (await params)?.path;
|
const path = (await params)?.path;
|
||||||
// const headersList = await headers();
|
const paramsCategory = path?.[0] ?? "";
|
||||||
// const paramsCategory = path?.[0] ?? "";
|
|
||||||
const paramsPage = path?.[2] ?? "";
|
const paramsPage = path?.[2] ?? "";
|
||||||
const paramsSearch = (await searchParams)?.s;
|
const paramsSearch = (await searchParams)?.s;
|
||||||
const page = sanitizePageNumber(paramsPage);
|
const page = sanitizePageNumber(paramsPage);
|
||||||
|
const headersList = await headers();
|
||||||
|
const mainUrl = headersList.get("x-main-url");
|
||||||
|
const fullUrl = headersList.get("x-full-url");
|
||||||
|
const siteName = headersList.get("x-site-name");
|
||||||
|
|
||||||
|
const category = await fetchBlogCategoryBySlug(paramsCategory);
|
||||||
|
if (!category) {
|
||||||
|
notFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
const jsonLd = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@graph": [
|
||||||
|
{
|
||||||
|
"@type": "CollectionPage",
|
||||||
|
"@id": fullUrl,
|
||||||
|
url: fullUrl,
|
||||||
|
name: `${category.data.name} - ${siteName}`,
|
||||||
|
isPartOf: {
|
||||||
|
"@id": `${mainUrl}/#website`,
|
||||||
|
},
|
||||||
|
primaryImageOfPage: {
|
||||||
|
"@id": `${fullUrl}#primaryimage`,
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
"@id": `${fullUrl}#primaryimage`,
|
||||||
|
},
|
||||||
|
inLanguage: "en-US",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "WebSite",
|
||||||
|
"@id": `${mainUrl}/#website`,
|
||||||
|
url: `${mainUrl}/`,
|
||||||
|
name: siteName,
|
||||||
|
description: "",
|
||||||
|
publisher: {
|
||||||
|
"@id": `${mainUrl}/#organization`,
|
||||||
|
},
|
||||||
|
potentialAction: [
|
||||||
|
{
|
||||||
|
"@type": "SearchAction",
|
||||||
|
target: {
|
||||||
|
"@type": "EntryPoint",
|
||||||
|
urlTemplate: `${mainUrl}/?s={search_term_string}`,
|
||||||
|
},
|
||||||
|
"query-input": {
|
||||||
|
"@type": "PropertyValueSpecification",
|
||||||
|
valueRequired: true,
|
||||||
|
valueName: "search_term_string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
inLanguage: "en-US",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "Organization",
|
||||||
|
"@id": `${mainUrl}/#organization`,
|
||||||
|
name: siteName,
|
||||||
|
url: `${mainUrl}/`,
|
||||||
|
logo: {
|
||||||
|
"@type": "ImageObject",
|
||||||
|
inLanguage: "en-US",
|
||||||
|
"@id": `${mainUrl}/#/schema/logo/image/`,
|
||||||
|
url: `${mainUrl}/assets/images/logo-dark.webp`,
|
||||||
|
contentUrl: `${mainUrl}/assets/images/logo-dark.webp`,
|
||||||
|
caption: siteName,
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
"@id": `${mainUrl}/#/schema/logo/image/`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HeroOther title="Blog" />
|
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
|
||||||
|
<HeroOther title={`Category: ${category.data.name}`} />
|
||||||
|
|
||||||
<section className="page-section" id="blog">
|
<section className="page-section" id="blog">
|
||||||
<div className="w-full max-w-7xl mx-auto px-4 md:px-8">
|
<div className="w-full max-w-7xl mx-auto px-4 md:px-8">
|
||||||
<form action={`category/chemotherapy/page/1`} method="GET">
|
<form action={`/category/${paramsCategory}`} method="GET">
|
||||||
<div className="input-group">
|
<div className="input-group">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@ -52,7 +135,7 @@ export default async function CategoryPage({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Suspense fallback={<Loading />}>
|
<Suspense fallback={<Loading />}>
|
||||||
<Blogs preset="categories" page={page} search={paramsSearch} />
|
<Blogs preset="categories" categoryId={category.data.id} page={page} search={paramsSearch} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -3,14 +3,30 @@ import { fetchBlog } from "@/services/payload/blog";
|
|||||||
import { BlogCardItem } from "./BlogCardItem";
|
import { BlogCardItem } from "./BlogCardItem";
|
||||||
import { sanitizeBlogContentIntoStringPreview } from "@/utils/sanitize";
|
import { sanitizeBlogContentIntoStringPreview } from "@/utils/sanitize";
|
||||||
|
|
||||||
export interface BlogsProps {
|
export type BlogsProps = {
|
||||||
preset?: "blogs" | "categories";
|
|
||||||
page: number;
|
page: number;
|
||||||
search?: string;
|
search?: string;
|
||||||
}
|
} & (
|
||||||
|
| {
|
||||||
|
preset?: "blogs";
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
preset?: "categories";
|
||||||
|
categoryId: number;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export default async function Blogs({ page, search, preset = "blogs" }: BlogsProps) {
|
export default async function Blogs({ page, search, ...params }: BlogsProps) {
|
||||||
const data = await fetchBlog({ page, search });
|
const fetchBlogParams: Parameters<typeof fetchBlog>[0] = {
|
||||||
|
page,
|
||||||
|
search,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (params.preset === "categories") {
|
||||||
|
fetchBlogParams.categoryId = params.categoryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await fetchBlog(fetchBlogParams);
|
||||||
|
|
||||||
if (!data?.totalDocs) return <></>;
|
if (!data?.totalDocs) return <></>;
|
||||||
|
|
||||||
@ -42,7 +58,7 @@ export default async function Blogs({ page, search, preset = "blogs" }: BlogsPro
|
|||||||
hasNextPage={data.hasNextPage}
|
hasNextPage={data.hasNextPage}
|
||||||
hasPreviousPage={data.hasPrevPage}
|
hasPreviousPage={data.hasPrevPage}
|
||||||
totalPages={data.totalPages}
|
totalPages={data.totalPages}
|
||||||
usePathParams={preset === "blogs" ? false : true}
|
usePathParams={params.preset === "blogs" ? false : true}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -28,8 +28,13 @@ export default function Pagination({
|
|||||||
const searchParams = new URLSearchParams(url.search);
|
const searchParams = new URLSearchParams(url.search);
|
||||||
|
|
||||||
if (usePathParams) {
|
if (usePathParams) {
|
||||||
searchParams.set("page", `${page}`);
|
let updatedPath = "";
|
||||||
window.location.href = `${pathName}/page/${page}/?${searchParams}`;
|
if (pathName.includes("/page")) {
|
||||||
|
updatedPath = pathName.replace(/\/page\/\d+/, `/page/${page}`);
|
||||||
|
} else {
|
||||||
|
updatedPath = `${pathName}/page/${page}`;
|
||||||
|
}
|
||||||
|
window.location.href = `${updatedPath}?${searchParams}`;
|
||||||
} else {
|
} else {
|
||||||
searchParams.set("page", `${page}`);
|
searchParams.set("page", `${page}`);
|
||||||
window.location.href = `${pathName}/?${searchParams}`;
|
window.location.href = `${pathName}/?${searchParams}`;
|
||||||
|
@ -5,10 +5,10 @@ import { getPayload, Where } from "payload";
|
|||||||
type FetchBlogParams = {
|
type FetchBlogParams = {
|
||||||
page?: number;
|
page?: number;
|
||||||
search?: string;
|
search?: string;
|
||||||
categorySlug?: string;
|
categoryId?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function fetchBlog({ page, search = "", categorySlug = "" }: FetchBlogParams = {}) {
|
export async function fetchBlog({ page, search = "", categoryId }: FetchBlogParams = {}) {
|
||||||
const payload = await getPayload({ config: payloadConfig });
|
const payload = await getPayload({ config: payloadConfig });
|
||||||
|
|
||||||
const queryCondition: Where = {};
|
const queryCondition: Where = {};
|
||||||
@ -17,9 +17,9 @@ export async function fetchBlog({ page, search = "", categorySlug = "" }: FetchB
|
|||||||
contains: search,
|
contains: search,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (!!categorySlug) {
|
if (!!categoryId) {
|
||||||
queryCondition["categories"] = {
|
queryCondition["categories"] = {
|
||||||
equals: 9,
|
equals: categoryId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,3 +70,19 @@ export async function fetchBlogDetail(slug: string | undefined) {
|
|||||||
imgUrl,
|
imgUrl,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchBlogCategoryBySlug(slug: string) {
|
||||||
|
const payload = await getPayload({ config: payloadConfig });
|
||||||
|
const category = await payload.find({
|
||||||
|
collection: "blogCategories",
|
||||||
|
where: {
|
||||||
|
slug: { equals: slug },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!category?.docs?.[0]) return null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: category.docs[0],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -21,7 +21,6 @@ export async function getDefaultMetadata(): Promise<Metadata> {
|
|||||||
},
|
},
|
||||||
openGraph: {
|
openGraph: {
|
||||||
siteName,
|
siteName,
|
||||||
title: siteName,
|
|
||||||
description: metaDesc,
|
description: metaDesc,
|
||||||
type: "website",
|
type: "website",
|
||||||
locale: "en_US",
|
locale: "en_US",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user