chore(templates): update missing changes in vercel website template (#10827)
This PR migrates some changes that had been made to the website template and had not been ported to the website template with vercel. Ideally, so that this does not happen again in the future and we do not have to do this manually, we could have a script in CI.
This commit is contained in:
5294
templates/blank/pnpm-lock.yaml
generated
5294
templates/blank/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -13,31 +13,17 @@ export interface Config {
|
||||
collections: {
|
||||
users: User;
|
||||
media: Media;
|
||||
'payload-locked-documents': PayloadLockedDocument;
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
};
|
||||
collectionsJoins: {};
|
||||
collectionsSelect: {
|
||||
users: UsersSelect<false> | UsersSelect<true>;
|
||||
media: MediaSelect<false> | MediaSelect<true>;
|
||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
|
||||
};
|
||||
db: {
|
||||
defaultIDType: string;
|
||||
};
|
||||
globals: {};
|
||||
globalsSelect: {};
|
||||
locale: null;
|
||||
user: User & {
|
||||
collection: 'users';
|
||||
};
|
||||
jobs: {
|
||||
tasks: unknown;
|
||||
workflows: unknown;
|
||||
};
|
||||
}
|
||||
export interface UserAuthOperations {
|
||||
forgotPassword: {
|
||||
@@ -93,29 +79,6 @@ export interface Media {
|
||||
focalX?: number | null;
|
||||
focalY?: number | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents".
|
||||
*/
|
||||
export interface PayloadLockedDocument {
|
||||
id: string;
|
||||
document?:
|
||||
| ({
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'media';
|
||||
value: string | Media;
|
||||
} | null);
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences".
|
||||
@@ -150,71 +113,6 @@ export interface PayloadMigration {
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users_select".
|
||||
*/
|
||||
export interface UsersSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
email?: T;
|
||||
resetPasswordToken?: T;
|
||||
resetPasswordExpiration?: T;
|
||||
salt?: T;
|
||||
hash?: T;
|
||||
loginAttempts?: T;
|
||||
lockUntil?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "media_select".
|
||||
*/
|
||||
export interface MediaSelect<T extends boolean = true> {
|
||||
alt?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
url?: T;
|
||||
thumbnailURL?: T;
|
||||
filename?: T;
|
||||
mimeType?: T;
|
||||
filesize?: T;
|
||||
width?: T;
|
||||
height?: T;
|
||||
focalX?: T;
|
||||
focalY?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents_select".
|
||||
*/
|
||||
export interface PayloadLockedDocumentsSelect<T extends boolean = true> {
|
||||
document?: T;
|
||||
globalSlug?: T;
|
||||
user?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences_select".
|
||||
*/
|
||||
export interface PayloadPreferencesSelect<T extends boolean = true> {
|
||||
user?: T;
|
||||
key?: T;
|
||||
value?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-migrations_select".
|
||||
*/
|
||||
export interface PayloadMigrationsSelect<T extends boolean = true> {
|
||||
name?: T;
|
||||
batch?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "auth".
|
||||
|
||||
5706
templates/website/pnpm-lock.yaml
generated
5706
templates/website/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -6,17 +6,16 @@
|
||||
"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"
|
||||
"start": "cross-env NODE_OPTIONS=--no-deprecation next start",
|
||||
"ci": "payload migrate && pnpm build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@payloadcms/db-postgres": "latest",
|
||||
"@payloadcms/next": "latest",
|
||||
"@payloadcms/payload-cloud": "latest",
|
||||
"@payloadcms/richtext-lexical": "latest",
|
||||
@@ -26,7 +25,8 @@
|
||||
"payload": "latest",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"sharp": "0.32.6"
|
||||
"sharp": "0.32.6",
|
||||
"@payloadcms/db-postgres": "latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "2be5b1e5-29bb-4d50-9d48-d8a2f47cd65e",
|
||||
"id": "9c4682b1-937a-4c35-be39-111e09bf4d0b",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as migration_20250114_010521_initial from './20250114_010521_initial'
|
||||
import * as migration_20250129_033106_initial from './20250129_033106_initial'
|
||||
|
||||
export const migrations = [
|
||||
{
|
||||
up: migration_20250114_010521_initial.up,
|
||||
down: migration_20250114_010521_initial.down,
|
||||
name: '20250114_010521_initial',
|
||||
up: migration_20250129_033106_initial.up,
|
||||
down: migration_20250129_033106_initial.down,
|
||||
name: '20250129_033106_initial',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -19,13 +19,13 @@
|
||||
"@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"
|
||||
"react-dom": "19.0.0",
|
||||
"@payloadcms/storage-vercel-blob": "latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
|
||||
@@ -13,31 +13,17 @@ export interface Config {
|
||||
collections: {
|
||||
users: User;
|
||||
media: Media;
|
||||
'payload-locked-documents': PayloadLockedDocument;
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
};
|
||||
collectionsJoins: {};
|
||||
collectionsSelect: {
|
||||
users: UsersSelect<false> | UsersSelect<true>;
|
||||
media: MediaSelect<false> | MediaSelect<true>;
|
||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
|
||||
};
|
||||
db: {
|
||||
defaultIDType: string;
|
||||
};
|
||||
globals: {};
|
||||
globalsSelect: {};
|
||||
locale: null;
|
||||
user: User & {
|
||||
collection: 'users';
|
||||
};
|
||||
jobs: {
|
||||
tasks: unknown;
|
||||
workflows: unknown;
|
||||
};
|
||||
}
|
||||
export interface UserAuthOperations {
|
||||
forgotPassword: {
|
||||
@@ -93,29 +79,6 @@ export interface Media {
|
||||
focalX?: number | null;
|
||||
focalY?: number | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents".
|
||||
*/
|
||||
export interface PayloadLockedDocument {
|
||||
id: string;
|
||||
document?:
|
||||
| ({
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'media';
|
||||
value: string | Media;
|
||||
} | null);
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences".
|
||||
@@ -150,71 +113,6 @@ export interface PayloadMigration {
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users_select".
|
||||
*/
|
||||
export interface UsersSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
email?: T;
|
||||
resetPasswordToken?: T;
|
||||
resetPasswordExpiration?: T;
|
||||
salt?: T;
|
||||
hash?: T;
|
||||
loginAttempts?: T;
|
||||
lockUntil?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "media_select".
|
||||
*/
|
||||
export interface MediaSelect<T extends boolean = true> {
|
||||
alt?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
url?: T;
|
||||
thumbnailURL?: T;
|
||||
filename?: T;
|
||||
mimeType?: T;
|
||||
filesize?: T;
|
||||
width?: T;
|
||||
height?: T;
|
||||
focalX?: T;
|
||||
focalY?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents_select".
|
||||
*/
|
||||
export interface PayloadLockedDocumentsSelect<T extends boolean = true> {
|
||||
document?: T;
|
||||
globalSlug?: T;
|
||||
user?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences_select".
|
||||
*/
|
||||
export interface PayloadPreferencesSelect<T extends boolean = true> {
|
||||
user?: T;
|
||||
key?: T;
|
||||
value?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-migrations_select".
|
||||
*/
|
||||
export interface PayloadMigrationsSelect<T extends boolean = true> {
|
||||
name?: T;
|
||||
batch?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "auth".
|
||||
|
||||
@@ -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"
|
||||
"start": "cross-env NODE_OPTIONS=--no-deprecation next start",
|
||||
"ci": "payload migrate && pnpm build"
|
||||
},
|
||||
"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"
|
||||
"react-dom": "19.0.0",
|
||||
"@payloadcms/db-vercel-postgres": "latest",
|
||||
"@payloadcms/storage-vercel-blob": "latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "8695c39d-451b-406a-b700-cfded95da90e",
|
||||
"id": "a5487bec-f1c8-4892-a6cf-871d624aefeb",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-vercel-postgres'
|
||||
|
||||
export async function up({ db }: MigrateUpArgs): Promise<void> {
|
||||
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,
|
||||
@@ -126,7 +126,7 @@ export async function up({ db }: MigrateUpArgs): Promise<void> {
|
||||
CREATE INDEX IF NOT EXISTS "payload_migrations_created_at_idx" ON "payload_migrations" USING btree ("created_at");`)
|
||||
}
|
||||
|
||||
export async function down({ db }: MigrateDownArgs): Promise<void> {
|
||||
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||
await db.execute(sql`
|
||||
DROP TABLE "users" CASCADE;
|
||||
DROP TABLE "media" CASCADE;
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as migration_20250114_010454_initial from './20250114_010454_initial'
|
||||
import * as migration_20250129_033058_initial from './20250129_033058_initial'
|
||||
|
||||
export const migrations = [
|
||||
{
|
||||
up: migration_20250114_010454_initial.up,
|
||||
down: migration_20250114_010454_initial.down,
|
||||
name: '20250114_010454_initial',
|
||||
up: migration_20250129_033058_initial.up,
|
||||
down: migration_20250129_033058_initial.down,
|
||||
name: '20250129_033058_initial',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -30,6 +30,9 @@ const eslintConfig = [
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
ignores: ['.next/'],
|
||||
},
|
||||
]
|
||||
|
||||
export default eslintConfig
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
"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",
|
||||
@@ -17,10 +16,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"
|
||||
"start": "cross-env NODE_OPTIONS=--no-deprecation next start",
|
||||
"ci": "payload migrate && pnpm build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@payloadcms/db-vercel-postgres": "latest",
|
||||
"@payloadcms/live-preview-react": "latest",
|
||||
"@payloadcms/next": "latest",
|
||||
"@payloadcms/payload-cloud": "latest",
|
||||
@@ -30,7 +29,6 @@
|
||||
"@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",
|
||||
@@ -52,7 +50,9 @@
|
||||
"react-hook-form": "7.45.4",
|
||||
"sharp": "0.32.6",
|
||||
"tailwind-merge": "^2.3.0",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"@payloadcms/db-vercel-postgres": "latest",
|
||||
"@payloadcms/storage-vercel-blob": "latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
export default {
|
||||
const config = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
|
||||
@@ -81,7 +81,7 @@ export default async function Page({ params: paramsPromise }: Args) {
|
||||
)
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params: paramsPromise }): Promise<Metadata> {
|
||||
export async function generateMetadata({ params: paramsPromise }: Args): Promise<Metadata> {
|
||||
const { slug = 'home' } = await paramsPromise
|
||||
const page = await queryPageBySlug({
|
||||
slug,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import type { Form as FormType } from '@payloadcms/plugin-form-builder/types'
|
||||
import type { FormFieldBlock, Form as FormType } from '@payloadcms/plugin-form-builder/types'
|
||||
|
||||
import { useRouter } from 'next/navigation'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
@@ -8,20 +8,9 @@ import RichText from '@/components/RichText'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import type { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical'
|
||||
|
||||
import { buildInitialFormState } from './buildInitialFormState'
|
||||
import { fields } from './fields'
|
||||
import { getClientSideURL } from '@/utilities/getURL'
|
||||
|
||||
export type Value = unknown
|
||||
|
||||
export interface Property {
|
||||
[key: string]: Value
|
||||
}
|
||||
|
||||
export interface Data {
|
||||
[key: string]: Property | Property[]
|
||||
}
|
||||
|
||||
export type FormBlockType = {
|
||||
blockName?: string
|
||||
blockType?: 'formBlock'
|
||||
@@ -43,7 +32,7 @@ export const FormBlock: React.FC<
|
||||
} = props
|
||||
|
||||
const formMethods = useForm({
|
||||
defaultValues: buildInitialFormState(formFromProps.fields),
|
||||
defaultValues: formFromProps.fields,
|
||||
})
|
||||
const {
|
||||
control,
|
||||
@@ -58,7 +47,7 @@ export const FormBlock: React.FC<
|
||||
const router = useRouter()
|
||||
|
||||
const onSubmit = useCallback(
|
||||
(data: Data) => {
|
||||
(data: FormFieldBlock[]) => {
|
||||
let loadingTimerID: ReturnType<typeof setTimeout>
|
||||
const submitForm = async () => {
|
||||
setError(undefined)
|
||||
@@ -143,7 +132,7 @@ export const FormBlock: React.FC<
|
||||
formFromProps.fields &&
|
||||
formFromProps.fields?.map((field, index) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const Field: React.FC<any> = fields?.[field.blockType]
|
||||
const Field: React.FC<any> = fields?.[field.blockType as keyof typeof fields]
|
||||
if (Field) {
|
||||
return (
|
||||
<div className="mb-6 last:mb-0" key={index}>
|
||||
|
||||
@@ -4,7 +4,7 @@ import React from 'react'
|
||||
import { Width } from '../Width'
|
||||
import { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical'
|
||||
|
||||
export const Message: React.FC = ({ message }: { message: SerializedEditorState }) => {
|
||||
export const Message: React.FC<{ message: SerializedEditorState }> = ({ message }) => {
|
||||
return (
|
||||
<Width className="my-12" width="100">
|
||||
{message && <RichText data={message} />}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import type { FormFieldBlock } from '@payloadcms/plugin-form-builder/types'
|
||||
|
||||
export const buildInitialFormState = (fields: FormFieldBlock[]) => {
|
||||
return fields?.reduce((initialSchema, field) => {
|
||||
if (field.blockType === 'checkbox') {
|
||||
return {
|
||||
...initialSchema,
|
||||
[field.name]: field.defaultValue,
|
||||
}
|
||||
}
|
||||
if (field.blockType === 'country') {
|
||||
return {
|
||||
...initialSchema,
|
||||
[field.name]: '',
|
||||
}
|
||||
}
|
||||
if (field.blockType === 'email') {
|
||||
return {
|
||||
...initialSchema,
|
||||
[field.name]: '',
|
||||
}
|
||||
}
|
||||
if (field.blockType === 'text') {
|
||||
return {
|
||||
...initialSchema,
|
||||
[field.name]: '',
|
||||
}
|
||||
}
|
||||
if (field.blockType === 'select') {
|
||||
return {
|
||||
...initialSchema,
|
||||
[field.name]: '',
|
||||
}
|
||||
}
|
||||
if (field.blockType === 'state') {
|
||||
return {
|
||||
...initialSchema,
|
||||
[field.name]: '',
|
||||
}
|
||||
}
|
||||
|
||||
return initialSchema
|
||||
}, {})
|
||||
}
|
||||
@@ -125,7 +125,7 @@ export const Pages: CollectionConfig<'pages'> = {
|
||||
hooks: {
|
||||
afterChange: [revalidatePage],
|
||||
beforeChange: [populatePublishedAt],
|
||||
beforeDelete: [revalidateDelete],
|
||||
afterDelete: [revalidateDelete],
|
||||
},
|
||||
versions: {
|
||||
drafts: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { PayloadAdminBarProps } from 'payload-admin-bar'
|
||||
import type { PayloadAdminBarProps, PayloadMeUser } from 'payload-admin-bar'
|
||||
|
||||
import { cn } from '@/utilities/ui'
|
||||
import { useSelectedLayoutSegments } from 'next/navigation'
|
||||
@@ -37,11 +37,13 @@ export const AdminBar: React.FC<{
|
||||
const { adminBarProps } = props || {}
|
||||
const segments = useSelectedLayoutSegments()
|
||||
const [show, setShow] = useState(false)
|
||||
const collection = collectionLabels?.[segments?.[1]] ? segments?.[1] : 'pages'
|
||||
const collection = (
|
||||
collectionLabels[segments?.[1] as keyof typeof collectionLabels] ? segments[1] : 'pages'
|
||||
) as keyof typeof collectionLabels
|
||||
const router = useRouter()
|
||||
|
||||
const onAuthChange = React.useCallback((user) => {
|
||||
setShow(user?.id)
|
||||
const onAuthChange = React.useCallback((user: PayloadMeUser) => {
|
||||
setShow(Boolean(user?.id))
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
||||
@@ -17,10 +17,10 @@ const SuccessMessage: React.FC = () => (
|
||||
export const SeedButton: React.FC = () => {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [seeded, setSeeded] = useState(false)
|
||||
const [error, setError] = useState(null)
|
||||
const [error, setError] = useState<null | string>(null)
|
||||
|
||||
const handleClick = useCallback(
|
||||
async (e) => {
|
||||
async (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.preventDefault()
|
||||
|
||||
if (seeded) {
|
||||
@@ -65,7 +65,8 @@ export const SeedButton: React.FC = () => {
|
||||
},
|
||||
)
|
||||
} catch (err) {
|
||||
setError(err)
|
||||
const error = err instanceof Error ? err.message : String(err)
|
||||
setError(error)
|
||||
}
|
||||
},
|
||||
[loading, seeded, error],
|
||||
|
||||
@@ -14,7 +14,7 @@ const defaultCollectionLabels = {
|
||||
|
||||
export const PageRange: React.FC<{
|
||||
className?: string
|
||||
collection?: string
|
||||
collection?: keyof typeof defaultCollectionLabels
|
||||
collectionLabels?: {
|
||||
plural?: string
|
||||
singular?: string
|
||||
@@ -39,7 +39,10 @@ export const PageRange: React.FC<{
|
||||
if (totalDocs && indexEnd > totalDocs) indexEnd = totalDocs
|
||||
|
||||
const { plural, singular } =
|
||||
collectionLabelsFromProps || defaultCollectionLabels[collection || ''] || defaultLabels || {}
|
||||
collectionLabelsFromProps ||
|
||||
(collection ? defaultCollectionLabels[collection] : undefined) ||
|
||||
defaultLabels ||
|
||||
{}
|
||||
|
||||
return (
|
||||
<div className={[className, 'font-semibold'].filter(Boolean).join(' ')}>
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
//This copy-and-pasted from lexical here: https://github.com/facebook/lexical/blob/c2ceee223f46543d12c574e62155e619f9a18a5d/packages/lexical/src/LexicalConstants.ts
|
||||
|
||||
import type { ElementFormatType, TextFormatType } from '@payloadcms/richtext-lexical/lexical'
|
||||
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
*/
|
||||
|
||||
// DOM
|
||||
export const DOM_ELEMENT_TYPE = 1
|
||||
export const DOM_TEXT_TYPE = 3
|
||||
|
||||
// Reconciling
|
||||
export const NO_DIRTY_NODES = 0
|
||||
export const HAS_DIRTY_NODES = 1
|
||||
export const FULL_RECONCILE = 2
|
||||
|
||||
// Text node modes
|
||||
export const IS_NORMAL = 0
|
||||
export const IS_TOKEN = 1
|
||||
export const IS_SEGMENTED = 2
|
||||
// IS_INERT = 3
|
||||
|
||||
// Text node formatting
|
||||
export const IS_BOLD = 1
|
||||
export const IS_ITALIC = 1 << 1
|
||||
export const IS_STRIKETHROUGH = 1 << 2
|
||||
export const IS_UNDERLINE = 1 << 3
|
||||
export const IS_CODE = 1 << 4
|
||||
export const IS_SUBSCRIPT = 1 << 5
|
||||
export const IS_SUPERSCRIPT = 1 << 6
|
||||
export const IS_HIGHLIGHT = 1 << 7
|
||||
|
||||
export const IS_ALL_FORMATTING =
|
||||
IS_BOLD |
|
||||
IS_ITALIC |
|
||||
IS_STRIKETHROUGH |
|
||||
IS_UNDERLINE |
|
||||
IS_CODE |
|
||||
IS_SUBSCRIPT |
|
||||
IS_SUPERSCRIPT |
|
||||
IS_HIGHLIGHT
|
||||
|
||||
// Text node details
|
||||
export const IS_DIRECTIONLESS = 1
|
||||
export const IS_UNMERGEABLE = 1 << 1
|
||||
|
||||
// Element node formatting
|
||||
export const IS_ALIGN_LEFT = 1
|
||||
export const IS_ALIGN_CENTER = 2
|
||||
export const IS_ALIGN_RIGHT = 3
|
||||
export const IS_ALIGN_JUSTIFY = 4
|
||||
export const IS_ALIGN_START = 5
|
||||
export const IS_ALIGN_END = 6
|
||||
|
||||
// Reconciliation
|
||||
export const NON_BREAKING_SPACE = '\u00A0'
|
||||
|
||||
export const DOUBLE_LINE_BREAK = '\n\n'
|
||||
|
||||
// For FF, we need to use a non-breaking space, or it gets composition
|
||||
// in a stuck state.
|
||||
|
||||
const RTL = '\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC'
|
||||
const LTR =
|
||||
'A-Za-z\u00C0-\u00D6\u00D8-\u00F6' +
|
||||
'\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF\u200E\u2C00-\uFB1C' +
|
||||
'\uFE00-\uFE6F\uFEFD-\uFFFF'
|
||||
|
||||
export const RTL_REGEX = new RegExp('^[^' + LTR + ']*[' + RTL + ']')
|
||||
|
||||
export const LTR_REGEX = new RegExp('^[^' + RTL + ']*[' + LTR + ']')
|
||||
|
||||
export const TEXT_TYPE_TO_FORMAT: Record<TextFormatType | string, number> = {
|
||||
bold: IS_BOLD,
|
||||
code: IS_CODE,
|
||||
highlight: IS_HIGHLIGHT,
|
||||
italic: IS_ITALIC,
|
||||
strikethrough: IS_STRIKETHROUGH,
|
||||
subscript: IS_SUBSCRIPT,
|
||||
superscript: IS_SUPERSCRIPT,
|
||||
underline: IS_UNDERLINE,
|
||||
}
|
||||
|
||||
export const DETAIL_TYPE_TO_DETAIL: Record<string, number> = {
|
||||
directionless: IS_DIRECTIONLESS,
|
||||
unmergeable: IS_UNMERGEABLE,
|
||||
}
|
||||
|
||||
export const ELEMENT_TYPE_TO_FORMAT: Record<Exclude<ElementFormatType, ''>, number> = {
|
||||
center: IS_ALIGN_CENTER,
|
||||
end: IS_ALIGN_END,
|
||||
justify: IS_ALIGN_JUSTIFY,
|
||||
left: IS_ALIGN_LEFT,
|
||||
right: IS_ALIGN_RIGHT,
|
||||
start: IS_ALIGN_START,
|
||||
}
|
||||
|
||||
export const ELEMENT_FORMAT_TO_TYPE: Record<number, ElementFormatType> = {
|
||||
[IS_ALIGN_CENTER]: 'center',
|
||||
[IS_ALIGN_END]: 'end',
|
||||
[IS_ALIGN_JUSTIFY]: 'justify',
|
||||
[IS_ALIGN_LEFT]: 'left',
|
||||
[IS_ALIGN_RIGHT]: 'right',
|
||||
[IS_ALIGN_START]: 'start',
|
||||
}
|
||||
|
||||
export const TEXT_MODE_TO_TYPE: Record<string, 0 | 1 | 2> = {
|
||||
normal: IS_NORMAL,
|
||||
segmented: IS_SEGMENTED,
|
||||
token: IS_TOKEN,
|
||||
}
|
||||
|
||||
export const TEXT_TYPE_TO_MODE: Record<number, string> = {
|
||||
[IS_NORMAL]: 'normal',
|
||||
[IS_SEGMENTED]: 'segmented',
|
||||
[IS_TOKEN]: 'token',
|
||||
}
|
||||
@@ -1,209 +0,0 @@
|
||||
import { BannerBlock } from '@/blocks/Banner/Component'
|
||||
import { CallToActionBlock } from '@/blocks/CallToAction/Component'
|
||||
import { CodeBlock, CodeBlockProps } from '@/blocks/Code/Component'
|
||||
import { MediaBlock } from '@/blocks/MediaBlock/Component'
|
||||
import React, { Fragment, JSX } from 'react'
|
||||
import { CMSLink } from '@/components/Link'
|
||||
import { DefaultNodeTypes, SerializedBlockNode } from '@payloadcms/richtext-lexical'
|
||||
import type { BannerBlock as BannerBlockProps } from '@/payload-types'
|
||||
|
||||
import {
|
||||
IS_BOLD,
|
||||
IS_CODE,
|
||||
IS_ITALIC,
|
||||
IS_STRIKETHROUGH,
|
||||
IS_SUBSCRIPT,
|
||||
IS_SUPERSCRIPT,
|
||||
IS_UNDERLINE,
|
||||
} from './nodeFormat'
|
||||
import type {
|
||||
CallToActionBlock as CTABlockProps,
|
||||
MediaBlock as MediaBlockProps,
|
||||
} from '@/payload-types'
|
||||
|
||||
export type NodeTypes =
|
||||
| DefaultNodeTypes
|
||||
| SerializedBlockNode<CTABlockProps | MediaBlockProps | BannerBlockProps | CodeBlockProps>
|
||||
|
||||
type Props = {
|
||||
nodes: NodeTypes[]
|
||||
}
|
||||
|
||||
export function serializeLexical({ nodes }: Props): JSX.Element {
|
||||
return (
|
||||
<Fragment>
|
||||
{nodes?.map((node, index): JSX.Element | null => {
|
||||
if (node == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (node.type === 'text') {
|
||||
let text = <React.Fragment key={index}>{node.text}</React.Fragment>
|
||||
if (node.format & IS_BOLD) {
|
||||
text = <strong key={index}>{text}</strong>
|
||||
}
|
||||
if (node.format & IS_ITALIC) {
|
||||
text = <em key={index}>{text}</em>
|
||||
}
|
||||
if (node.format & IS_STRIKETHROUGH) {
|
||||
text = (
|
||||
<span key={index} style={{ textDecoration: 'line-through' }}>
|
||||
{text}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
if (node.format & IS_UNDERLINE) {
|
||||
text = (
|
||||
<span key={index} style={{ textDecoration: 'underline' }}>
|
||||
{text}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
if (node.format & IS_CODE) {
|
||||
text = <code key={index}>{node.text}</code>
|
||||
}
|
||||
if (node.format & IS_SUBSCRIPT) {
|
||||
text = <sub key={index}>{text}</sub>
|
||||
}
|
||||
if (node.format & IS_SUPERSCRIPT) {
|
||||
text = <sup key={index}>{text}</sup>
|
||||
}
|
||||
|
||||
return text
|
||||
}
|
||||
|
||||
// NOTE: Hacky fix for
|
||||
// https://github.com/facebook/lexical/blob/d10c4e6e55261b2fdd7d1845aed46151d0f06a8c/packages/lexical-list/src/LexicalListItemNode.ts#L133
|
||||
// which does not return checked: false (only true - i.e. there is no prop for false)
|
||||
const serializedChildrenFn = (node: NodeTypes): JSX.Element | null => {
|
||||
if (node.children == null) {
|
||||
return null
|
||||
} else {
|
||||
if (node?.type === 'list' && node?.listType === 'check') {
|
||||
for (const item of node.children) {
|
||||
if ('checked' in item) {
|
||||
if (!item?.checked) {
|
||||
item.checked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return serializeLexical({ nodes: node.children as NodeTypes[] })
|
||||
}
|
||||
}
|
||||
|
||||
const serializedChildren = 'children' in node ? serializedChildrenFn(node) : ''
|
||||
|
||||
if (node.type === 'block') {
|
||||
const block = node.fields
|
||||
|
||||
const blockType = block?.blockType
|
||||
|
||||
if (!block || !blockType) {
|
||||
return null
|
||||
}
|
||||
|
||||
switch (blockType) {
|
||||
case 'cta':
|
||||
return <CallToActionBlock key={index} {...block} />
|
||||
case 'mediaBlock':
|
||||
return (
|
||||
<MediaBlock
|
||||
className="col-start-1 col-span-3"
|
||||
imgClassName="m-0"
|
||||
key={index}
|
||||
{...block}
|
||||
captionClassName="mx-auto max-w-[48rem]"
|
||||
enableGutter={false}
|
||||
disableInnerContainer={true}
|
||||
/>
|
||||
)
|
||||
case 'banner':
|
||||
return <BannerBlock className="col-start-2 mb-4" key={index} {...block} />
|
||||
case 'code':
|
||||
return <CodeBlock className="col-start-2" key={index} {...block} />
|
||||
default:
|
||||
return null
|
||||
}
|
||||
} else {
|
||||
switch (node.type) {
|
||||
case 'linebreak': {
|
||||
return <br className="col-start-2" key={index} />
|
||||
}
|
||||
case 'paragraph': {
|
||||
return (
|
||||
<p className="col-start-2" key={index}>
|
||||
{serializedChildren}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
case 'heading': {
|
||||
const Tag = node?.tag
|
||||
return (
|
||||
<Tag className="col-start-2" key={index}>
|
||||
{serializedChildren}
|
||||
</Tag>
|
||||
)
|
||||
}
|
||||
case 'list': {
|
||||
const Tag = node?.tag
|
||||
return (
|
||||
<Tag className="list col-start-2" key={index}>
|
||||
{serializedChildren}
|
||||
</Tag>
|
||||
)
|
||||
}
|
||||
case 'listitem': {
|
||||
if (node?.checked != null) {
|
||||
return (
|
||||
<li
|
||||
aria-checked={node.checked ? 'true' : 'false'}
|
||||
className={` ${node.checked ? '' : ''}`}
|
||||
key={index}
|
||||
role="checkbox"
|
||||
tabIndex={-1}
|
||||
value={node?.value}
|
||||
>
|
||||
{serializedChildren}
|
||||
</li>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<li key={index} value={node?.value}>
|
||||
{serializedChildren}
|
||||
</li>
|
||||
)
|
||||
}
|
||||
}
|
||||
case 'quote': {
|
||||
return (
|
||||
<blockquote className="col-start-2" key={index}>
|
||||
{serializedChildren}
|
||||
</blockquote>
|
||||
)
|
||||
}
|
||||
case 'link': {
|
||||
const fields = node.fields
|
||||
|
||||
return (
|
||||
<CMSLink
|
||||
key={index}
|
||||
newTab={Boolean(fields?.newTab)}
|
||||
// @ts-expect-error - this should disappear when upgrading to the latest version of Payload
|
||||
reference={fields.doc}
|
||||
type={fields.linkType === 'internal' ? 'reference' : 'custom'}
|
||||
url={fields.url}
|
||||
>
|
||||
{serializedChildren}
|
||||
</CMSLink>
|
||||
)
|
||||
}
|
||||
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}
|
||||
})}
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
@@ -10,7 +10,6 @@ export const contact: Partial<Page> = {
|
||||
{
|
||||
blockType: 'formBlock',
|
||||
enableIntro: true,
|
||||
// @ts-expect-error this should dissapear when upgrading to the latest version of Payload
|
||||
form: '{{CONTACT_FORM_ID}}',
|
||||
introContent: {
|
||||
root: {
|
||||
|
||||
@@ -84,7 +84,7 @@ export const homeStatic: Page = {
|
||||
title: 'Payload Website Template',
|
||||
},
|
||||
title: 'Home',
|
||||
id: 0,
|
||||
id: '',
|
||||
layout: [],
|
||||
updatedAt: '',
|
||||
createdAt: '',
|
||||
|
||||
@@ -23,7 +23,6 @@ export const home: RequiredDataFromCollectionSlug<'pages'> = {
|
||||
},
|
||||
},
|
||||
],
|
||||
// @ts-expect-error - this should disappear when upgrading to the latest version of Payload
|
||||
media: '{{IMAGE_1}}',
|
||||
richText: {
|
||||
root: {
|
||||
@@ -502,7 +501,6 @@ export const home: RequiredDataFromCollectionSlug<'pages'> = {
|
||||
{
|
||||
blockName: 'Media Block',
|
||||
blockType: 'mediaBlock',
|
||||
// @ts-expect-error - this should disappear when upgrading to the latest version of Payload
|
||||
media: '{{IMAGE_2}}',
|
||||
},
|
||||
{
|
||||
@@ -659,7 +657,6 @@ export const home: RequiredDataFromCollectionSlug<'pages'> = {
|
||||
],
|
||||
meta: {
|
||||
description: 'An open-source website built with Payload and Next.js.',
|
||||
// @ts-expect-error - this should disappear when upgrading to the latest version of Payload
|
||||
image: '{{IMAGE_1}}',
|
||||
title: 'Payload Website Template',
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Field } from 'payload'
|
||||
import type { Field, GroupField } from 'payload'
|
||||
|
||||
import deepMerge from '@/utilities/deepMerge'
|
||||
|
||||
@@ -18,11 +18,11 @@ export const appearanceOptions: Record<LinkAppearances, { label: string; value:
|
||||
type LinkType = (options?: {
|
||||
appearances?: LinkAppearances[] | false
|
||||
disableLabel?: boolean
|
||||
overrides?: Record<string, unknown>
|
||||
overrides?: Partial<GroupField>
|
||||
}) => Field
|
||||
|
||||
export const link: LinkType = ({ appearances, disableLabel = false, overrides = {} } = {}) => {
|
||||
const linkResult: Field = {
|
||||
const linkResult: GroupField = {
|
||||
name: 'link',
|
||||
type: 'group',
|
||||
admin: {
|
||||
|
||||
@@ -53,7 +53,7 @@ export const SlugComponent: React.FC<SlugComponentProps> = ({
|
||||
}, [targetFieldValue, checkboxValue, setValue, value])
|
||||
|
||||
const handleLock = useCallback(
|
||||
(e) => {
|
||||
(e: React.MouseEvent<Element>) => {
|
||||
e.preventDefault()
|
||||
|
||||
dispatchFields({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "4744a0d7-07ca-4325-9494-f4ec014a6818",
|
||||
"id": "b2ff7f1c-8dd6-4188-adb6-abfc6304df24",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-vercel-postgres'
|
||||
|
||||
export async function up({ db }: MigrateUpArgs): Promise<void> {
|
||||
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||
await db.execute(sql`
|
||||
CREATE TYPE "public"."enum_pages_hero_links_link_type" AS ENUM('reference', 'custom');
|
||||
CREATE TYPE "public"."enum_pages_hero_links_link_appearance" AS ENUM('default', 'outline');
|
||||
@@ -1558,7 +1558,7 @@ export async function up({ db }: MigrateUpArgs): Promise<void> {
|
||||
CREATE INDEX IF NOT EXISTS "footer_rels_posts_id_idx" ON "footer_rels" USING btree ("posts_id");`)
|
||||
}
|
||||
|
||||
export async function down({ db }: MigrateDownArgs): Promise<void> {
|
||||
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||
await db.execute(sql`
|
||||
DROP TABLE "pages_hero_links" CASCADE;
|
||||
DROP TABLE "pages_blocks_cta_links" CASCADE;
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as migration_20250114_010510_initial from './20250114_010510_initial'
|
||||
import * as migration_20250129_033102_initial from './20250129_033102_initial'
|
||||
|
||||
export const migrations = [
|
||||
{
|
||||
up: migration_20250114_010510_initial.up,
|
||||
down: migration_20250114_010510_initial.down,
|
||||
name: '20250114_010510_initial',
|
||||
up: migration_20250129_033102_initial.up,
|
||||
down: migration_20250129_033102_initial.down,
|
||||
name: '20250129_033102_initial',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -14,15 +14,11 @@ export const formatAuthors = (
|
||||
authors: NonNullable<NonNullable<Post['populatedAuthors']>[number]>[],
|
||||
) => {
|
||||
// Ensure we don't have any authors without a name
|
||||
const filteredAuthors = authors.filter((author) => Boolean(author.name))
|
||||
const authorNames = authors.map((author) => author.name).filter(Boolean)
|
||||
|
||||
if (filteredAuthors.length === 0) return ''
|
||||
if (filteredAuthors.length === 1) return filteredAuthors[0].name
|
||||
if (filteredAuthors.length === 2)
|
||||
return `${filteredAuthors[0].name} and ${filteredAuthors[1].name}`
|
||||
if (authorNames.length === 0) return ''
|
||||
if (authorNames.length === 1) return authorNames[0]
|
||||
if (authorNames.length === 2) return `${authorNames[0]} and ${authorNames[1]}`
|
||||
|
||||
return `${filteredAuthors
|
||||
.slice(0, -1)
|
||||
.map((author) => author?.name)
|
||||
.join(', ')} and ${filteredAuthors[authors.length - 1].name}`
|
||||
return `${authorNames.slice(0, -1).join(', ')} and ${authorNames[authorNames.length - 1]}`
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ const getImageURL = (image?: Media | Config['db']['defaultIDType'] | null) => {
|
||||
}
|
||||
|
||||
export const generateMeta = async (args: {
|
||||
doc: Partial<Page> | Partial<Post>
|
||||
doc: Partial<Page> | Partial<Post> | null
|
||||
}): Promise<Metadata> => {
|
||||
const { doc } = args || {}
|
||||
const { doc } = args
|
||||
|
||||
const ogImage = getImageURL(doc?.meta?.image)
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import tailwindcssAnimate from 'tailwindcss-animate'
|
||||
import typography from '@tailwindcss/typography'
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
const config = {
|
||||
content: [
|
||||
'./pages/**/*.{ts,tsx}',
|
||||
'./components/**/*.{ts,tsx}',
|
||||
@@ -7,7 +10,7 @@ export default {
|
||||
'./src/**/*.{ts,tsx}',
|
||||
],
|
||||
darkMode: ['selector', '[data-theme="dark"]'],
|
||||
plugins: [require('tailwindcss-animate'), require('@tailwindcss/typography')],
|
||||
plugins: [tailwindcssAnimate, typography],
|
||||
prefix: '',
|
||||
safelist: [
|
||||
'lg:col-span-4',
|
||||
@@ -104,7 +107,7 @@ export default {
|
||||
to: { height: '0' },
|
||||
},
|
||||
},
|
||||
typography: ({ theme }) => ({
|
||||
typography: () => ({
|
||||
DEFAULT: {
|
||||
css: [
|
||||
{
|
||||
@@ -146,3 +149,5 @@ export default {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Strictness */
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noImplicitOverride": true,
|
||||
|
||||
"baseUrl": ".",
|
||||
"esModuleInterop": true,
|
||||
"target": "ES2022",
|
||||
@@ -10,7 +15,6 @@
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": false,
|
||||
"strictNullChecks": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
|
||||
Reference in New Issue
Block a user