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";
|
||||
|
||||
export const metadata = {
|
||||
title: "Page | Cochise Oncology",
|
||||
description: "Page | Cochise Oncology",
|
||||
title: "Cochise Oncology",
|
||||
description: "Cochise Oncology",
|
||||
};
|
||||
|
||||
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 { ContentBlock } from "@/blocks/Content";
|
||||
import { OurTeamBlock } from "@/blocks/OurTeam";
|
||||
import formatSlug from "@/utils/formatSlug";
|
||||
import { CollectionConfig } from "payload";
|
||||
|
||||
@ -34,7 +35,7 @@ export const Pages: CollectionConfig = {
|
||||
label: "Page Layout",
|
||||
type: "blocks",
|
||||
minRows: 1,
|
||||
blocks: [ContentBlock, BeforeFooterBlock],
|
||||
blocks: [ContentBlock, BeforeFooterBlock, OurTeamBlock],
|
||||
},
|
||||
{
|
||||
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) {
|
||||
return (
|
||||
<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"
|
||||
>
|
||||
<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>
|
||||
<p className="text-lg mb-6">{description}</p>
|
||||
{!!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 { ContentBlock } from "./Content";
|
||||
import { BeforeFooterBlock } from "./BeforeFooter";
|
||||
import { OurTeamBlock } from "./OurTeam";
|
||||
|
||||
const blockComponents = {
|
||||
contentBlock: ContentBlock,
|
||||
beforeFooterBlock: BeforeFooterBlock,
|
||||
ourTeamBlock: OurTeamBlock,
|
||||
};
|
||||
|
||||
export const RenderBlocks: React.FC<{
|
||||
|
@ -30,9 +30,9 @@ export default async function Page({ slug }: PageProps) {
|
||||
</div>
|
||||
)}
|
||||
{!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
|
||||
src="/assets/images/demo-fancy/bg-shape-1.svg"
|
||||
src="/assets/images/hero-default.webp"
|
||||
width="0"
|
||||
height="0"
|
||||
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;
|
||||
blogs: Blog;
|
||||
pages: Page;
|
||||
teams: Team;
|
||||
forms: Form;
|
||||
'form-submissions': FormSubmission;
|
||||
'payload-locked-documents': PayloadLockedDocument;
|
||||
@ -27,6 +28,7 @@ export interface Config {
|
||||
media: MediaSelect<false> | MediaSelect<true>;
|
||||
blogs: BlogsSelect<false> | BlogsSelect<true>;
|
||||
pages: PagesSelect<false> | PagesSelect<true>;
|
||||
teams: TeamsSelect<false> | TeamsSelect<true>;
|
||||
forms: FormsSelect<false> | FormsSelect<true>;
|
||||
'form-submissions': FormSubmissionsSelect<false> | FormSubmissionsSelect<true>;
|
||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||
@ -168,6 +170,12 @@ export interface Page {
|
||||
blockName?: string | null;
|
||||
blockType: 'beforeFooterBlock';
|
||||
}
|
||||
| {
|
||||
team?: (number | Team)[] | null;
|
||||
id?: string | null;
|
||||
blockName?: string | null;
|
||||
blockType: 'ourTeamBlock';
|
||||
}
|
||||
)[]
|
||||
| null;
|
||||
meta?: {
|
||||
@ -178,6 +186,33 @@ export interface Page {
|
||||
updatedAt: 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
|
||||
* via the `definition` "forms".
|
||||
@ -371,6 +406,10 @@ export interface PayloadLockedDocument {
|
||||
relationTo: 'pages';
|
||||
value: number | Page;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'teams';
|
||||
value: number | Team;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'forms';
|
||||
value: number | Form;
|
||||
@ -494,6 +533,13 @@ export interface PagesSelect<T extends boolean = true> {
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
ourTeamBlock?:
|
||||
| T
|
||||
| {
|
||||
team?: T;
|
||||
id?: T;
|
||||
blockName?: T;
|
||||
};
|
||||
};
|
||||
meta?:
|
||||
| T
|
||||
@ -505,6 +551,18 @@ export interface PagesSelect<T extends boolean = true> {
|
||||
updatedAt?: 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
|
||||
* via the `definition` "forms_select".
|
||||
|
@ -11,6 +11,7 @@ import { fileURLToPath } from "url";
|
||||
import { Blogs } from "@/collections/Blogs";
|
||||
import { Media } from "@/collections/Media";
|
||||
import { Pages } from "@/collections/Pages";
|
||||
import { Teams } from "@/collections/Teams";
|
||||
import { Users } from "@/collections/Users";
|
||||
import {
|
||||
BoldFeature,
|
||||
@ -46,7 +47,7 @@ export default buildConfig({
|
||||
},
|
||||
theme: "dark",
|
||||
},
|
||||
collections: [Users, Media, Blogs, Pages],
|
||||
collections: [Users, Media, Blogs, Pages, Teams],
|
||||
secret: process.env.PAYLOAD_SECRET || "",
|
||||
typescript: {
|
||||
outputFile: path.resolve(dirname, "payload-types.ts"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user