chore: handles live preview data (#3440)

This commit is contained in:
Jacob Fletcher
2023-10-05 10:14:57 -04:00
committed by GitHub
parent f989e02a85
commit 0ac36069bd
12 changed files with 588 additions and 20 deletions

View File

@@ -65,6 +65,59 @@ export default buildConfigWithDefaults({
name: 'slug',
type: 'text',
required: true,
admin: {
position: 'sidebar',
},
},
{
name: 'layout',
type: 'blocks',
blocks: [
{
slug: 'hero',
labels: {
singular: 'Hero',
plural: 'Hero',
},
fields: [
{
name: 'title',
type: 'text',
required: true,
},
{
name: 'description',
type: 'textarea',
required: true,
},
],
},
],
},
{
name: 'featuredPosts',
type: 'relationship',
relationTo: 'posts',
hasMany: true,
},
],
},
{
slug: 'posts',
access: {
read: () => true,
create: () => true,
update: () => true,
delete: () => true,
},
admin: {
useAsTitle: 'title',
},
fields: [
{
name: 'title',
type: 'text',
required: true,
},
],
},
@@ -78,12 +131,27 @@ export default buildConfigWithDefaults({
},
})
const post1 = await payload.create({
collection: 'posts',
data: {
title: 'Post 1',
},
})
await payload.create({
collection: slug,
data: {
title: 'Hello, world!',
description: 'This is an example of live preview.',
slug: 'home',
layout: [
{
blockType: 'hero',
title: 'Hello, world!',
description: 'This is an example of live preview.',
},
],
featuredPosts: [post1.id],
},
})
},

View File

@@ -1,11 +1,8 @@
export type PageType = {
title?: string
description?: string
}
import { Page } from '@/payload-types'
export const PAYLOAD_SERVER_URL = 'http://localhost:3000'
export const getPage = async (slug: string): Promise<PageType> => {
export const getPage = async (slug: string): Promise<Page> => {
return await fetch(`http://localhost:3000/api/pages?where[slug][equals]=${slug}`, {
method: 'GET',
cache: 'no-store',

View File

@@ -2,11 +2,12 @@
import React, { Fragment } from 'react'
import styles from './page.module.css'
import { PAYLOAD_SERVER_URL, PageType } from './api'
import { PAYLOAD_SERVER_URL } from './api'
// The `useLivePreview` hook is imported from the monorepo for development purposes only
// in your own app you would import this hook directly from the payload package itself
// i.e. `import { useLivePreview } from 'payload'`
import { useLivePreview } from '../../../../packages/payload/src/admin/components/views/LivePreview/useLivePreview'
import { Page as PageType } from '@/payload-types'
export type Props = {
initialPage: PageType
@@ -14,15 +15,48 @@ export type Props = {
export const Page: React.FC<Props> = (props) => {
const { initialPage } = props
const { data, isLoading } = useLivePreview({ initialPage, serverURL: PAYLOAD_SERVER_URL })
const { data, isLoading } = useLivePreview<PageType>({
initialPage,
serverURL: PAYLOAD_SERVER_URL,
})
return (
<main className={styles.main}>
{isLoading && <Fragment>Loading...</Fragment>}
{!isLoading && (
<Fragment>
<h1>{data?.title}</h1>
<p>{data?.description}</p>
<h1>{data.title}</h1>
<p>{data.description}</p>
{data.layout && (
<div>
<p>Blocks</p>
<div className={styles.blocks}>
{data.layout.map((block, index) => {
const { title, description } = block
return (
<div key={index}>
<h2>{title}</h2>
<p>{description}</p>
</div>
)
})}
</div>
</div>
)}
<br />
<hr />
<br />
{data.featuredPosts && (
<div>
<p>Featured Posts</p>
<ul className={styles['featured-posts']}>
{data.featuredPosts.map((post, index) => (
<li key={index}>{typeof post === 'string' ? post : post.id}</li>
))}
</ul>
</div>
)}
</Fragment>
)}
</main>

View File

@@ -10,3 +10,9 @@
.main > *:last-child {
margin-bottom: 0;
}
.featured-posts {
margin: 0;
padding: 0;
list-style: none;
}

View File

@@ -1,6 +1,24 @@
import { getPage } from './api'
import { Page } from './page.client'
import { notFound } from 'next/navigation'
import type { Metadata, ResolvingMetadata } from 'next'
type Props = {
params: { id: string }
searchParams: { [key: string]: string | string[] | undefined }
}
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata,
): Promise<Metadata> {
const page = await getPage('home')
return {
title: page.title,
description: page.description,
}
}
export default async function Home() {
const page = await getPage('home')

View File

@@ -0,0 +1,100 @@
/* tslint:disable */
/* eslint-disable */
/**
* This file was automatically generated by Payload.
* DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,
* and re-run `payload generate:types` to regenerate this file.
*/
export interface Config {
collections: {
users: User
pages: Page
posts: Post
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}
globals: {}
}
export interface User {
id: string
updatedAt: string
createdAt: string
email: string
resetPasswordToken?: string
resetPasswordExpiration?: string
salt?: string
hash?: string
loginAttempts?: number
lockUntil?: string
password?: string
}
export interface Page {
id: string
title: string
description: string
slug: string
layout?: {
title: string
description: string
id?: string
blockName?: string
blockType: 'hero'
}[]
featuredPosts?: string[] | Post[]
updatedAt: string
createdAt: string
}
export interface Post {
id: string
title: string
updatedAt: string
createdAt: string
}
export interface PayloadPreference {
id: string
user: {
relationTo: 'users'
value: string | User
}
key?: string
value?:
| {
[k: string]: unknown
}
| unknown[]
| string
| number
| boolean
| null
updatedAt: string
createdAt: string
}
export interface PayloadMigration {
id: string
name?: string
batch?: number
schema?:
| {
[k: string]: unknown
}
| unknown[]
| string
| number
| boolean
| null
updatedAt: string
createdAt: string
}
declare module 'payload' {
export interface GeneratedTypes {
collections: {
users: User
pages: Page
posts: Post
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}
}
}

View File

@@ -10,6 +10,7 @@ export interface Config {
collections: {
users: User
pages: Page
posts: Post
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}
@@ -33,6 +34,20 @@ export interface Page {
title: string
description: string
slug: string
layout?: {
title: string
description: string
id?: string
blockName?: string
blockType: 'hero'
}[]
featuredPosts?: string[] | Post[]
updatedAt: string
createdAt: string
}
export interface Post {
id: string
title: string
updatedAt: string
createdAt: string
}
@@ -77,6 +92,7 @@ declare module 'payload' {
collections: {
users: User
pages: Page
posts: Post
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}