feat: OurTeam block component & fetching
This commit is contained in:
parent
ba04b73c4f
commit
2f7303d000
BIN
public/assets/images/hero-default.webp
Normal file
BIN
public/assets/images/hero-default.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 244 KiB |
@ -4,8 +4,8 @@ import Image from "next/image";
|
|||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
title: "Page | Cochise Oncology",
|
title: "Cochise Oncology",
|
||||||
description: "Page | Cochise Oncology",
|
description: "Cochise Oncology",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async function CustomPage({ params }: { params?: Promise<{ pageslug?: string }> }) {
|
export default async function CustomPage({ params }: { params?: Promise<{ pageslug?: string }> }) {
|
||||||
|
13
src/blocks/OurTeam.ts
Normal file
13
src/blocks/OurTeam.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { Block } from "payload";
|
||||||
|
|
||||||
|
export const OurTeamBlock: Block = {
|
||||||
|
slug: "ourTeamBlock",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "team",
|
||||||
|
type: "relationship",
|
||||||
|
relationTo: "teams",
|
||||||
|
hasMany: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
@ -1,5 +1,6 @@
|
|||||||
import { BeforeFooterBlock } from "@/blocks/BeforeFooter";
|
import { BeforeFooterBlock } from "@/blocks/BeforeFooter";
|
||||||
import { ContentBlock } from "@/blocks/Content";
|
import { ContentBlock } from "@/blocks/Content";
|
||||||
|
import { OurTeamBlock } from "@/blocks/OurTeam";
|
||||||
import formatSlug from "@/utils/formatSlug";
|
import formatSlug from "@/utils/formatSlug";
|
||||||
import { CollectionConfig } from "payload";
|
import { CollectionConfig } from "payload";
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ export const Pages: CollectionConfig = {
|
|||||||
label: "Page Layout",
|
label: "Page Layout",
|
||||||
type: "blocks",
|
type: "blocks",
|
||||||
minRows: 1,
|
minRows: 1,
|
||||||
blocks: [ContentBlock, BeforeFooterBlock],
|
blocks: [ContentBlock, BeforeFooterBlock, OurTeamBlock],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "meta",
|
name: "meta",
|
||||||
|
34
src/collections/Teams.ts
Normal file
34
src/collections/Teams.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import type { CollectionConfig } from "payload";
|
||||||
|
import { lexicalEditor } from "@payloadcms/richtext-lexical";
|
||||||
|
|
||||||
|
export const Teams: CollectionConfig = {
|
||||||
|
slug: "teams",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
type: "text",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "role",
|
||||||
|
type: "text",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "img",
|
||||||
|
label: "Image",
|
||||||
|
type: "upload",
|
||||||
|
relationTo: "media",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "biography",
|
||||||
|
type: "richText",
|
||||||
|
editor: lexicalEditor({}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
admin: {
|
||||||
|
hideAPIURL: true,
|
||||||
|
useAsTitle: "name",
|
||||||
|
},
|
||||||
|
};
|
@ -10,10 +10,10 @@ export interface BeforeFooterBlockProps {
|
|||||||
export function BeforeFooterBlock({ title, description, buttonText }: BeforeFooterBlockProps) {
|
export function BeforeFooterBlock({ title, description, buttonText }: BeforeFooterBlockProps) {
|
||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
className={`page-section text-white text-center scrollSpysection bg-dark-1 light-content bg-scroll`}
|
className={`page-section text-white text-center scrollSpysection bg-dark-1 light-content bg-scroll relative`}
|
||||||
id="about"
|
id="about"
|
||||||
>
|
>
|
||||||
<div className="container mx-auto px-6">
|
<div className="container mx-auto px-6 z-50">
|
||||||
<h2 className="text-3xl font-bold mb-4">{title}</h2>
|
<h2 className="text-3xl font-bold mb-4">{title}</h2>
|
||||||
<p className="text-lg mb-6">{description}</p>
|
<p className="text-lg mb-6">{description}</p>
|
||||||
{!!buttonText && (
|
{!!buttonText && (
|
||||||
|
39
src/components/Blocks/OurTeam/index.tsx
Normal file
39
src/components/Blocks/OurTeam/index.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { CardTeam } from "@/components/Teams/CardTeam";
|
||||||
|
|
||||||
|
type Team = {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
role: string;
|
||||||
|
img: { url: string; alt: string };
|
||||||
|
biography: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface OurTeamProps {
|
||||||
|
team: Team[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function OurTeamBlock({ team }: OurTeamProps) {
|
||||||
|
return (
|
||||||
|
<section className="page-section bg-gray-light-1 relative">
|
||||||
|
{/* Decoration Circles */}
|
||||||
|
<div className="decoration-12" />
|
||||||
|
<div className="decoration-13" />
|
||||||
|
{/* End Decoration Circles */}
|
||||||
|
<div className="container mx-auto px-6 text-center">
|
||||||
|
<h2 className="text-4xl font-semibold text-gray-800 mb-8">Our Team</h2>
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
|
||||||
|
{team.map((member, idx) => (
|
||||||
|
<CardTeam
|
||||||
|
key={idx}
|
||||||
|
data={{
|
||||||
|
name: member.name,
|
||||||
|
img: member.img.url,
|
||||||
|
role: member.role,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
@ -3,10 +3,12 @@ import React, { Fragment } from "react";
|
|||||||
import type { Page } from "@/payload-types";
|
import type { Page } from "@/payload-types";
|
||||||
import { ContentBlock } from "./Content";
|
import { ContentBlock } from "./Content";
|
||||||
import { BeforeFooterBlock } from "./BeforeFooter";
|
import { BeforeFooterBlock } from "./BeforeFooter";
|
||||||
|
import { OurTeamBlock } from "./OurTeam";
|
||||||
|
|
||||||
const blockComponents = {
|
const blockComponents = {
|
||||||
contentBlock: ContentBlock,
|
contentBlock: ContentBlock,
|
||||||
beforeFooterBlock: BeforeFooterBlock,
|
beforeFooterBlock: BeforeFooterBlock,
|
||||||
|
ourTeamBlock: OurTeamBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RenderBlocks: React.FC<{
|
export const RenderBlocks: React.FC<{
|
||||||
|
@ -30,9 +30,9 @@ export default async function Page({ slug }: PageProps) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!page?.heroImg?.url && (
|
{!page?.heroImg?.url && (
|
||||||
<div className="absolute top-0 left-0 w-full h-full opacity-003">
|
<div className="absolute top-0 left-0 w-full h-full opacity-20">
|
||||||
<Image
|
<Image
|
||||||
src="/assets/images/demo-fancy/bg-shape-1.svg"
|
src="/assets/images/hero-default.webp"
|
||||||
width="0"
|
width="0"
|
||||||
height="0"
|
height="0"
|
||||||
sizes="100vw"
|
sizes="100vw"
|
||||||
|
27
src/components/Teams/CardTeam.tsx
Normal file
27
src/components/Teams/CardTeam.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
|
export interface CardTeamProps {
|
||||||
|
data: {
|
||||||
|
name: string;
|
||||||
|
role: string;
|
||||||
|
img: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CardTeam({ data }: CardTeamProps) {
|
||||||
|
return (
|
||||||
|
<div className="bg-white p-6 rounded-lg shadow-md">
|
||||||
|
<Image
|
||||||
|
src={data.img}
|
||||||
|
alt={data.name}
|
||||||
|
width={80}
|
||||||
|
height={80}
|
||||||
|
className="rounded-full object-cover mx-auto"
|
||||||
|
style={{ width: "80px", height: "80px" }}
|
||||||
|
/>
|
||||||
|
<h3 className="mt-4 text-lg font-medium text-gray-900">{data.name}</h3>
|
||||||
|
<p className="text-gray-600">{data.role}</p>
|
||||||
|
<button className="bg-slate-400 rounded-full p-2 font-semibold text-slate-50 text-xs">BIOGRAPHY</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -15,6 +15,7 @@ export interface Config {
|
|||||||
media: Media;
|
media: Media;
|
||||||
blogs: Blog;
|
blogs: Blog;
|
||||||
pages: Page;
|
pages: Page;
|
||||||
|
teams: Team;
|
||||||
forms: Form;
|
forms: Form;
|
||||||
'form-submissions': FormSubmission;
|
'form-submissions': FormSubmission;
|
||||||
'payload-locked-documents': PayloadLockedDocument;
|
'payload-locked-documents': PayloadLockedDocument;
|
||||||
@ -27,6 +28,7 @@ export interface Config {
|
|||||||
media: MediaSelect<false> | MediaSelect<true>;
|
media: MediaSelect<false> | MediaSelect<true>;
|
||||||
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>;
|
||||||
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>;
|
||||||
@ -168,6 +170,12 @@ export interface Page {
|
|||||||
blockName?: string | null;
|
blockName?: string | null;
|
||||||
blockType: 'beforeFooterBlock';
|
blockType: 'beforeFooterBlock';
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
team?: (number | Team)[] | null;
|
||||||
|
id?: string | null;
|
||||||
|
blockName?: string | null;
|
||||||
|
blockType: 'ourTeamBlock';
|
||||||
|
}
|
||||||
)[]
|
)[]
|
||||||
| null;
|
| null;
|
||||||
meta?: {
|
meta?: {
|
||||||
@ -178,6 +186,33 @@ export interface Page {
|
|||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "teams".
|
||||||
|
*/
|
||||||
|
export interface Team {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
role: string;
|
||||||
|
img: number | Media;
|
||||||
|
biography?: {
|
||||||
|
root: {
|
||||||
|
type: string;
|
||||||
|
children: {
|
||||||
|
type: string;
|
||||||
|
version: number;
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
direction: ('ltr' | 'rtl') | null;
|
||||||
|
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||||
|
indent: number;
|
||||||
|
version: number;
|
||||||
|
};
|
||||||
|
[k: string]: unknown;
|
||||||
|
} | null;
|
||||||
|
updatedAt: string;
|
||||||
|
createdAt: string;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "forms".
|
* via the `definition` "forms".
|
||||||
@ -371,6 +406,10 @@ export interface PayloadLockedDocument {
|
|||||||
relationTo: 'pages';
|
relationTo: 'pages';
|
||||||
value: number | Page;
|
value: number | Page;
|
||||||
} | null)
|
} | null)
|
||||||
|
| ({
|
||||||
|
relationTo: 'teams';
|
||||||
|
value: number | Team;
|
||||||
|
} | null)
|
||||||
| ({
|
| ({
|
||||||
relationTo: 'forms';
|
relationTo: 'forms';
|
||||||
value: number | Form;
|
value: number | Form;
|
||||||
@ -494,6 +533,13 @@ export interface PagesSelect<T extends boolean = true> {
|
|||||||
id?: T;
|
id?: T;
|
||||||
blockName?: T;
|
blockName?: T;
|
||||||
};
|
};
|
||||||
|
ourTeamBlock?:
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
team?: T;
|
||||||
|
id?: T;
|
||||||
|
blockName?: T;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
meta?:
|
meta?:
|
||||||
| T
|
| T
|
||||||
@ -505,6 +551,18 @@ export interface PagesSelect<T extends boolean = true> {
|
|||||||
updatedAt?: T;
|
updatedAt?: T;
|
||||||
createdAt?: T;
|
createdAt?: T;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "teams_select".
|
||||||
|
*/
|
||||||
|
export interface TeamsSelect<T extends boolean = true> {
|
||||||
|
name?: T;
|
||||||
|
role?: T;
|
||||||
|
img?: T;
|
||||||
|
biography?: 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".
|
||||||
|
@ -11,6 +11,7 @@ import { fileURLToPath } from "url";
|
|||||||
import { Blogs } from "@/collections/Blogs";
|
import { Blogs } from "@/collections/Blogs";
|
||||||
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 { Users } from "@/collections/Users";
|
import { Users } from "@/collections/Users";
|
||||||
import {
|
import {
|
||||||
BoldFeature,
|
BoldFeature,
|
||||||
@ -46,7 +47,7 @@ export default buildConfig({
|
|||||||
},
|
},
|
||||||
theme: "dark",
|
theme: "dark",
|
||||||
},
|
},
|
||||||
collections: [Users, Media, Blogs, Pages],
|
collections: [Users, Media, Blogs, Pages, Teams],
|
||||||
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"),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user