From bada44fec3090676c7377d24e1995b30591d8fb1 Mon Sep 17 00:00:00 2001 From: Brian Nelson Date: Tue, 21 Oct 2025 12:38:50 -0400 Subject: [PATCH] data fetching --- bun.lock | 7 +++ package.json | 1 + src/app/(frontend)/[slug]/page.tsx | 7 +++ src/app/(frontend)/globals.css | 4 ++ src/app/(frontend)/page.tsx | 2 +- src/app/(frontend)/projects/[slug]/page.tsx | 31 +++++++++++ src/components/RichTextComponents.tsx | 57 +++++++++++++++++++++ utilities/queries.ts | 16 +++++- 8 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 src/app/(frontend)/[slug]/page.tsx create mode 100644 src/app/(frontend)/projects/[slug]/page.tsx create mode 100644 src/components/RichTextComponents.tsx diff --git a/bun.lock b/bun.lock index 964b043..a123208 100644 --- a/bun.lock +++ b/bun.lock @@ -11,6 +11,7 @@ "@payloadcms/plugin-seo": "^3.59.1", "@payloadcms/richtext-lexical": "3.59.1", "@payloadcms/ui": "3.59.1", + "@portabletext/react": "^4.0.3", "@radix-ui/react-slot": "^1.2.3", "@tailwindcss/postcss": "^4.1.14", "class-variance-authority": "^0.7.1", @@ -497,6 +498,12 @@ "@playwright/test": ["@playwright/test@1.54.1", "", { "dependencies": { "playwright": "1.54.1" }, "bin": { "playwright": "cli.js" } }, "sha512-FS8hQ12acieG2dYSksmLOF7BNxnVf2afRJdCuM1eMSxj6QTSE6G4InGF7oApGgDb65MX7AwMVlIkpru0yZA4Xw=="], + "@portabletext/react": ["@portabletext/react@4.0.3", "", { "dependencies": { "@portabletext/toolkit": "^3.0.1", "@portabletext/types": "^2.0.15" }, "peerDependencies": { "react": "^18.2 || ^19" } }, "sha512-sdVSXbi0L5MBVb1Ch5KwbBPZjW/Oqe6s5ZkPi4LcItzHl8rqY2jB0VxsFaGywZyn8Jc47cGLaOtyBM9HkW/9Hg=="], + + "@portabletext/toolkit": ["@portabletext/toolkit@3.0.1", "", { "dependencies": { "@portabletext/types": "^2.0.15" } }, "sha512-z8NGqxKxfP0zuC58hPe8+xFC17qSbQ3nC9DgZmhrr7NUFaENJ6vAHJBsH5QzT7nKUjj++dTn+i4O2Uz9cqiGjA=="], + + "@portabletext/types": ["@portabletext/types@2.0.15", "", {}, "sha512-2e6i2gSQsrA/5OL5Gm4/9bxB9MNO73Fa47zj+0mT93xkoQUCGCWX5fZh1YBJ86hszaRYlqvqG08oULxvvPPp/Q=="], + "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], diff --git a/package.json b/package.json index 9953110..aaad988 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@payloadcms/plugin-seo": "^3.59.1", "@payloadcms/richtext-lexical": "3.59.1", "@payloadcms/ui": "3.59.1", + "@portabletext/react": "^4.0.3", "@radix-ui/react-slot": "^1.2.3", "@tailwindcss/postcss": "^4.1.14", "class-variance-authority": "^0.7.1", diff --git a/src/app/(frontend)/[slug]/page.tsx b/src/app/(frontend)/[slug]/page.tsx new file mode 100644 index 0000000..5bbee00 --- /dev/null +++ b/src/app/(frontend)/[slug]/page.tsx @@ -0,0 +1,7 @@ +import React from 'react' + +export default function SinglePage() { + return ( +
SinglePage
+ ) +} diff --git a/src/app/(frontend)/globals.css b/src/app/(frontend)/globals.css index 238e915..385ed45 100644 --- a/src/app/(frontend)/globals.css +++ b/src/app/(frontend)/globals.css @@ -164,3 +164,7 @@ svg { } } } + +h2 { + @apply text-3xl font-bold +} \ No newline at end of file diff --git a/src/app/(frontend)/page.tsx b/src/app/(frontend)/page.tsx index 81db63c..e709f85 100644 --- a/src/app/(frontend)/page.tsx +++ b/src/app/(frontend)/page.tsx @@ -90,7 +90,7 @@ export default async function HomePage() { .filter((item) => !item.featuredProject) .map((item) => (
- +

{item.title}

{item.description}

diff --git a/src/app/(frontend)/projects/[slug]/page.tsx b/src/app/(frontend)/projects/[slug]/page.tsx new file mode 100644 index 0000000..de883dc --- /dev/null +++ b/src/app/(frontend)/projects/[slug]/page.tsx @@ -0,0 +1,31 @@ +import { SINGLE_PROJECT_QUERY } from '@/utilities/queries' +import React from 'react' +import { PortableText } from "@portabletext/react" +import { RichTextComponent } from '@/src/components/RichTextComponents' +import Image from 'next/image' +import { RichText } from '@payloadcms/richtext-lexical/react' + +export default async function SingleProjectPage({ params }: { params: { slug: string } }) { + const fetchData = await SINGLE_PROJECT_QUERY(params.slug) + const pageData = fetchData.docs[0]; + // console.log(pageData) + + return ( +
+

{pageData.title}

+ {pageData.featuredImage && ( + {pageData.featuredImage.alt} + )} +
+ {pageData.richText && ( + + )} +
+
+ ) +} diff --git a/src/components/RichTextComponents.tsx b/src/components/RichTextComponents.tsx new file mode 100644 index 0000000..1bbd810 --- /dev/null +++ b/src/components/RichTextComponents.tsx @@ -0,0 +1,57 @@ +import Image from 'next/image'; +import Link from 'next/link'; + +export const RichTextComponent: any = { + types: { + image: ({ value }: any) => { + return ( +
+ {/* {value.alt} */} +
+ ); + }, + }, + list: { + bullet: ({ children }: any) => { + + }, + number: ({ children }: any) => { +
    {children}
+ }, + }, + block: { + // Ex. 1: customizing common block types + h1: ({children}: any) =>

{children}

, + h2: ({ children }: any) =>

{children}

, + h3: ({ children }: any) =>

{children}

, + h4: ({ children }: any) =>

{children}

, + blockquote: ({ children }: any) => ( +
+ {children} +
+ ), + normal: ({children}: any) =>

{children}

+ }, + marks: { + link: ({ children, value }: any) => { + const rel = !value.href.startsWith("") + ? "noreferrer noopener" + : undefined; + + return ( + + {children} + + ) + } + } +} diff --git a/utilities/queries.ts b/utilities/queries.ts index 9b71213..d478aa6 100644 --- a/utilities/queries.ts +++ b/utilities/queries.ts @@ -24,6 +24,18 @@ export const PROJECT_QUERY = await payload.find({ order: true, categories: true, featuredProject: true, - }, + }, sort: '-order' -}) \ No newline at end of file +}) + +export const SINGLE_PROJECT_QUERY = async (slug: string) => { + return await payload.find({ + collection: 'projects', + where: { + slug: { + equals: slug + } + }, + limit: 1 + } +)} \ No newline at end of file