feat(blogs): restructure and add CTA section
This commit is contained in:
parent
3433d3a597
commit
27f9c83e8e
@ -1,3 +1,4 @@
|
|||||||
|
import { BeforeFooterBlock } from "@/components/Blocks/BeforeFooter";
|
||||||
import BlogDetail, { BlogDetailContentSkeleton } from "@/components/Blogs/BlogDetail";
|
import BlogDetail, { BlogDetailContentSkeleton } from "@/components/Blogs/BlogDetail";
|
||||||
import { fetchBlogDetail } from "@/services/payload/blog";
|
import { fetchBlogDetail } from "@/services/payload/blog";
|
||||||
import { Metadata } from "next";
|
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 {
|
return {
|
||||||
title: title,
|
title: title,
|
||||||
description: title,
|
description: description,
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: title,
|
title: title,
|
||||||
description: title,
|
description: description,
|
||||||
images: [{ url: blog.imgUrl }],
|
images: [{ url: blog.imgUrl }],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -40,6 +42,7 @@ export default async function SingleBlogPage({ params }: { params: Promise<{ slu
|
|||||||
<>
|
<>
|
||||||
<Suspense fallback={<Loading />}>
|
<Suspense fallback={<Loading />}>
|
||||||
<BlogDetail slug={slug} />
|
<BlogDetail slug={slug} />
|
||||||
|
<BeforeFooterBlock />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
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 { sanitizePageNumber } from "@/utils/sanitize";
|
import { sanitizePageNumber } from "@/utils/sanitize";
|
||||||
@ -5,8 +6,8 @@ import Image from "next/image";
|
|||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
title: "Blogs | Cochise Oncology",
|
title: "Blog - Cochise Oncology",
|
||||||
description: "Blogs | Cochise Oncology",
|
description: "Blog - Cochise Oncology",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async function BlogPage({ searchParams }: { searchParams?: Promise<{ page?: string }> }) {
|
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} />
|
<Blogs page={page} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<BeforeFooterBlock />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
28
src/collections/BlogCategories.ts
Normal file
28
src/collections/BlogCategories.ts
Normal 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",
|
||||||
|
},
|
||||||
|
};
|
32
src/collections/BlogTags.tsx
Normal file
32
src/collections/BlogTags.tsx
Normal 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",
|
||||||
|
},
|
||||||
|
};
|
@ -4,6 +4,7 @@ import formatSlug from "@/utils/formatSlug";
|
|||||||
|
|
||||||
export const Blogs: CollectionConfig = {
|
export const Blogs: CollectionConfig = {
|
||||||
slug: "blogs",
|
slug: "blogs",
|
||||||
|
labels: { plural: "Posts", singular: "Post" },
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: "title",
|
name: "title",
|
||||||
@ -13,9 +14,6 @@ export const Blogs: CollectionConfig = {
|
|||||||
{
|
{
|
||||||
name: "slug",
|
name: "slug",
|
||||||
type: "text",
|
type: "text",
|
||||||
admin: {
|
|
||||||
position: "sidebar",
|
|
||||||
},
|
|
||||||
hooks: {
|
hooks: {
|
||||||
beforeValidate: [formatSlug("title")],
|
beforeValidate: [formatSlug("title")],
|
||||||
},
|
},
|
||||||
@ -33,8 +31,47 @@ export const Blogs: CollectionConfig = {
|
|||||||
required: true,
|
required: true,
|
||||||
editor: lexicalEditor({}),
|
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: {
|
admin: {
|
||||||
hideAPIURL: true,
|
hideAPIURL: true,
|
||||||
|
group: "Blogs",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -54,11 +54,6 @@ export const Pages: CollectionConfig = {
|
|||||||
label: "Description",
|
label: "Description",
|
||||||
type: "textarea",
|
type: "textarea",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "keywords",
|
|
||||||
label: "Keywords",
|
|
||||||
type: "text",
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -70,6 +70,8 @@ export interface Config {
|
|||||||
blogs: Blog;
|
blogs: Blog;
|
||||||
pages: Page;
|
pages: Page;
|
||||||
teams: Team;
|
teams: Team;
|
||||||
|
blogCategories: BlogCategory;
|
||||||
|
blogTags: BlogTag;
|
||||||
forms: Form;
|
forms: Form;
|
||||||
'form-submissions': FormSubmission;
|
'form-submissions': FormSubmission;
|
||||||
'payload-locked-documents': PayloadLockedDocument;
|
'payload-locked-documents': PayloadLockedDocument;
|
||||||
@ -83,6 +85,8 @@ export interface Config {
|
|||||||
blogs: BlogsSelect<false> | BlogsSelect<true>;
|
blogs: BlogsSelect<false> | BlogsSelect<true>;
|
||||||
pages: PagesSelect<false> | PagesSelect<true>;
|
pages: PagesSelect<false> | PagesSelect<true>;
|
||||||
teams: TeamsSelect<false> | TeamsSelect<true>;
|
teams: TeamsSelect<false> | TeamsSelect<true>;
|
||||||
|
blogCategories: BlogCategoriesSelect<false> | BlogCategoriesSelect<true>;
|
||||||
|
blogTags: BlogTagsSelect<false> | BlogTagsSelect<true>;
|
||||||
forms: FormsSelect<false> | FormsSelect<true>;
|
forms: FormsSelect<false> | FormsSelect<true>;
|
||||||
'form-submissions': FormSubmissionsSelect<false> | FormSubmissionsSelect<true>;
|
'form-submissions': FormSubmissionsSelect<false> | FormSubmissionsSelect<true>;
|
||||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||||
@ -182,6 +186,36 @@ export interface Blog {
|
|||||||
};
|
};
|
||||||
[k: string]: unknown;
|
[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;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
}
|
}
|
||||||
@ -267,7 +301,6 @@ export interface Page {
|
|||||||
meta?: {
|
meta?: {
|
||||||
title?: string | null;
|
title?: string | null;
|
||||||
description?: string | null;
|
description?: string | null;
|
||||||
keywords?: string | null;
|
|
||||||
};
|
};
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
@ -496,6 +529,14 @@ export interface PayloadLockedDocument {
|
|||||||
relationTo: 'teams';
|
relationTo: 'teams';
|
||||||
value: number | Team;
|
value: number | Team;
|
||||||
} | null)
|
} | null)
|
||||||
|
| ({
|
||||||
|
relationTo: 'blogCategories';
|
||||||
|
value: number | BlogCategory;
|
||||||
|
} | null)
|
||||||
|
| ({
|
||||||
|
relationTo: 'blogTags';
|
||||||
|
value: number | BlogTag;
|
||||||
|
} | null)
|
||||||
| ({
|
| ({
|
||||||
relationTo: 'forms';
|
relationTo: 'forms';
|
||||||
value: number | Form;
|
value: number | Form;
|
||||||
@ -589,6 +630,15 @@ export interface BlogsSelect<T extends boolean = true> {
|
|||||||
slug?: T;
|
slug?: T;
|
||||||
img?: T;
|
img?: T;
|
||||||
content?: T;
|
content?: T;
|
||||||
|
categories?: T;
|
||||||
|
tags?: T;
|
||||||
|
meta?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
title?: T;
|
||||||
|
description?: T;
|
||||||
|
};
|
||||||
|
is_published?: T;
|
||||||
updatedAt?: T;
|
updatedAt?: T;
|
||||||
createdAt?: T;
|
createdAt?: T;
|
||||||
}
|
}
|
||||||
@ -652,7 +702,6 @@ export interface PagesSelect<T extends boolean = true> {
|
|||||||
| {
|
| {
|
||||||
title?: T;
|
title?: T;
|
||||||
description?: T;
|
description?: T;
|
||||||
keywords?: T;
|
|
||||||
};
|
};
|
||||||
updatedAt?: T;
|
updatedAt?: T;
|
||||||
createdAt?: T;
|
createdAt?: T;
|
||||||
@ -669,6 +718,27 @@ export interface TeamsSelect<T extends boolean = true> {
|
|||||||
updatedAt?: T;
|
updatedAt?: T;
|
||||||
createdAt?: 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
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "forms_select".
|
* via the `definition` "forms_select".
|
||||||
|
@ -8,7 +8,9 @@ import { buildConfig } from "payload";
|
|||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
|
|
||||||
|
import { BlogCategories } from "@/collections/BlogCategories";
|
||||||
import { Blogs } from "@/collections/Blogs";
|
import { Blogs } from "@/collections/Blogs";
|
||||||
|
import { BlogTags } from "@/collections/BlogTags";
|
||||||
import { Media } from "@/collections/Media";
|
import { Media } from "@/collections/Media";
|
||||||
import { Pages } from "@/collections/Pages";
|
import { Pages } from "@/collections/Pages";
|
||||||
import { Teams } from "@/collections/Teams";
|
import { Teams } from "@/collections/Teams";
|
||||||
@ -47,7 +49,7 @@ export default buildConfig({
|
|||||||
},
|
},
|
||||||
theme: "dark",
|
theme: "dark",
|
||||||
},
|
},
|
||||||
collections: [Users, Media, Blogs, Pages, Teams],
|
collections: [Users, Media, Blogs, Pages, Teams, BlogCategories, BlogTags],
|
||||||
secret: process.env.PAYLOAD_SECRET || "",
|
secret: process.env.PAYLOAD_SECRET || "",
|
||||||
typescript: {
|
typescript: {
|
||||||
outputFile: path.resolve(dirname, "payload-types.ts"),
|
outputFile: path.resolve(dirname, "payload-types.ts"),
|
||||||
|
@ -9,6 +9,11 @@ export async function fetchBlog(page: number | undefined) {
|
|||||||
page,
|
page,
|
||||||
pagination: true,
|
pagination: true,
|
||||||
limit: 6,
|
limit: 6,
|
||||||
|
where: {
|
||||||
|
is_published: {
|
||||||
|
equals: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const formattedData = blogDataQuery.docs.map((item) => {
|
const formattedData = blogDataQuery.docs.map((item) => {
|
||||||
@ -31,6 +36,9 @@ export async function fetchBlogDetail(slug: string) {
|
|||||||
collection: "blogs",
|
collection: "blogs",
|
||||||
where: {
|
where: {
|
||||||
slug: { equals: slug },
|
slug: { equals: slug },
|
||||||
|
is_published: {
|
||||||
|
equals: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
limit: 1,
|
limit: 1,
|
||||||
pagination: false,
|
pagination: false,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user