refactor: migrate to pnpm monorepo with Payload CMS backend and Astro frontend to support scalable website development and AI-assisted workflows
This commit is contained in:
111
apps/backend/src/endpoints/seed/contact-form.ts
Normal file
111
apps/backend/src/endpoints/seed/contact-form.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import { RequiredDataFromCollectionSlug } from 'payload'
|
||||
|
||||
export const contactForm: RequiredDataFromCollectionSlug<'forms'> = {
|
||||
confirmationMessage: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'The contact form has been submitted successfully.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h2',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
confirmationType: 'message',
|
||||
createdAt: '2023-01-12T21:47:41.374Z',
|
||||
emails: [
|
||||
{
|
||||
emailFrom: '"Payload" \u003Cdemo@payloadcms.com\u003E',
|
||||
emailTo: '{{email}}',
|
||||
message: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Your contact form submission was successfully received.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
subject: "You've received a new message.",
|
||||
},
|
||||
],
|
||||
fields: [
|
||||
{
|
||||
name: 'full-name',
|
||||
blockName: 'full-name',
|
||||
blockType: 'text',
|
||||
label: 'Full Name',
|
||||
required: true,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
name: 'email',
|
||||
blockName: 'email',
|
||||
blockType: 'email',
|
||||
label: 'Email',
|
||||
required: true,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
name: 'phone',
|
||||
blockName: 'phone',
|
||||
blockType: 'number',
|
||||
label: 'Phone',
|
||||
required: false,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
name: 'message',
|
||||
blockName: 'message',
|
||||
blockType: 'textarea',
|
||||
label: 'Message',
|
||||
required: true,
|
||||
width: 100,
|
||||
},
|
||||
],
|
||||
redirect: undefined,
|
||||
submitButtonLabel: 'Submit',
|
||||
title: 'Contact Form',
|
||||
updatedAt: '2023-01-12T21:47:41.374Z',
|
||||
}
|
||||
56
apps/backend/src/endpoints/seed/contact-page.ts
Normal file
56
apps/backend/src/endpoints/seed/contact-page.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import type { Form } from '@/payload-types'
|
||||
import { RequiredDataFromCollectionSlug } from 'payload'
|
||||
|
||||
type ContactArgs = {
|
||||
contactForm: Form
|
||||
}
|
||||
|
||||
export const contact: (args: ContactArgs) => RequiredDataFromCollectionSlug<'pages'> = ({
|
||||
contactForm,
|
||||
}) => {
|
||||
return {
|
||||
slug: 'contact',
|
||||
_status: 'published',
|
||||
hero: {
|
||||
type: 'none',
|
||||
},
|
||||
layout: [
|
||||
{
|
||||
blockType: 'formBlock',
|
||||
enableIntro: true,
|
||||
form: contactForm,
|
||||
introContent: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Example contact form:',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h3',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
title: 'Contact',
|
||||
}
|
||||
}
|
||||
88
apps/backend/src/endpoints/seed/home-static.ts
Normal file
88
apps/backend/src/endpoints/seed/home-static.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import type { RequiredDataFromCollectionSlug } from 'payload'
|
||||
|
||||
// Used for pre-seeded content so that the homepage is not empty
|
||||
export const homeStatic: RequiredDataFromCollectionSlug<'pages'> = {
|
||||
slug: 'home',
|
||||
_status: 'published',
|
||||
hero: {
|
||||
type: 'lowImpact',
|
||||
richText: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Payload Website Template',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h1',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'link',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Visit the admin dashboard',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
fields: {
|
||||
linkType: 'custom',
|
||||
newTab: false,
|
||||
url: '/admin',
|
||||
},
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: ' to make your account and seed content for your website.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
meta: {
|
||||
description: 'An open-source website built with Payload and Next.js.',
|
||||
title: 'Payload Website Template',
|
||||
},
|
||||
title: 'Home',
|
||||
layout: [],
|
||||
}
|
||||
675
apps/backend/src/endpoints/seed/home.ts
Normal file
675
apps/backend/src/endpoints/seed/home.ts
Normal file
@@ -0,0 +1,675 @@
|
||||
import type { RequiredDataFromCollectionSlug } from 'payload'
|
||||
import type { Media } from '@/payload-types'
|
||||
|
||||
type HomeArgs = {
|
||||
heroImage: Media
|
||||
metaImage: Media
|
||||
}
|
||||
|
||||
export const home: (args: HomeArgs) => RequiredDataFromCollectionSlug<'pages'> = ({
|
||||
heroImage,
|
||||
metaImage,
|
||||
}) => {
|
||||
return {
|
||||
slug: 'home',
|
||||
_status: 'published',
|
||||
hero: {
|
||||
type: 'highImpact',
|
||||
links: [
|
||||
{
|
||||
link: {
|
||||
type: 'custom',
|
||||
appearance: 'default',
|
||||
label: 'All posts',
|
||||
url: '/posts',
|
||||
},
|
||||
},
|
||||
{
|
||||
link: {
|
||||
type: 'custom',
|
||||
appearance: 'outline',
|
||||
label: 'Contact',
|
||||
url: '/contact',
|
||||
},
|
||||
},
|
||||
],
|
||||
media: heroImage.id,
|
||||
richText: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Payload Website Template',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h1',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'link',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Visit the admin dashboard',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
fields: {
|
||||
linkType: 'custom',
|
||||
newTab: false,
|
||||
url: '/admin',
|
||||
},
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 3,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: " to begin managing this site's content. The code for this template is completely open-source and can be found ",
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'on our Github',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
fields: {
|
||||
linkType: 'custom',
|
||||
newTab: true,
|
||||
url: 'https://github.com/payloadcms/payload/tree/main/templates/website',
|
||||
},
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 3,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: '. ',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
layout: [
|
||||
{
|
||||
blockName: 'Content Block',
|
||||
blockType: 'content',
|
||||
columns: [
|
||||
{
|
||||
richText: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Core features',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h2',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
size: 'full',
|
||||
},
|
||||
{
|
||||
enableLink: false,
|
||||
richText: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Admin Dashboard',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h3',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: "Manage this site's pages and posts from the ",
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'admin dashboard',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
fields: {
|
||||
linkType: 'custom',
|
||||
newTab: false,
|
||||
url: '/admin',
|
||||
},
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: '.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
size: 'oneThird',
|
||||
},
|
||||
{
|
||||
enableLink: false,
|
||||
richText: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Preview',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h3',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Using versions, drafts, and preview, editors can review and share their changes before publishing them.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
size: 'oneThird',
|
||||
},
|
||||
{
|
||||
enableLink: false,
|
||||
richText: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Page Builder',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h3',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Custom page builder allows you to create unique page, post, and project layouts for any type of content.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
size: 'oneThird',
|
||||
},
|
||||
{
|
||||
enableLink: false,
|
||||
richText: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'SEO',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h3',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Editors have complete control over SEO data and site content directly from the ',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'admin dashboard',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
fields: {
|
||||
linkType: 'custom',
|
||||
newTab: false,
|
||||
url: '/admin',
|
||||
},
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: '.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
size: 'oneThird',
|
||||
},
|
||||
{
|
||||
enableLink: false,
|
||||
richText: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Dark Mode',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h3',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Users will experience this site in their preferred color scheme and each block can be inverted.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
size: 'oneThird',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
blockName: 'Media Block',
|
||||
blockType: 'mediaBlock',
|
||||
media: metaImage.id,
|
||||
},
|
||||
{
|
||||
blockName: 'Archive Block',
|
||||
blockType: 'archive',
|
||||
categories: [],
|
||||
introContent: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Recent posts',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h3',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'The posts below are displayed in an "Archive" layout building block which is an extremely powerful way to display documents on a page. It can be auto-populated by collection or by category, or posts can be individually selected. Pagination controls will automatically appear if the number of results exceeds the number of items per page.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
populateBy: 'collection',
|
||||
relationTo: 'posts',
|
||||
},
|
||||
{
|
||||
blockName: 'CTA',
|
||||
blockType: 'cta',
|
||||
links: [
|
||||
{
|
||||
link: {
|
||||
type: 'custom',
|
||||
appearance: 'default',
|
||||
label: 'All posts',
|
||||
url: '/posts',
|
||||
},
|
||||
},
|
||||
],
|
||||
richText: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'This is a call to action',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h3',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'This is a custom layout building block ',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'configured in the admin dashboard',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
fields: {
|
||||
linkType: 'custom',
|
||||
newTab: false,
|
||||
url: '/admin',
|
||||
},
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: '.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
meta: {
|
||||
description: 'An open-source website built with Payload and Next.js.',
|
||||
image: heroImage.id,
|
||||
title: 'Payload Website Template',
|
||||
},
|
||||
title: 'Home',
|
||||
}
|
||||
}
|
||||
67
apps/backend/src/endpoints/seed/image-1.ts
Normal file
67
apps/backend/src/endpoints/seed/image-1.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import type { Media } from '@/payload-types'
|
||||
|
||||
export const image1: Omit<Media, 'createdAt' | 'id' | 'updatedAt'> = {
|
||||
alt: 'Curving abstract shapes with an orange and blue gradient',
|
||||
caption: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Photo by ',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Andrew Kliatskyi',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
fields: {
|
||||
linkType: 'custom',
|
||||
newTab: true,
|
||||
url: 'https://unsplash.com/@kirp',
|
||||
},
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: ' on Unsplash.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
67
apps/backend/src/endpoints/seed/image-2.ts
Normal file
67
apps/backend/src/endpoints/seed/image-2.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import type { Media } from '@/payload-types'
|
||||
|
||||
export const image2: Omit<Media, 'createdAt' | 'id' | 'updatedAt'> = {
|
||||
alt: 'Curving abstract shapes with an orange and blue gradient',
|
||||
caption: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Photo by ',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Andrew Kliatskyi',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
fields: {
|
||||
linkType: 'custom',
|
||||
newTab: true,
|
||||
url: 'https://unsplash.com/@kirp',
|
||||
},
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: ' on Unsplash.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
67
apps/backend/src/endpoints/seed/image-3.ts
Normal file
67
apps/backend/src/endpoints/seed/image-3.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import type { Media } from '@/payload-types'
|
||||
|
||||
export const image3: Omit<Media, 'createdAt' | 'id' | 'updatedAt'> = {
|
||||
alt: 'Straight metallic shapes with an orange and blue gradient',
|
||||
caption: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Photo by ',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Andrew Kliatskyi',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
fields: {
|
||||
linkType: 'custom',
|
||||
newTab: true,
|
||||
url: 'https://unsplash.com/@kirp',
|
||||
},
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: ' on Unsplash.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
5
apps/backend/src/endpoints/seed/image-hero-1.ts
Normal file
5
apps/backend/src/endpoints/seed/image-hero-1.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { Media } from '@/payload-types'
|
||||
|
||||
export const imageHero1: Omit<Media, 'createdAt' | 'id' | 'updatedAt'> = {
|
||||
alt: 'Straight metallic shapes with a blue gradient',
|
||||
}
|
||||
BIN
apps/backend/src/endpoints/seed/image-hero1.webp
Normal file
BIN
apps/backend/src/endpoints/seed/image-hero1.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 753 KiB |
BIN
apps/backend/src/endpoints/seed/image-post1.webp
Normal file
BIN
apps/backend/src/endpoints/seed/image-post1.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 115 KiB |
BIN
apps/backend/src/endpoints/seed/image-post2.webp
Normal file
BIN
apps/backend/src/endpoints/seed/image-post2.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 165 KiB |
BIN
apps/backend/src/endpoints/seed/image-post3.webp
Normal file
BIN
apps/backend/src/endpoints/seed/image-post3.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 110 KiB |
363
apps/backend/src/endpoints/seed/index.ts
Normal file
363
apps/backend/src/endpoints/seed/index.ts
Normal file
@@ -0,0 +1,363 @@
|
||||
import type { CollectionSlug, GlobalSlug, Payload, PayloadRequest, File } from 'payload'
|
||||
|
||||
import { contactForm as contactFormData } from './contact-form'
|
||||
import { contact as contactPageData } from './contact-page'
|
||||
import { home } from './home'
|
||||
import { image1 } from './image-1'
|
||||
import { image2 } from './image-2'
|
||||
import { imageHero1 } from './image-hero-1'
|
||||
import { post1 } from './post-1'
|
||||
import { post2 } from './post-2'
|
||||
import { post3 } from './post-3'
|
||||
|
||||
const collections: CollectionSlug[] = [
|
||||
'categories',
|
||||
'media',
|
||||
'pages',
|
||||
'posts',
|
||||
'forms',
|
||||
'form-submissions',
|
||||
'search',
|
||||
]
|
||||
const globals: GlobalSlug[] = ['header', 'footer']
|
||||
|
||||
// Next.js revalidation errors are normal when seeding the database without a server running
|
||||
// i.e. running `yarn seed` locally instead of using the admin UI within an active app
|
||||
// The app is not running to revalidate the pages and so the API routes are not available
|
||||
// These error messages can be ignored: `Error hitting revalidate route for...`
|
||||
export const seed = async ({
|
||||
payload,
|
||||
req,
|
||||
}: {
|
||||
payload: Payload
|
||||
req: PayloadRequest
|
||||
}): Promise<void> => {
|
||||
payload.logger.info('Seeding database...')
|
||||
|
||||
// we need to clear the media directory before seeding
|
||||
// as well as the collections and globals
|
||||
// this is because while `yarn seed` drops the database
|
||||
// the custom `/api/seed` endpoint does not
|
||||
payload.logger.info(`— Clearing collections and globals...`)
|
||||
|
||||
// clear the database
|
||||
await Promise.all(
|
||||
globals.map((global) =>
|
||||
payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
navItems: [],
|
||||
},
|
||||
depth: 0,
|
||||
context: {
|
||||
disableRevalidate: true,
|
||||
},
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
await Promise.all(
|
||||
collections.map((collection) => payload.db.deleteMany({ collection, req, where: {} })),
|
||||
)
|
||||
|
||||
await Promise.all(
|
||||
collections
|
||||
.filter((collection) => Boolean(payload.collections[collection].config.versions))
|
||||
.map((collection) => payload.db.deleteVersions({ collection, req, where: {} })),
|
||||
)
|
||||
|
||||
payload.logger.info(`— Seeding demo author and user...`)
|
||||
|
||||
await payload.delete({
|
||||
collection: 'users',
|
||||
depth: 0,
|
||||
where: {
|
||||
email: {
|
||||
equals: 'demo-author@example.com',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
payload.logger.info(`— Seeding media...`)
|
||||
|
||||
const [image1Buffer, image2Buffer, image3Buffer, hero1Buffer] = await Promise.all([
|
||||
fetchFileByURL(
|
||||
'https://raw.githubusercontent.com/payloadcms/payload/refs/heads/main/templates/website/src/endpoints/seed/image-post1.webp',
|
||||
),
|
||||
fetchFileByURL(
|
||||
'https://raw.githubusercontent.com/payloadcms/payload/refs/heads/main/templates/website/src/endpoints/seed/image-post2.webp',
|
||||
),
|
||||
fetchFileByURL(
|
||||
'https://raw.githubusercontent.com/payloadcms/payload/refs/heads/main/templates/website/src/endpoints/seed/image-post3.webp',
|
||||
),
|
||||
fetchFileByURL(
|
||||
'https://raw.githubusercontent.com/payloadcms/payload/refs/heads/main/templates/website/src/endpoints/seed/image-hero1.webp',
|
||||
),
|
||||
])
|
||||
|
||||
const [demoAuthor, image1Doc, image2Doc, image3Doc, imageHomeDoc] = await Promise.all([
|
||||
payload.create({
|
||||
collection: 'users',
|
||||
data: {
|
||||
name: 'Demo Author',
|
||||
email: 'demo-author@example.com',
|
||||
password: 'password',
|
||||
},
|
||||
}),
|
||||
payload.create({
|
||||
collection: 'media',
|
||||
data: image1,
|
||||
file: image1Buffer,
|
||||
}),
|
||||
payload.create({
|
||||
collection: 'media',
|
||||
data: image2,
|
||||
file: image2Buffer,
|
||||
}),
|
||||
payload.create({
|
||||
collection: 'media',
|
||||
data: image2,
|
||||
file: image3Buffer,
|
||||
}),
|
||||
payload.create({
|
||||
collection: 'media',
|
||||
data: imageHero1,
|
||||
file: hero1Buffer,
|
||||
}),
|
||||
|
||||
payload.create({
|
||||
collection: 'categories',
|
||||
data: {
|
||||
title: 'Technology',
|
||||
breadcrumbs: [
|
||||
{
|
||||
label: 'Technology',
|
||||
url: '/technology',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
|
||||
payload.create({
|
||||
collection: 'categories',
|
||||
data: {
|
||||
title: 'News',
|
||||
breadcrumbs: [
|
||||
{
|
||||
label: 'News',
|
||||
url: '/news',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
|
||||
payload.create({
|
||||
collection: 'categories',
|
||||
data: {
|
||||
title: 'Finance',
|
||||
breadcrumbs: [
|
||||
{
|
||||
label: 'Finance',
|
||||
url: '/finance',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
payload.create({
|
||||
collection: 'categories',
|
||||
data: {
|
||||
title: 'Design',
|
||||
breadcrumbs: [
|
||||
{
|
||||
label: 'Design',
|
||||
url: '/design',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
|
||||
payload.create({
|
||||
collection: 'categories',
|
||||
data: {
|
||||
title: 'Software',
|
||||
breadcrumbs: [
|
||||
{
|
||||
label: 'Software',
|
||||
url: '/software',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
|
||||
payload.create({
|
||||
collection: 'categories',
|
||||
data: {
|
||||
title: 'Engineering',
|
||||
breadcrumbs: [
|
||||
{
|
||||
label: 'Engineering',
|
||||
url: '/engineering',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
])
|
||||
|
||||
payload.logger.info(`— Seeding posts...`)
|
||||
|
||||
// Do not create posts with `Promise.all` because we want the posts to be created in order
|
||||
// This way we can sort them by `createdAt` or `publishedAt` and they will be in the expected order
|
||||
const post1Doc = await payload.create({
|
||||
collection: 'posts',
|
||||
depth: 0,
|
||||
context: {
|
||||
disableRevalidate: true,
|
||||
},
|
||||
data: post1({ heroImage: image1Doc, blockImage: image2Doc, author: demoAuthor }),
|
||||
})
|
||||
|
||||
const post2Doc = await payload.create({
|
||||
collection: 'posts',
|
||||
depth: 0,
|
||||
context: {
|
||||
disableRevalidate: true,
|
||||
},
|
||||
data: post2({ heroImage: image2Doc, blockImage: image3Doc, author: demoAuthor }),
|
||||
})
|
||||
|
||||
const post3Doc = await payload.create({
|
||||
collection: 'posts',
|
||||
depth: 0,
|
||||
context: {
|
||||
disableRevalidate: true,
|
||||
},
|
||||
data: post3({ heroImage: image3Doc, blockImage: image1Doc, author: demoAuthor }),
|
||||
})
|
||||
|
||||
// update each post with related posts
|
||||
await payload.update({
|
||||
id: post1Doc.id,
|
||||
collection: 'posts',
|
||||
data: {
|
||||
relatedPosts: [post2Doc.id, post3Doc.id],
|
||||
},
|
||||
})
|
||||
await payload.update({
|
||||
id: post2Doc.id,
|
||||
collection: 'posts',
|
||||
data: {
|
||||
relatedPosts: [post1Doc.id, post3Doc.id],
|
||||
},
|
||||
})
|
||||
await payload.update({
|
||||
id: post3Doc.id,
|
||||
collection: 'posts',
|
||||
data: {
|
||||
relatedPosts: [post1Doc.id, post2Doc.id],
|
||||
},
|
||||
})
|
||||
|
||||
payload.logger.info(`— Seeding contact form...`)
|
||||
|
||||
const contactForm = await payload.create({
|
||||
collection: 'forms',
|
||||
depth: 0,
|
||||
data: contactFormData,
|
||||
})
|
||||
|
||||
payload.logger.info(`— Seeding pages...`)
|
||||
|
||||
const [_, contactPage] = await Promise.all([
|
||||
payload.create({
|
||||
collection: 'pages',
|
||||
depth: 0,
|
||||
data: home({ heroImage: imageHomeDoc, metaImage: image2Doc }),
|
||||
}),
|
||||
payload.create({
|
||||
collection: 'pages',
|
||||
depth: 0,
|
||||
data: contactPageData({ contactForm: contactForm }),
|
||||
}),
|
||||
])
|
||||
|
||||
payload.logger.info(`— Seeding globals...`)
|
||||
|
||||
await Promise.all([
|
||||
payload.updateGlobal({
|
||||
slug: 'header',
|
||||
data: {
|
||||
navItems: [
|
||||
{
|
||||
link: {
|
||||
type: 'custom',
|
||||
label: 'Posts',
|
||||
url: '/posts',
|
||||
},
|
||||
},
|
||||
{
|
||||
link: {
|
||||
type: 'reference',
|
||||
label: 'Contact',
|
||||
reference: {
|
||||
relationTo: 'pages',
|
||||
value: contactPage.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
payload.updateGlobal({
|
||||
slug: 'footer',
|
||||
data: {
|
||||
navItems: [
|
||||
{
|
||||
link: {
|
||||
type: 'custom',
|
||||
label: 'Admin',
|
||||
url: '/admin',
|
||||
},
|
||||
},
|
||||
{
|
||||
link: {
|
||||
type: 'custom',
|
||||
label: 'Source Code',
|
||||
newTab: true,
|
||||
url: 'https://github.com/payloadcms/payload/tree/main/templates/website',
|
||||
},
|
||||
},
|
||||
{
|
||||
link: {
|
||||
type: 'custom',
|
||||
label: 'Payload',
|
||||
newTab: true,
|
||||
url: 'https://payloadcms.com/',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
])
|
||||
|
||||
payload.logger.info('Seeded database successfully!')
|
||||
}
|
||||
|
||||
async function fetchFileByURL(url: string): Promise<File> {
|
||||
const res = await fetch(url, {
|
||||
credentials: 'include',
|
||||
method: 'GET',
|
||||
})
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`Failed to fetch file from ${url}, status: ${res.status}`)
|
||||
}
|
||||
|
||||
const data = await res.arrayBuffer()
|
||||
|
||||
return {
|
||||
name: url.split('/').pop() || `file-${Date.now()}`,
|
||||
data: Buffer.from(data),
|
||||
mimetype: `image/${url.split('.').pop()}`,
|
||||
size: data.byteLength,
|
||||
}
|
||||
}
|
||||
315
apps/backend/src/endpoints/seed/post-1.ts
Normal file
315
apps/backend/src/endpoints/seed/post-1.ts
Normal file
@@ -0,0 +1,315 @@
|
||||
import type { Media, User } from '@/payload-types'
|
||||
import { RequiredDataFromCollectionSlug } from 'payload'
|
||||
|
||||
export type PostArgs = {
|
||||
heroImage: Media
|
||||
blockImage: Media
|
||||
author: User
|
||||
}
|
||||
|
||||
export const post1: (args: PostArgs) => RequiredDataFromCollectionSlug<'posts'> = ({
|
||||
heroImage,
|
||||
blockImage,
|
||||
author,
|
||||
}) => {
|
||||
return {
|
||||
slug: 'digital-horizons',
|
||||
_status: 'published',
|
||||
authors: [author],
|
||||
content: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Dive into the marvels of modern innovation, where the only constant is change. A journey where pixels and data converge to craft the future.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h2',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
fields: {
|
||||
blockName: 'Disclaimer',
|
||||
blockType: 'banner',
|
||||
content: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 1,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Disclaimer:',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: ' This content is fabricated and for demonstration purposes only. To edit this post, ',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'navigate to the admin dashboard',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
fields: {
|
||||
linkType: 'custom',
|
||||
newTab: true,
|
||||
url: '/admin',
|
||||
},
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 3,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: '.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
style: 'info',
|
||||
},
|
||||
format: '',
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'The Rise of AI and Machine Learning',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h2',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'We find ourselves in a transformative era where artificial intelligence (AI) stands at the forefront of technological evolution. The ripple effects of its advancements are reshaping industries at an unprecedented pace. No longer are businesses bound by the limitations of tedious, manual processes. Instead, sophisticated machines, fueled by vast amounts of historical data, are now capable of making decisions previously left to human intuition. These intelligent systems are not only optimizing operations but also pioneering innovative approaches, heralding a new age of business transformation worldwide. ',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'To demonstrate basic AI functionality, here is a javascript snippet that makes a POST request to a generic AI API in order to generate text based on a prompt. ',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h4',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
fields: {
|
||||
blockName: 'Generate Text',
|
||||
blockType: 'code',
|
||||
code: "async function generateText(prompt) {\n const apiKey = 'your-api-key';\n const apiUrl = 'https://api.example.com/generate-text';\n\n const response = await fetch(apiUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`\n },\n body: JSON.stringify({\n model: 'text-generation-model',\n prompt: prompt,\n max_tokens: 50\n })\n });\n\n const data = await response.json();\n console.log(data.choices[0].text.trim());\n}\n\n// Example usage\ngenerateText(\"Once upon a time in a faraway land,\");\n",
|
||||
language: 'javascript',
|
||||
},
|
||||
format: '',
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'IoT: Connecting the World Around Us',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h2',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: "In today's rapidly evolving technological landscape, the Internet of Things (IoT) stands out as a revolutionary force. From transforming our residences with smart home systems to redefining transportation through connected cars, IoT's influence is palpable in nearly every facet of our daily lives.",
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: "This technology hinges on the seamless integration of devices and systems, allowing them to communicate and collaborate effortlessly. With each connected device, we move a step closer to a world where convenience and efficiency are embedded in the very fabric of our existence. As a result, we're transitioning into an era where our surroundings intuitively respond to our needs, heralding a smarter and more interconnected global community.",
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
fields: {
|
||||
blockName: '',
|
||||
blockType: 'mediaBlock',
|
||||
media: blockImage.id,
|
||||
},
|
||||
format: '',
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
fields: {
|
||||
blockName: 'Dynamic Components',
|
||||
blockType: 'banner',
|
||||
content: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: "This content above is completely dynamic using custom layout building blocks configured in the CMS. This can be anything you'd like from rich text and images, to highly designed, complex components.",
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
style: 'info',
|
||||
},
|
||||
format: '',
|
||||
version: 2,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
heroImage: heroImage.id,
|
||||
meta: {
|
||||
description:
|
||||
'Dive into the marvels of modern innovation, where the only constant is change. A journey where pixels and data converge to craft the future.',
|
||||
image: heroImage.id,
|
||||
title: 'Digital Horizons: A Glimpse into Tomorrow',
|
||||
},
|
||||
relatedPosts: [], // this is populated by the seed script
|
||||
title: 'Digital Horizons: A Glimpse into Tomorrow',
|
||||
}
|
||||
}
|
||||
232
apps/backend/src/endpoints/seed/post-2.ts
Normal file
232
apps/backend/src/endpoints/seed/post-2.ts
Normal file
@@ -0,0 +1,232 @@
|
||||
import { RequiredDataFromCollectionSlug } from 'payload'
|
||||
import type { PostArgs } from './post-1'
|
||||
|
||||
export const post2: (args: PostArgs) => RequiredDataFromCollectionSlug<'posts'> = ({
|
||||
heroImage,
|
||||
blockImage,
|
||||
author,
|
||||
}) => {
|
||||
return {
|
||||
slug: 'global-gaze',
|
||||
_status: 'published',
|
||||
authors: [author],
|
||||
content: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Explore the untold and overlooked. A magnified view into the corners of the world, where every story deserves its spotlight.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h2',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
fields: {
|
||||
blockName: 'Disclaimer',
|
||||
blockType: 'banner',
|
||||
content: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 1,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Disclaimer:',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: ' This content is fabricated and for demonstration purposes only. To edit this post, ',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'navigate to the admin dashboard.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
fields: {
|
||||
linkType: 'custom',
|
||||
newTab: true,
|
||||
url: '/admin',
|
||||
},
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 3,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 1,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
style: 'info',
|
||||
},
|
||||
format: '',
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'The Power of Resilience: Stories of Recovery and Hope',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h2',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: "Throughout history, regions across the globe have faced the devastating impact of natural disasters, the turbulence of political unrest, and the challenging ripples of economic downturns. In these moments of profound crisis, an often-underestimated force emerges: the indomitable resilience of the human spirit. These aren't just tales of mere survival, but stories of communities forging bonds, uniting with a collective purpose, and demonstrating an innate ability to overcome.",
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
fields: {
|
||||
blockName: '',
|
||||
blockType: 'mediaBlock',
|
||||
media: blockImage.id,
|
||||
},
|
||||
format: '',
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'From neighbors forming makeshift rescue teams during floods to entire cities rallying to rebuild after economic collapse, the essence of humanity is most evident in these acts of solidarity. As we delve into these narratives, we witness the transformative power of community spirit, where adversity becomes a catalyst for growth, unity, and a brighter, rebuilt future.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
fields: {
|
||||
blockName: 'Dynamic components',
|
||||
blockType: 'banner',
|
||||
content: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: "This content above is completely dynamic using custom layout building blocks configured in the CMS. This can be anything you'd like from rich text and images, to highly designed, complex components.",
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
style: 'info',
|
||||
},
|
||||
format: '',
|
||||
version: 2,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
heroImage: heroImage.id,
|
||||
meta: {
|
||||
description:
|
||||
'Explore the untold and overlooked. A magnified view into the corners of the world, where every story deserves its spotlight.',
|
||||
image: heroImage.id,
|
||||
title: 'Global Gaze: Beyond the Headlines',
|
||||
},
|
||||
relatedPosts: [], // this is populated by the seed script
|
||||
title: 'Global Gaze: Beyond the Headlines',
|
||||
}
|
||||
}
|
||||
268
apps/backend/src/endpoints/seed/post-3.ts
Normal file
268
apps/backend/src/endpoints/seed/post-3.ts
Normal file
@@ -0,0 +1,268 @@
|
||||
import { RequiredDataFromCollectionSlug } from 'payload'
|
||||
import type { PostArgs } from './post-1'
|
||||
|
||||
export const post3: (args: PostArgs) => RequiredDataFromCollectionSlug<'posts'> = ({
|
||||
heroImage,
|
||||
blockImage,
|
||||
author,
|
||||
}) => {
|
||||
return {
|
||||
slug: 'dollar-and-sense-the-financial-forecast',
|
||||
_status: 'published',
|
||||
authors: [author],
|
||||
content: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'block',
|
||||
fields: {
|
||||
blockName: 'Disclaimer',
|
||||
blockType: 'banner',
|
||||
content: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 1,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Disclaimer: ',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'This content is fabricated and for demonstration purposes only. To edit this post, ',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'navigate to the admin dashboard.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
fields: {
|
||||
linkType: 'custom',
|
||||
newTab: true,
|
||||
url: '/admin',
|
||||
},
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 3,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 1,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
style: 'info',
|
||||
},
|
||||
format: '',
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: "Money isn't just currency; ",
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 2,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: "it's a language. ",
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Dive deep into its nuances, where strategy meets intuition in the vast sea of finance.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h2',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: "Money, in its essence, transcends the mere concept of coins and paper notes; it becomes a profound language that speaks of value, trust, and societal structures. Like any language, it possesses intricate nuances and subtleties that require a discerning understanding. It's in these depths where the calculated world of financial strategy collides with the raw, instinctive nature of human intuition. Just as a seasoned linguist might dissect the syntax and semantics of a sentence, a financial expert navigates the vast and tumultuous ocean of finance, guided not only by logic and data but also by gut feelings and foresight. Every transaction, investment, and financial decision becomes a dialogue in this expansive lexicon of commerce and value.",
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
fields: {
|
||||
blockName: '',
|
||||
blockType: 'mediaBlock',
|
||||
media: blockImage.id,
|
||||
},
|
||||
format: '',
|
||||
version: 2,
|
||||
},
|
||||
{
|
||||
type: 'heading',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'Stock Market Dynamics: Bulls, Bears, and the Uncertain Middle',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
tag: 'h2',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: 'The stock market is a realm of vast opportunity but also poses risks. Discover the forces that drive market trends and the strategies employed by top traders to navigate this complex ecosystem. From market analysis to understanding investor psychology, get a comprehensive insight into the world of stocks.',
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: "The stock market, often visualized as a bustling arena of numbers and ticker tapes, is as much about human behavior as it is about economics. It's a place where optimism, represented by the bullish rally, meets the caution of bearish downturns, with each vying to dictate the market's direction. But between these two extremes lies an uncertain middle ground, a zone populated by traders and investors who constantly weigh hope against fear. Successful navigation requires more than just financial acumen; it demands an understanding of collective sentiments and the ability to predict not just market movements, but also the reactions of other market participants. In this intricate dance of numbers and nerves, the most astute players are those who master both the hard data and the soft nuances of human behavior.",
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
type: 'block',
|
||||
fields: {
|
||||
blockName: 'Dynamic components',
|
||||
blockType: 'banner',
|
||||
content: {
|
||||
root: {
|
||||
type: 'root',
|
||||
children: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
detail: 0,
|
||||
format: 0,
|
||||
mode: 'normal',
|
||||
style: '',
|
||||
text: "This content above is completely dynamic using custom layout building blocks configured in the CMS. This can be anything you'd like from rich text and images, to highly designed, complex components.",
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
textFormat: 0,
|
||||
version: 1,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
style: 'info',
|
||||
},
|
||||
format: '',
|
||||
version: 2,
|
||||
},
|
||||
],
|
||||
direction: 'ltr',
|
||||
format: '',
|
||||
indent: 0,
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
heroImage: heroImage.id,
|
||||
meta: {
|
||||
description: `Money isn't just currency; it's a language. Dive deep into its nuances, where strategy meets intuition in the vast sea of finance.`,
|
||||
image: heroImage.id,
|
||||
title: 'Dollar and Sense: The Financial Forecast',
|
||||
},
|
||||
relatedPosts: [], // this is populated by the seed script
|
||||
title: 'Dollar and Sense: The Financial Forecast',
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user