feat(blogs): restructure and add CTA section

This commit is contained in:
RizqiSyahrendra 2025-02-12 14:22:55 +07:00
parent 3433d3a597
commit 27f9c83e8e
9 changed files with 194 additions and 16 deletions

View File

@ -1,3 +1,4 @@
import { BeforeFooterBlock } from "@/components/Blocks/BeforeFooter";
import BlogDetail, { BlogDetailContentSkeleton } from "@/components/Blogs/BlogDetail";
import { fetchBlogDetail } from "@/services/payload/blog";
import { Metadata } from "next";
@ -20,14 +21,15 @@ export async function generateMetadata({ params }: { params: Promise<{ slug: str
};
}
const title = `${blog.data.title} - ${name}`;
const title = `${!!blog.data?.meta?.title ? blog.data?.meta?.title : blog.data.title} - ${name}`;
const description = `${!!blog.data?.meta?.description ? blog.data?.meta?.description : blog.data.title} - ${name}`;
return {
title: title,
description: title,
description: description,
openGraph: {
title: title,
description: title,
description: description,
images: [{ url: blog.imgUrl }],
},
};
@ -40,6 +42,7 @@ export default async function SingleBlogPage({ params }: { params: Promise<{ slu
<>
<Suspense fallback={<Loading />}>
<BlogDetail slug={slug} />
<BeforeFooterBlock />
</Suspense>
</>
);

View File

@ -1,3 +1,4 @@
import { BeforeFooterBlock } from "@/components/Blocks/BeforeFooter";
import { BlogCardItemSkeleton } from "@/components/Blogs/BlogCardItem";
import Blogs from "@/components/Blogs/Blogs";
import { sanitizePageNumber } from "@/utils/sanitize";
@ -5,8 +6,8 @@ import Image from "next/image";
import { Suspense } from "react";
export const metadata = {
title: "Blogs | Cochise Oncology",
description: "Blogs | Cochise Oncology",
title: "Blog - Cochise Oncology",
description: "Blog - Cochise Oncology",
};
export default async function BlogPage({ searchParams }: { searchParams?: Promise<{ page?: string }> }) {
@ -36,6 +37,8 @@ export default async function BlogPage({ searchParams }: { searchParams?: Promis
<Blogs page={page} />
</Suspense>
</section>
<BeforeFooterBlock />
</>
);
}

View File

@ -0,0 +1,28 @@
import formatSlug from "@/utils/formatSlug";
import type { CollectionConfig } from "payload";
export const BlogCategories: CollectionConfig = {
slug: "blogCategories",
labels: { plural: "Categories", singular: "Category" },
fields: [
{
name: "name",
type: "text",
required: true,
},
{
name: "slug",
type: "text",
admin: {
position: "sidebar",
},
hooks: {
beforeValidate: [formatSlug("title")],
},
},
],
admin: {
hideAPIURL: true,
group: "Blogs",
},
};

View File

@ -0,0 +1,32 @@
import formatSlug from "@/utils/formatSlug";
import type { CollectionConfig } from "payload";
export const BlogTags: CollectionConfig = {
slug: "blogTags",
labels: { plural: "Tags", singular: "Tag" },
fields: [
{
name: "name",
type: "text",
required: true,
},
{
name: "slug",
type: "text",
admin: {
position: "sidebar",
},
hooks: {
beforeValidate: [formatSlug("title")],
},
},
{
name: "description",
type: "textarea",
},
],
admin: {
hideAPIURL: true,
group: "Blogs",
},
};

View File

@ -4,6 +4,7 @@ import formatSlug from "@/utils/formatSlug";
export const Blogs: CollectionConfig = {
slug: "blogs",
labels: { plural: "Posts", singular: "Post" },
fields: [
{
name: "title",
@ -13,9 +14,6 @@ export const Blogs: CollectionConfig = {
{
name: "slug",
type: "text",
admin: {
position: "sidebar",
},
hooks: {
beforeValidate: [formatSlug("title")],
},
@ -33,8 +31,47 @@ export const Blogs: CollectionConfig = {
required: true,
editor: lexicalEditor({}),
},
{
name: "categories",
type: "relationship",
relationTo: "blogCategories",
hasMany: true,
},
{
name: "tags",
type: "relationship",
relationTo: "blogTags",
hasMany: true,
},
{
name: "meta",
label: "Page Meta",
type: "group",
fields: [
{
name: "title",
label: "Title",
type: "text",
},
{
name: "description",
label: "Description",
type: "textarea",
},
],
},
{
name: "is_published",
label: "Published",
type: "checkbox",
defaultValue: true,
admin: {
position: "sidebar",
},
},
],
admin: {
hideAPIURL: true,
group: "Blogs",
},
};

View File

@ -54,11 +54,6 @@ export const Pages: CollectionConfig = {
label: "Description",
type: "textarea",
},
{
name: "keywords",
label: "Keywords",
type: "text",
},
],
},
],

View File

@ -70,6 +70,8 @@ export interface Config {
blogs: Blog;
pages: Page;
teams: Team;
blogCategories: BlogCategory;
blogTags: BlogTag;
forms: Form;
'form-submissions': FormSubmission;
'payload-locked-documents': PayloadLockedDocument;
@ -83,6 +85,8 @@ export interface Config {
blogs: BlogsSelect<false> | BlogsSelect<true>;
pages: PagesSelect<false> | PagesSelect<true>;
teams: TeamsSelect<false> | TeamsSelect<true>;
blogCategories: BlogCategoriesSelect<false> | BlogCategoriesSelect<true>;
blogTags: BlogTagsSelect<false> | BlogTagsSelect<true>;
forms: FormsSelect<false> | FormsSelect<true>;
'form-submissions': FormSubmissionsSelect<false> | FormSubmissionsSelect<true>;
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
@ -182,6 +186,36 @@ export interface Blog {
};
[k: string]: unknown;
};
categories?: (number | BlogCategory)[] | null;
tags?: (number | BlogTag)[] | null;
meta?: {
title?: string | null;
description?: string | null;
};
is_published?: boolean | null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "blogCategories".
*/
export interface BlogCategory {
id: number;
name: string;
slug?: string | null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "blogTags".
*/
export interface BlogTag {
id: number;
name: string;
slug?: string | null;
description?: string | null;
updatedAt: string;
createdAt: string;
}
@ -267,7 +301,6 @@ export interface Page {
meta?: {
title?: string | null;
description?: string | null;
keywords?: string | null;
};
updatedAt: string;
createdAt: string;
@ -496,6 +529,14 @@ export interface PayloadLockedDocument {
relationTo: 'teams';
value: number | Team;
} | null)
| ({
relationTo: 'blogCategories';
value: number | BlogCategory;
} | null)
| ({
relationTo: 'blogTags';
value: number | BlogTag;
} | null)
| ({
relationTo: 'forms';
value: number | Form;
@ -589,6 +630,15 @@ export interface BlogsSelect<T extends boolean = true> {
slug?: T;
img?: T;
content?: T;
categories?: T;
tags?: T;
meta?:
| T
| {
title?: T;
description?: T;
};
is_published?: T;
updatedAt?: T;
createdAt?: T;
}
@ -652,7 +702,6 @@ export interface PagesSelect<T extends boolean = true> {
| {
title?: T;
description?: T;
keywords?: T;
};
updatedAt?: T;
createdAt?: T;
@ -669,6 +718,27 @@ export interface TeamsSelect<T extends boolean = true> {
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "blogCategories_select".
*/
export interface BlogCategoriesSelect<T extends boolean = true> {
name?: T;
slug?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "blogTags_select".
*/
export interface BlogTagsSelect<T extends boolean = true> {
name?: T;
slug?: T;
description?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "forms_select".

View File

@ -8,7 +8,9 @@ import { buildConfig } from "payload";
import sharp from "sharp";
import { fileURLToPath } from "url";
import { BlogCategories } from "@/collections/BlogCategories";
import { Blogs } from "@/collections/Blogs";
import { BlogTags } from "@/collections/BlogTags";
import { Media } from "@/collections/Media";
import { Pages } from "@/collections/Pages";
import { Teams } from "@/collections/Teams";
@ -47,7 +49,7 @@ export default buildConfig({
},
theme: "dark",
},
collections: [Users, Media, Blogs, Pages, Teams],
collections: [Users, Media, Blogs, Pages, Teams, BlogCategories, BlogTags],
secret: process.env.PAYLOAD_SECRET || "",
typescript: {
outputFile: path.resolve(dirname, "payload-types.ts"),

View File

@ -9,6 +9,11 @@ export async function fetchBlog(page: number | undefined) {
page,
pagination: true,
limit: 6,
where: {
is_published: {
equals: true,
},
},
});
const formattedData = blogDataQuery.docs.map((item) => {
@ -31,6 +36,9 @@ export async function fetchBlogDetail(slug: string) {
collection: "blogs",
where: {
slug: { equals: slug },
is_published: {
equals: true,
},
},
limit: 1,
pagination: false,