templates: use typed functions in website template seed endpoint (#10420)

`JSON.parse(JSON.stringify().replace())` is easy to make mistakes with and since we have TypeScript data objects already for the data we're seeding it's pretty easy to just factor these as functions, making their dependencies explicit.
This commit is contained in:
Steve Kuznetsov
2025-02-03 12:40:22 -07:00
committed by GitHub
parent 4a4e90a170
commit 0a1cc6adcb
31 changed files with 2925 additions and 3889 deletions

View File

@@ -2,13 +2,11 @@ import type { Metadata } from 'next'
import { PayloadRedirects } from '@/components/PayloadRedirects'
import configPromise from '@payload-config'
import { getPayload } from 'payload'
import { getPayload, type RequiredDataFromCollectionSlug } from 'payload'
import { draftMode } from 'next/headers'
import React, { cache } from 'react'
import { homeStatic } from '@/endpoints/seed/home-static'
import type { Page as PageType } from '@/payload-types'
import { RenderBlocks } from '@/blocks/RenderBlocks'
import { RenderHero } from '@/heros/RenderHero'
import { generateMeta } from '@/utilities/generateMeta'
@@ -50,7 +48,7 @@ export default async function Page({ params: paramsPromise }: Args) {
const { slug = 'home' } = await paramsPromise
const url = '/' + slug
let page: PageType | null
let page: RequiredDataFromCollectionSlug<'pages'> | null
page = await queryPageBySlug({
slug,

View File

@@ -1,6 +1,6 @@
import type { Form } from '@/payload-types'
import { RequiredDataFromCollectionSlug } from 'payload'
export const contactForm: Partial<Form> = {
export const contactForm: RequiredDataFromCollectionSlug<'forms'> = {
confirmationMessage: {
root: {
type: 'root',

View File

@@ -1,6 +1,14 @@
import type { Page } from '@/payload-types'
import type { Form } from '@/payload-types'
import { RequiredDataFromCollectionSlug } from 'payload'
export const contact: Partial<Page> = {
type ContactArgs = {
contactForm: Form
}
export const contact: (args: ContactArgs) => RequiredDataFromCollectionSlug<'pages'> = ({
contactForm,
}) => {
return {
slug: 'contact',
_status: 'published',
hero: {
@@ -10,7 +18,7 @@ export const contact: Partial<Page> = {
{
blockType: 'formBlock',
enableIntro: true,
form: '{{CONTACT_FORM_ID}}',
form: contactForm,
introContent: {
root: {
type: 'root',
@@ -44,4 +52,5 @@ export const contact: Partial<Page> = {
},
],
title: 'Contact',
}
}

View File

@@ -1,7 +1,7 @@
import type { Page } from '@/payload-types'
import type { RequiredDataFromCollectionSlug } from 'payload'
// Used for pre-seeded content so that the homepage is not empty
export const homeStatic: Page = {
export const homeStatic: RequiredDataFromCollectionSlug<'pages'> = {
slug: 'home',
_status: 'published',
hero: {
@@ -84,8 +84,5 @@ export const homeStatic: Page = {
title: 'Payload Website Template',
},
title: 'Home',
id: '',
layout: [],
updatedAt: '',
createdAt: '',
}

View File

@@ -1,6 +1,16 @@
import type { RequiredDataFromCollectionSlug } from 'payload'
import type { Media } from '@/payload-types'
export const home: RequiredDataFromCollectionSlug<'pages'> = {
type HomeArgs = {
heroImage: Media
metaImage: Media
}
export const home: (args: HomeArgs) => RequiredDataFromCollectionSlug<'pages'> = ({
heroImage,
metaImage,
}) => {
return {
slug: 'home',
_status: 'published',
hero: {
@@ -23,7 +33,7 @@ export const home: RequiredDataFromCollectionSlug<'pages'> = {
},
},
],
media: '{{IMAGE_1}}',
media: heroImage.id,
richText: {
root: {
type: 'root',
@@ -501,7 +511,7 @@ export const home: RequiredDataFromCollectionSlug<'pages'> = {
{
blockName: 'Media Block',
blockType: 'mediaBlock',
media: '{{IMAGE_2}}',
media: metaImage.id,
},
{
blockName: 'Archive Block',
@@ -657,8 +667,9 @@ export const home: RequiredDataFromCollectionSlug<'pages'> = {
],
meta: {
description: 'An open-source website built with Payload and Next.js.',
image: '{{IMAGE_1}}',
image: heroImage.id,
title: 'Payload Website Template',
},
title: 'Home',
}
}

View File

@@ -237,12 +237,7 @@ export const seed = async ({
context: {
disableRevalidate: true,
},
data: JSON.parse(
JSON.stringify({ ...post1, categories: [technologyCategory.id] })
.replace(/"\{\{IMAGE_1\}\}"/g, String(image1ID))
.replace(/"\{\{IMAGE_2\}\}"/g, String(image2ID))
.replace(/"\{\{AUTHOR\}\}"/g, String(demoAuthorID)),
),
data: post1({ heroImage: image1Doc, blockImage: image2Doc, author: demoAuthor }),
})
const post2Doc = await payload.create({
@@ -251,12 +246,7 @@ export const seed = async ({
context: {
disableRevalidate: true,
},
data: JSON.parse(
JSON.stringify({ ...post2, categories: [newsCategory.id] })
.replace(/"\{\{IMAGE_1\}\}"/g, String(image2ID))
.replace(/"\{\{IMAGE_2\}\}"/g, String(image3ID))
.replace(/"\{\{AUTHOR\}\}"/g, String(demoAuthorID)),
),
data: post2({ heroImage: image2Doc, blockImage: image3Doc, author: demoAuthor }),
})
const post3Doc = await payload.create({
@@ -265,12 +255,7 @@ export const seed = async ({
context: {
disableRevalidate: true,
},
data: JSON.parse(
JSON.stringify({ ...post3, categories: [financeCategory.id] })
.replace(/"\{\{IMAGE_1\}\}"/g, String(image3ID))
.replace(/"\{\{IMAGE_2\}\}"/g, String(image1ID))
.replace(/"\{\{AUTHOR\}\}"/g, String(demoAuthorID)),
),
data: post3({ heroImage: image3Doc, blockImage: image1Doc, author: demoAuthor }),
})
// update each post with related posts
@@ -301,7 +286,7 @@ export const seed = async ({
const contactForm = await payload.create({
collection: 'forms',
depth: 0,
data: JSON.parse(JSON.stringify(contactFormData)),
data: contactFormData,
})
let contactFormID: number | string = contactForm.id
@@ -316,21 +301,12 @@ export const seed = async ({
payload.create({
collection: 'pages',
depth: 0,
data: JSON.parse(
JSON.stringify(home)
.replace(/"\{\{IMAGE_1\}\}"/g, String(imageHomeID))
.replace(/"\{\{IMAGE_2\}\}"/g, String(image2ID)),
),
data: home({heroImage: imageHomeDoc, metaImage: image2Doc}),
}),
payload.create({
collection: 'pages',
depth: 0,
data: JSON.parse(
JSON.stringify(contactPageData).replace(
/"\{\{CONTACT_FORM_ID\}\}"/g,
String(contactFormID),
),
),
data: contactPageData({ contactForm: contactForm }),
}),
])

View File

@@ -1,11 +1,21 @@
import type { Post } from '@/payload-types'
import type { Media, User } from '@/payload-types'
import { RequiredDataFromCollectionSlug } from 'payload'
export const post1: Partial<Post> = {
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',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
authors: ['{{AUTHOR}}'],
authors: [author],
content: {
root: {
type: 'root',
@@ -240,7 +250,7 @@ export const post1: Partial<Post> = {
fields: {
blockName: '',
blockType: 'mediaBlock',
media: '{{IMAGE_2}}',
media: blockImage.id,
},
format: '',
version: 2,
@@ -292,17 +302,14 @@ export const post1: Partial<Post> = {
version: 1,
},
},
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
heroImage: '{{IMAGE_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.',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
image: '{{IMAGE_1}}',
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',
}
}

View File

@@ -1,11 +1,15 @@
import type { Post } from '@/payload-types'
import { RequiredDataFromCollectionSlug } from 'payload'
import type { PostArgs } from './post-1'
export const post2: Partial<Post> = {
export const post2: (args: PostArgs) => RequiredDataFromCollectionSlug<'posts'> = ({
heroImage,
blockImage,
author,
}) => {
return {
slug: 'global-gaze',
_status: 'published',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
authors: ['{{AUTHOR}}'],
authors: [author],
content: {
root: {
type: 'root',
@@ -144,7 +148,7 @@ export const post2: Partial<Post> = {
fields: {
blockName: '',
blockType: 'mediaBlock',
media: '{{IMAGE_2}}',
media: blockImage.id,
},
format: '',
version: 2,
@@ -215,17 +219,14 @@ export const post2: Partial<Post> = {
version: 1,
},
},
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
heroImage: '{{IMAGE_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.',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
image: '{{IMAGE_1}}',
image: heroImage.id,
title: 'Global Gaze: Beyond the Headlines',
},
relatedPosts: [], // this is populated by the seed script
title: 'Global Gaze: Beyond the Headlines',
}
}

View File

@@ -1,11 +1,15 @@
import type { Post } from '@/payload-types'
import { RequiredDataFromCollectionSlug } from 'payload'
import type { PostArgs } from './post-1'
export const post3: Partial<Post> = {
export const post3: (args: PostArgs) => RequiredDataFromCollectionSlug<'posts'> = ({
heroImage,
blockImage,
author,
}) => {
return {
slug: 'dollar-and-sense-the-financial-forecast',
_status: 'published',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
authors: ['{{AUTHOR}}'],
authors: [author],
content: {
root: {
type: 'root',
@@ -143,7 +147,7 @@ export const post3: Partial<Post> = {
fields: {
blockName: '',
blockType: 'mediaBlock',
media: '{{IMAGE_2}}',
media: blockImage.id,
},
format: '',
version: 2,
@@ -252,16 +256,13 @@ export const post3: Partial<Post> = {
version: 1,
},
},
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
heroImage: '{{IMAGE_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.`,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
image: '{{IMAGE_1}}',
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',
}
}

View File

@@ -6,16 +6,17 @@
"type": "module",
"scripts": {
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
"ci": "payload migrate && pnpm build",
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
"devsafe": "rm -rf .next && cross-env NODE_OPTIONS=--no-deprecation next dev",
"generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",
"generate:types": "cross-env NODE_OPTIONS=--no-deprecation payload generate:types",
"lint": "cross-env NODE_OPTIONS=--no-deprecation next lint",
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
"start": "cross-env NODE_OPTIONS=--no-deprecation next start",
"ci": "payload migrate && pnpm build"
"start": "cross-env NODE_OPTIONS=--no-deprecation next start"
},
"dependencies": {
"@payloadcms/db-postgres": "latest",
"@payloadcms/next": "latest",
"@payloadcms/payload-cloud": "latest",
"@payloadcms/richtext-lexical": "latest",
@@ -25,8 +26,7 @@
"payload": "latest",
"react": "19.0.0",
"react-dom": "19.0.0",
"sharp": "0.32.6",
"@payloadcms/db-postgres": "latest"
"sharp": "0.32.6"
},
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",

View File

@@ -1,138 +0,0 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
CREATE TABLE IF NOT EXISTS "users" (
"id" serial PRIMARY KEY NOT NULL,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"email" varchar NOT NULL,
"reset_password_token" varchar,
"reset_password_expiration" timestamp(3) with time zone,
"salt" varchar,
"hash" varchar,
"login_attempts" numeric DEFAULT 0,
"lock_until" timestamp(3) with time zone
);
CREATE TABLE IF NOT EXISTS "media" (
"id" serial PRIMARY KEY NOT NULL,
"alt" varchar NOT NULL,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"url" varchar,
"thumbnail_u_r_l" varchar,
"filename" varchar,
"mime_type" varchar,
"filesize" numeric,
"width" numeric,
"height" numeric,
"focal_x" numeric,
"focal_y" numeric
);
CREATE TABLE IF NOT EXISTS "payload_locked_documents" (
"id" serial PRIMARY KEY NOT NULL,
"global_slug" varchar,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE IF NOT EXISTS "payload_locked_documents_rels" (
"id" serial PRIMARY KEY NOT NULL,
"order" integer,
"parent_id" integer NOT NULL,
"path" varchar NOT NULL,
"users_id" integer,
"media_id" integer
);
CREATE TABLE IF NOT EXISTS "payload_preferences" (
"id" serial PRIMARY KEY NOT NULL,
"key" varchar,
"value" jsonb,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE IF NOT EXISTS "payload_preferences_rels" (
"id" serial PRIMARY KEY NOT NULL,
"order" integer,
"parent_id" integer NOT NULL,
"path" varchar NOT NULL,
"users_id" integer
);
CREATE TABLE IF NOT EXISTS "payload_migrations" (
"id" serial PRIMARY KEY NOT NULL,
"name" varchar,
"batch" numeric,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
DO $$ BEGIN
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."payload_locked_documents"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
DO $$ BEGIN
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_users_fk" FOREIGN KEY ("users_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
DO $$ BEGIN
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_media_fk" FOREIGN KEY ("media_id") REFERENCES "public"."media"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
DO $$ BEGIN
ALTER TABLE "payload_preferences_rels" ADD CONSTRAINT "payload_preferences_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."payload_preferences"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
DO $$ BEGIN
ALTER TABLE "payload_preferences_rels" ADD CONSTRAINT "payload_preferences_rels_users_fk" FOREIGN KEY ("users_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
CREATE INDEX IF NOT EXISTS "users_updated_at_idx" ON "users" USING btree ("updated_at");
CREATE INDEX IF NOT EXISTS "users_created_at_idx" ON "users" USING btree ("created_at");
CREATE UNIQUE INDEX IF NOT EXISTS "users_email_idx" ON "users" USING btree ("email");
CREATE INDEX IF NOT EXISTS "media_updated_at_idx" ON "media" USING btree ("updated_at");
CREATE INDEX IF NOT EXISTS "media_created_at_idx" ON "media" USING btree ("created_at");
CREATE UNIQUE INDEX IF NOT EXISTS "media_filename_idx" ON "media" USING btree ("filename");
CREATE INDEX IF NOT EXISTS "payload_locked_documents_global_slug_idx" ON "payload_locked_documents" USING btree ("global_slug");
CREATE INDEX IF NOT EXISTS "payload_locked_documents_updated_at_idx" ON "payload_locked_documents" USING btree ("updated_at");
CREATE INDEX IF NOT EXISTS "payload_locked_documents_created_at_idx" ON "payload_locked_documents" USING btree ("created_at");
CREATE INDEX IF NOT EXISTS "payload_locked_documents_rels_order_idx" ON "payload_locked_documents_rels" USING btree ("order");
CREATE INDEX IF NOT EXISTS "payload_locked_documents_rels_parent_idx" ON "payload_locked_documents_rels" USING btree ("parent_id");
CREATE INDEX IF NOT EXISTS "payload_locked_documents_rels_path_idx" ON "payload_locked_documents_rels" USING btree ("path");
CREATE INDEX IF NOT EXISTS "payload_locked_documents_rels_users_id_idx" ON "payload_locked_documents_rels" USING btree ("users_id");
CREATE INDEX IF NOT EXISTS "payload_locked_documents_rels_media_id_idx" ON "payload_locked_documents_rels" USING btree ("media_id");
CREATE INDEX IF NOT EXISTS "payload_preferences_key_idx" ON "payload_preferences" USING btree ("key");
CREATE INDEX IF NOT EXISTS "payload_preferences_updated_at_idx" ON "payload_preferences" USING btree ("updated_at");
CREATE INDEX IF NOT EXISTS "payload_preferences_created_at_idx" ON "payload_preferences" USING btree ("created_at");
CREATE INDEX IF NOT EXISTS "payload_preferences_rels_order_idx" ON "payload_preferences_rels" USING btree ("order");
CREATE INDEX IF NOT EXISTS "payload_preferences_rels_parent_idx" ON "payload_preferences_rels" USING btree ("parent_id");
CREATE INDEX IF NOT EXISTS "payload_preferences_rels_path_idx" ON "payload_preferences_rels" USING btree ("path");
CREATE INDEX IF NOT EXISTS "payload_preferences_rels_users_id_idx" ON "payload_preferences_rels" USING btree ("users_id");
CREATE INDEX IF NOT EXISTS "payload_migrations_updated_at_idx" ON "payload_migrations" USING btree ("updated_at");
CREATE INDEX IF NOT EXISTS "payload_migrations_created_at_idx" ON "payload_migrations" USING btree ("created_at");`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
DROP TABLE "users" CASCADE;
DROP TABLE "media" CASCADE;
DROP TABLE "payload_locked_documents" CASCADE;
DROP TABLE "payload_locked_documents_rels" CASCADE;
DROP TABLE "payload_preferences" CASCADE;
DROP TABLE "payload_preferences_rels" CASCADE;
DROP TABLE "payload_migrations" CASCADE;`)
}

View File

@@ -1,9 +0,0 @@
import * as migration_20250129_033106_initial from './20250129_033106_initial'
export const migrations = [
{
up: migration_20250129_033106_initial.up,
down: migration_20250129_033106_initial.down,
name: '20250129_033106_initial',
},
]

View File

@@ -6,27 +6,27 @@
"type": "module",
"scripts": {
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
"ci": "payload migrate && pnpm build",
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
"devsafe": "rm -rf .next && cross-env NODE_OPTIONS=--no-deprecation next dev",
"generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",
"generate:types": "cross-env NODE_OPTIONS=--no-deprecation payload generate:types",
"lint": "cross-env NODE_OPTIONS=--no-deprecation next lint",
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
"start": "cross-env NODE_OPTIONS=--no-deprecation next start",
"ci": "payload migrate && pnpm build"
"start": "cross-env NODE_OPTIONS=--no-deprecation next start"
},
"dependencies": {
"@payloadcms/db-vercel-postgres": "latest",
"@payloadcms/next": "latest",
"@payloadcms/payload-cloud": "latest",
"@payloadcms/richtext-lexical": "latest",
"@payloadcms/storage-vercel-blob": "latest",
"cross-env": "^7.0.3",
"graphql": "^16.8.1",
"next": "15.1.5",
"payload": "latest",
"react": "19.0.0",
"react-dom": "19.0.0",
"@payloadcms/db-vercel-postgres": "latest",
"@payloadcms/storage-vercel-blob": "latest"
"react-dom": "19.0.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",

View File

@@ -1,808 +0,0 @@
{
"id": "a5487bec-f1c8-4892-a6cf-871d624aefeb",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"created_at": {
"name": "created_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"email": {
"name": "email",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"reset_password_token": {
"name": "reset_password_token",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"reset_password_expiration": {
"name": "reset_password_expiration",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": false
},
"salt": {
"name": "salt",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"hash": {
"name": "hash",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"login_attempts": {
"name": "login_attempts",
"type": "numeric",
"primaryKey": false,
"notNull": false,
"default": 0
},
"lock_until": {
"name": "lock_until",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"users_updated_at_idx": {
"name": "users_updated_at_idx",
"columns": [
{
"expression": "updated_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"users_created_at_idx": {
"name": "users_created_at_idx",
"columns": [
{
"expression": "created_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"users_email_idx": {
"name": "users_email_idx",
"columns": [
{
"expression": "email",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.media": {
"name": "media",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"alt": {
"name": "alt",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"created_at": {
"name": "created_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"url": {
"name": "url",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"thumbnail_u_r_l": {
"name": "thumbnail_u_r_l",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"filename": {
"name": "filename",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"mime_type": {
"name": "mime_type",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"filesize": {
"name": "filesize",
"type": "numeric",
"primaryKey": false,
"notNull": false
},
"width": {
"name": "width",
"type": "numeric",
"primaryKey": false,
"notNull": false
},
"height": {
"name": "height",
"type": "numeric",
"primaryKey": false,
"notNull": false
},
"focal_x": {
"name": "focal_x",
"type": "numeric",
"primaryKey": false,
"notNull": false
},
"focal_y": {
"name": "focal_y",
"type": "numeric",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"media_updated_at_idx": {
"name": "media_updated_at_idx",
"columns": [
{
"expression": "updated_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"media_created_at_idx": {
"name": "media_created_at_idx",
"columns": [
{
"expression": "created_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"media_filename_idx": {
"name": "media_filename_idx",
"columns": [
{
"expression": "filename",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payload_locked_documents": {
"name": "payload_locked_documents",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"global_slug": {
"name": "global_slug",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"updated_at": {
"name": "updated_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"created_at": {
"name": "created_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"payload_locked_documents_global_slug_idx": {
"name": "payload_locked_documents_global_slug_idx",
"columns": [
{
"expression": "global_slug",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_locked_documents_updated_at_idx": {
"name": "payload_locked_documents_updated_at_idx",
"columns": [
{
"expression": "updated_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_locked_documents_created_at_idx": {
"name": "payload_locked_documents_created_at_idx",
"columns": [
{
"expression": "created_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payload_locked_documents_rels": {
"name": "payload_locked_documents_rels",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"order": {
"name": "order",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"parent_id": {
"name": "parent_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"path": {
"name": "path",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"users_id": {
"name": "users_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"media_id": {
"name": "media_id",
"type": "integer",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"payload_locked_documents_rels_order_idx": {
"name": "payload_locked_documents_rels_order_idx",
"columns": [
{
"expression": "order",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_locked_documents_rels_parent_idx": {
"name": "payload_locked_documents_rels_parent_idx",
"columns": [
{
"expression": "parent_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_locked_documents_rels_path_idx": {
"name": "payload_locked_documents_rels_path_idx",
"columns": [
{
"expression": "path",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_locked_documents_rels_users_id_idx": {
"name": "payload_locked_documents_rels_users_id_idx",
"columns": [
{
"expression": "users_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_locked_documents_rels_media_id_idx": {
"name": "payload_locked_documents_rels_media_id_idx",
"columns": [
{
"expression": "media_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"payload_locked_documents_rels_parent_fk": {
"name": "payload_locked_documents_rels_parent_fk",
"tableFrom": "payload_locked_documents_rels",
"tableTo": "payload_locked_documents",
"columnsFrom": ["parent_id"],
"columnsTo": ["id"],
"onDelete": "cascade",
"onUpdate": "no action"
},
"payload_locked_documents_rels_users_fk": {
"name": "payload_locked_documents_rels_users_fk",
"tableFrom": "payload_locked_documents_rels",
"tableTo": "users",
"columnsFrom": ["users_id"],
"columnsTo": ["id"],
"onDelete": "cascade",
"onUpdate": "no action"
},
"payload_locked_documents_rels_media_fk": {
"name": "payload_locked_documents_rels_media_fk",
"tableFrom": "payload_locked_documents_rels",
"tableTo": "media",
"columnsFrom": ["media_id"],
"columnsTo": ["id"],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payload_preferences": {
"name": "payload_preferences",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"key": {
"name": "key",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"value": {
"name": "value",
"type": "jsonb",
"primaryKey": false,
"notNull": false
},
"updated_at": {
"name": "updated_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"created_at": {
"name": "created_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"payload_preferences_key_idx": {
"name": "payload_preferences_key_idx",
"columns": [
{
"expression": "key",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_preferences_updated_at_idx": {
"name": "payload_preferences_updated_at_idx",
"columns": [
{
"expression": "updated_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_preferences_created_at_idx": {
"name": "payload_preferences_created_at_idx",
"columns": [
{
"expression": "created_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payload_preferences_rels": {
"name": "payload_preferences_rels",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"order": {
"name": "order",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"parent_id": {
"name": "parent_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"path": {
"name": "path",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"users_id": {
"name": "users_id",
"type": "integer",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"payload_preferences_rels_order_idx": {
"name": "payload_preferences_rels_order_idx",
"columns": [
{
"expression": "order",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_preferences_rels_parent_idx": {
"name": "payload_preferences_rels_parent_idx",
"columns": [
{
"expression": "parent_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_preferences_rels_path_idx": {
"name": "payload_preferences_rels_path_idx",
"columns": [
{
"expression": "path",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_preferences_rels_users_id_idx": {
"name": "payload_preferences_rels_users_id_idx",
"columns": [
{
"expression": "users_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"payload_preferences_rels_parent_fk": {
"name": "payload_preferences_rels_parent_fk",
"tableFrom": "payload_preferences_rels",
"tableTo": "payload_preferences",
"columnsFrom": ["parent_id"],
"columnsTo": ["id"],
"onDelete": "cascade",
"onUpdate": "no action"
},
"payload_preferences_rels_users_fk": {
"name": "payload_preferences_rels_users_fk",
"tableFrom": "payload_preferences_rels",
"tableTo": "users",
"columnsFrom": ["users_id"],
"columnsTo": ["id"],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payload_migrations": {
"name": "payload_migrations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"batch": {
"name": "batch",
"type": "numeric",
"primaryKey": false,
"notNull": false
},
"updated_at": {
"name": "updated_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"created_at": {
"name": "created_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"payload_migrations_updated_at_idx": {
"name": "payload_migrations_updated_at_idx",
"columns": [
{
"expression": "updated_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_migrations_created_at_idx": {
"name": "payload_migrations_created_at_idx",
"columns": [
{
"expression": "created_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
}
}

View File

@@ -1,5 +1,5 @@
{
"id": "9c4682b1-937a-4c35-be39-111e09bf4d0b",
"id": "47d7f1d6-9c82-4fed-89c6-b3abeb06158c",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "7",
"dialect": "postgresql",

View File

@@ -1,9 +1,9 @@
import * as migration_20250129_033058_initial from './20250129_033058_initial'
import * as migration_20250203_154437_initial from './20250203_154437_initial'
export const migrations = [
{
up: migration_20250129_033058_initial.up,
down: migration_20250129_033058_initial.down,
name: '20250129_033058_initial',
up: migration_20250203_154437_initial.up,
down: migration_20250203_154437_initial.down,
name: '20250203_154437_initial',
},
]

View File

@@ -1,14 +1,10 @@
# Database connection string
POSTGRES_URL=postgresql://127.0.0.1:5432/your-database-name
# Used to encrypt JWT tokens
PAYLOAD_SECRET=YOUR_SECRET_HERE
# Used to configure CORS, format links and more. No trailing slash
NEXT_PUBLIC_SERVER_URL=http://localhost:3000
# Secret used to authenticate cron jobs
CRON_SECRET=YOUR_CRON_SECRET_HERE
# Used to validate preview requests
PREVIEW_SECRET=YOUR_SECRET_HERE

View File

@@ -7,6 +7,7 @@
"scripts": {
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
"postbuild": "next-sitemap --config next-sitemap.config.cjs",
"ci": "payload migrate && pnpm build",
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
"dev:prod": "cross-env NODE_OPTIONS=--no-deprecation rm -rf .next && pnpm build && pnpm start",
"generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",
@@ -16,10 +17,10 @@
"lint:fix": "cross-env NODE_OPTIONS=--no-deprecation next lint --fix",
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
"reinstall": "cross-env NODE_OPTIONS=--no-deprecation rm -rf node_modules && rm pnpm-lock.yaml && pnpm --ignore-workspace install",
"start": "cross-env NODE_OPTIONS=--no-deprecation next start",
"ci": "payload migrate && pnpm build"
"start": "cross-env NODE_OPTIONS=--no-deprecation next start"
},
"dependencies": {
"@payloadcms/db-vercel-postgres": "latest",
"@payloadcms/live-preview-react": "latest",
"@payloadcms/next": "latest",
"@payloadcms/payload-cloud": "latest",
@@ -29,6 +30,7 @@
"@payloadcms/plugin-search": "latest",
"@payloadcms/plugin-seo": "latest",
"@payloadcms/richtext-lexical": "latest",
"@payloadcms/storage-vercel-blob": "latest",
"@payloadcms/ui": "latest",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-label": "^2.0.2",
@@ -50,9 +52,7 @@
"react-hook-form": "7.45.4",
"sharp": "0.32.6",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
"@payloadcms/db-vercel-postgres": "latest",
"@payloadcms/storage-vercel-blob": "latest"
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",

View File

@@ -2,13 +2,11 @@ import type { Metadata } from 'next'
import { PayloadRedirects } from '@/components/PayloadRedirects'
import configPromise from '@payload-config'
import { getPayload } from 'payload'
import { getPayload, type RequiredDataFromCollectionSlug } from 'payload'
import { draftMode } from 'next/headers'
import React, { cache } from 'react'
import { homeStatic } from '@/endpoints/seed/home-static'
import type { Page as PageType } from '@/payload-types'
import { RenderBlocks } from '@/blocks/RenderBlocks'
import { RenderHero } from '@/heros/RenderHero'
import { generateMeta } from '@/utilities/generateMeta'
@@ -50,7 +48,7 @@ export default async function Page({ params: paramsPromise }: Args) {
const { slug = 'home' } = await paramsPromise
const url = '/' + slug
let page: PageType | null
let page: RequiredDataFromCollectionSlug<'pages'> | null
page = await queryPageBySlug({
slug,

View File

@@ -1,6 +1,6 @@
import type { Form } from '@/payload-types'
import { RequiredDataFromCollectionSlug } from 'payload'
export const contactForm: Partial<Form> = {
export const contactForm: RequiredDataFromCollectionSlug<'forms'> = {
confirmationMessage: {
root: {
type: 'root',

View File

@@ -1,6 +1,14 @@
import type { Page } from '@/payload-types'
import type { Form } from '@/payload-types'
import { RequiredDataFromCollectionSlug } from 'payload'
export const contact: Partial<Page> = {
type ContactArgs = {
contactForm: Form
}
export const contact: (args: ContactArgs) => RequiredDataFromCollectionSlug<'pages'> = ({
contactForm,
}) => {
return {
slug: 'contact',
_status: 'published',
hero: {
@@ -10,8 +18,7 @@ export const contact: Partial<Page> = {
{
blockType: 'formBlock',
enableIntro: true,
// @ts-ignore
form: '{{CONTACT_FORM_ID}}',
form: contactForm,
introContent: {
root: {
type: 'root',
@@ -45,4 +52,5 @@ export const contact: Partial<Page> = {
},
],
title: 'Contact',
}
}

View File

@@ -1,7 +1,7 @@
import type { Page } from '@/payload-types'
import type { RequiredDataFromCollectionSlug } from 'payload'
// Used for pre-seeded content so that the homepage is not empty
export const homeStatic: Page = {
export const homeStatic: RequiredDataFromCollectionSlug<'pages'> = {
slug: 'home',
_status: 'published',
hero: {
@@ -84,9 +84,5 @@ export const homeStatic: Page = {
title: 'Payload Website Template',
},
title: 'Home',
// @ts-ignore
id: '',
layout: [],
updatedAt: '',
createdAt: '',
}

View File

@@ -1,6 +1,16 @@
import type { RequiredDataFromCollectionSlug } from 'payload'
import type { Media } from '@/payload-types'
export const home: RequiredDataFromCollectionSlug<'pages'> = {
type HomeArgs = {
heroImage: Media
metaImage: Media
}
export const home: (args: HomeArgs) => RequiredDataFromCollectionSlug<'pages'> = ({
heroImage,
metaImage,
}) => {
return {
slug: 'home',
_status: 'published',
hero: {
@@ -23,8 +33,7 @@ export const home: RequiredDataFromCollectionSlug<'pages'> = {
},
},
],
// @ts-ignore
media: '{{IMAGE_1}}',
media: heroImage.id,
richText: {
root: {
type: 'root',
@@ -502,8 +511,7 @@ export const home: RequiredDataFromCollectionSlug<'pages'> = {
{
blockName: 'Media Block',
blockType: 'mediaBlock',
// @ts-ignore
media: '{{IMAGE_2}}',
media: metaImage.id,
},
{
blockName: 'Archive Block',
@@ -659,9 +667,9 @@ export const home: RequiredDataFromCollectionSlug<'pages'> = {
],
meta: {
description: 'An open-source website built with Payload and Next.js.',
// @ts-ignore
image: '{{IMAGE_1}}',
image: heroImage.id,
title: 'Payload Website Template',
},
title: 'Home',
}
}

View File

@@ -237,12 +237,7 @@ export const seed = async ({
context: {
disableRevalidate: true,
},
data: JSON.parse(
JSON.stringify({ ...post1, categories: [technologyCategory.id] })
.replace(/"\{\{IMAGE_1\}\}"/g, String(image1ID))
.replace(/"\{\{IMAGE_2\}\}"/g, String(image2ID))
.replace(/"\{\{AUTHOR\}\}"/g, String(demoAuthorID)),
),
data: post1({ heroImage: image1Doc, blockImage: image2Doc, author: demoAuthor }),
})
const post2Doc = await payload.create({
@@ -251,12 +246,7 @@ export const seed = async ({
context: {
disableRevalidate: true,
},
data: JSON.parse(
JSON.stringify({ ...post2, categories: [newsCategory.id] })
.replace(/"\{\{IMAGE_1\}\}"/g, String(image2ID))
.replace(/"\{\{IMAGE_2\}\}"/g, String(image3ID))
.replace(/"\{\{AUTHOR\}\}"/g, String(demoAuthorID)),
),
data: post2({ heroImage: image2Doc, blockImage: image3Doc, author: demoAuthor }),
})
const post3Doc = await payload.create({
@@ -265,12 +255,7 @@ export const seed = async ({
context: {
disableRevalidate: true,
},
data: JSON.parse(
JSON.stringify({ ...post3, categories: [financeCategory.id] })
.replace(/"\{\{IMAGE_1\}\}"/g, String(image3ID))
.replace(/"\{\{IMAGE_2\}\}"/g, String(image1ID))
.replace(/"\{\{AUTHOR\}\}"/g, String(demoAuthorID)),
),
data: post3({ heroImage: image3Doc, blockImage: image1Doc, author: demoAuthor }),
})
// update each post with related posts
@@ -301,7 +286,7 @@ export const seed = async ({
const contactForm = await payload.create({
collection: 'forms',
depth: 0,
data: JSON.parse(JSON.stringify(contactFormData)),
data: contactFormData,
})
let contactFormID: number | string = contactForm.id
@@ -316,21 +301,12 @@ export const seed = async ({
payload.create({
collection: 'pages',
depth: 0,
data: JSON.parse(
JSON.stringify(home)
.replace(/"\{\{IMAGE_1\}\}"/g, String(imageHomeID))
.replace(/"\{\{IMAGE_2\}\}"/g, String(image2ID)),
),
data: home({ heroImage: imageHomeDoc, metaImage: image2Doc }),
}),
payload.create({
collection: 'pages',
depth: 0,
data: JSON.parse(
JSON.stringify(contactPageData).replace(
/"\{\{CONTACT_FORM_ID\}\}"/g,
String(contactFormID),
),
),
data: contactPageData({ contactForm: contactForm }),
}),
])

View File

@@ -1,11 +1,21 @@
import type { Post } from '@/payload-types'
import type { Media, User } from '@/payload-types'
import { RequiredDataFromCollectionSlug } from 'payload'
export const post1: Partial<Post> = {
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',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
authors: ['{{AUTHOR}}'],
authors: [author],
content: {
root: {
type: 'root',
@@ -240,7 +250,7 @@ export const post1: Partial<Post> = {
fields: {
blockName: '',
blockType: 'mediaBlock',
media: '{{IMAGE_2}}',
media: blockImage.id,
},
format: '',
version: 2,
@@ -292,17 +302,14 @@ export const post1: Partial<Post> = {
version: 1,
},
},
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
heroImage: '{{IMAGE_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.',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
image: '{{IMAGE_1}}',
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',
}
}

View File

@@ -1,11 +1,15 @@
import type { Post } from '@/payload-types'
import { RequiredDataFromCollectionSlug } from 'payload'
import type { PostArgs } from './post-1'
export const post2: Partial<Post> = {
export const post2: (args: PostArgs) => RequiredDataFromCollectionSlug<'posts'> = ({
heroImage,
blockImage,
author,
}) => {
return {
slug: 'global-gaze',
_status: 'published',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
authors: ['{{AUTHOR}}'],
authors: [author],
content: {
root: {
type: 'root',
@@ -144,7 +148,7 @@ export const post2: Partial<Post> = {
fields: {
blockName: '',
blockType: 'mediaBlock',
media: '{{IMAGE_2}}',
media: blockImage.id,
},
format: '',
version: 2,
@@ -215,17 +219,14 @@ export const post2: Partial<Post> = {
version: 1,
},
},
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
heroImage: '{{IMAGE_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.',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
image: '{{IMAGE_1}}',
image: heroImage.id,
title: 'Global Gaze: Beyond the Headlines',
},
relatedPosts: [], // this is populated by the seed script
title: 'Global Gaze: Beyond the Headlines',
}
}

View File

@@ -1,11 +1,15 @@
import type { Post } from '@/payload-types'
import { RequiredDataFromCollectionSlug } from 'payload'
import type { PostArgs } from './post-1'
export const post3: Partial<Post> = {
export const post3: (args: PostArgs) => RequiredDataFromCollectionSlug<'posts'> = ({
heroImage,
blockImage,
author,
}) => {
return {
slug: 'dollar-and-sense-the-financial-forecast',
_status: 'published',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
authors: ['{{AUTHOR}}'],
authors: [author],
content: {
root: {
type: 'root',
@@ -143,7 +147,7 @@ export const post3: Partial<Post> = {
fields: {
blockName: '',
blockType: 'mediaBlock',
media: '{{IMAGE_2}}',
media: blockImage.id,
},
format: '',
version: 2,
@@ -252,16 +256,13 @@ export const post3: Partial<Post> = {
version: 1,
},
},
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
heroImage: '{{IMAGE_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.`,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
image: '{{IMAGE_1}}',
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',
}
}

View File

@@ -1,5 +1,5 @@
{
"id": "b2ff7f1c-8dd6-4188-adb6-abfc6304df24",
"id": "a7ad29c9-3b07-4943-a44f-4d1bc1a970ba",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "7",
"dialect": "postgresql",

View File

@@ -1,9 +1,9 @@
import * as migration_20250129_033102_initial from './20250129_033102_initial'
import * as migration_20250203_154449_initial from './20250203_154449_initial'
export const migrations = [
{
up: migration_20250129_033102_initial.up,
down: migration_20250129_033102_initial.down,
name: '20250129_033102_initial',
up: migration_20250203_154449_initial.up,
down: migration_20250203_154449_initial.down,
name: '20250203_154449_initial',
},
]