remove: unnecessary code
This commit is contained in:
@@ -1,26 +0,0 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { anyone } from '../access/anyone'
|
||||
import { authenticated } from '../access/authenticated'
|
||||
import { slugField } from '@/fields/slug'
|
||||
|
||||
export const Categories: CollectionConfig = {
|
||||
slug: 'categories',
|
||||
access: {
|
||||
create: authenticated,
|
||||
delete: authenticated,
|
||||
read: anyone,
|
||||
update: authenticated,
|
||||
},
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
...slugField(),
|
||||
],
|
||||
}
|
||||
@@ -8,8 +8,6 @@ import {
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import { anyone } from '../access/anyone'
|
||||
import { authenticated } from '../access/authenticated'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
@@ -17,10 +15,7 @@ const dirname = path.dirname(filename)
|
||||
export const Media: CollectionConfig = {
|
||||
slug: 'media',
|
||||
access: {
|
||||
create: authenticated,
|
||||
delete: authenticated,
|
||||
read: anyone,
|
||||
update: authenticated,
|
||||
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
import type { CollectionAfterChangeHook, CollectionAfterDeleteHook } from 'payload'
|
||||
|
||||
import { revalidatePath, revalidateTag } from 'next/cache'
|
||||
|
||||
import type { Page } from '../../../payload-types'
|
||||
|
||||
export const revalidatePage: CollectionAfterChangeHook<Page> = ({
|
||||
doc,
|
||||
previousDoc,
|
||||
req: { payload, context },
|
||||
}) => {
|
||||
if (!context.disableRevalidate) {
|
||||
if (doc._status === 'published') {
|
||||
const path = doc.slug === 'home' ? '/' : `/${doc.slug}`
|
||||
|
||||
payload.logger.info(`Revalidating page at path: ${path}`)
|
||||
|
||||
revalidatePath(path)
|
||||
revalidateTag('pages-sitemap')
|
||||
}
|
||||
|
||||
// If the page was previously published, we need to revalidate the old path
|
||||
if (previousDoc?._status === 'published' && doc._status !== 'published') {
|
||||
const oldPath = previousDoc.slug === 'home' ? '/' : `/${previousDoc.slug}`
|
||||
|
||||
payload.logger.info(`Revalidating old page at path: ${oldPath}`)
|
||||
|
||||
revalidatePath(oldPath)
|
||||
revalidateTag('pages-sitemap')
|
||||
}
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
export const revalidateDelete: CollectionAfterDeleteHook<Page> = ({ doc, req: { context } }) => {
|
||||
if (!context.disableRevalidate) {
|
||||
const path = doc?.slug === 'home' ? '/' : `/${doc?.slug}`
|
||||
revalidatePath(path)
|
||||
revalidateTag('pages-sitemap')
|
||||
}
|
||||
|
||||
return doc
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { authenticated } from '../../access/authenticated'
|
||||
import { authenticatedOrPublished } from '../../access/authenticatedOrPublished'
|
||||
import { Archive } from '../../blocks/ArchiveBlock/config'
|
||||
import { CallToAction } from '../../blocks/CallToAction/config'
|
||||
import { Content } from '../../blocks/Content/config'
|
||||
import { FormBlock } from '../../blocks/Form/config'
|
||||
import { MediaBlock } from '../../blocks/MediaBlock/config'
|
||||
import { hero } from '@/heros/config'
|
||||
import { slugField } from '@/fields/slug'
|
||||
import { populatePublishedAt } from '../../hooks/populatePublishedAt'
|
||||
import { generatePreviewPath } from '../../utilities/generatePreviewPath'
|
||||
import { revalidateDelete, revalidatePage } from './hooks/revalidatePage'
|
||||
|
||||
import {
|
||||
MetaDescriptionField,
|
||||
MetaImageField,
|
||||
MetaTitleField,
|
||||
OverviewField,
|
||||
PreviewField,
|
||||
} from '@payloadcms/plugin-seo/fields'
|
||||
|
||||
export const Pages: CollectionConfig<'pages'> = {
|
||||
slug: 'pages',
|
||||
access: {
|
||||
create: authenticated,
|
||||
delete: authenticated,
|
||||
read: authenticatedOrPublished,
|
||||
update: authenticated,
|
||||
},
|
||||
// This config controls what's populated by default when a page is referenced
|
||||
// https://payloadcms.com/docs/queries/select#defaultpopulate-collection-config-property
|
||||
// Type safe if the collection slug generic is passed to `CollectionConfig` - `CollectionConfig<'pages'>
|
||||
defaultPopulate: {
|
||||
title: true,
|
||||
slug: true,
|
||||
},
|
||||
admin: {
|
||||
defaultColumns: ['title', 'slug', 'updatedAt'],
|
||||
livePreview: {
|
||||
url: ({ data, req }) => {
|
||||
const path = generatePreviewPath({
|
||||
slug: typeof data?.slug === 'string' ? data.slug : '',
|
||||
collection: 'pages',
|
||||
req,
|
||||
})
|
||||
|
||||
return path
|
||||
},
|
||||
},
|
||||
preview: (data, { req }) =>
|
||||
generatePreviewPath({
|
||||
slug: typeof data?.slug === 'string' ? data.slug : '',
|
||||
collection: 'pages',
|
||||
req,
|
||||
}),
|
||||
useAsTitle: 'title',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
type: 'tabs',
|
||||
tabs: [
|
||||
{
|
||||
fields: [hero],
|
||||
label: 'Hero',
|
||||
},
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'layout',
|
||||
type: 'blocks',
|
||||
blocks: [CallToAction, Content, MediaBlock, Archive, FormBlock],
|
||||
required: true,
|
||||
admin: {
|
||||
initCollapsed: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
label: 'Content',
|
||||
},
|
||||
{
|
||||
name: 'meta',
|
||||
label: 'SEO',
|
||||
fields: [
|
||||
OverviewField({
|
||||
titlePath: 'meta.title',
|
||||
descriptionPath: 'meta.description',
|
||||
imagePath: 'meta.image',
|
||||
}),
|
||||
MetaTitleField({
|
||||
hasGenerateFn: true,
|
||||
}),
|
||||
MetaImageField({
|
||||
relationTo: 'media',
|
||||
}),
|
||||
|
||||
MetaDescriptionField({}),
|
||||
PreviewField({
|
||||
// if the `generateUrl` function is configured
|
||||
hasGenerateFn: true,
|
||||
|
||||
// field paths to match the target field for data
|
||||
titlePath: 'meta.title',
|
||||
descriptionPath: 'meta.description',
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'publishedAt',
|
||||
type: 'date',
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
},
|
||||
},
|
||||
...slugField(),
|
||||
],
|
||||
hooks: {
|
||||
afterChange: [revalidatePage],
|
||||
beforeChange: [populatePublishedAt],
|
||||
afterDelete: [revalidateDelete],
|
||||
},
|
||||
versions: {
|
||||
drafts: {
|
||||
autosave: {
|
||||
interval: 100, // We set this interval for optimal live preview
|
||||
},
|
||||
schedulePublish: true,
|
||||
},
|
||||
maxPerDoc: 50,
|
||||
},
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { anyone } from '../access/anyone'
|
||||
import { authenticated } from '../access/authenticated'
|
||||
import { slugField } from '@/fields/slug'
|
||||
|
||||
export const Papers: CollectionConfig = {
|
||||
slug: 'papers',
|
||||
@@ -11,10 +8,7 @@ export const Papers: CollectionConfig = {
|
||||
plural: 'Diplomarbeiten',
|
||||
},
|
||||
access: {
|
||||
create: authenticated,
|
||||
delete: authenticated,
|
||||
read: anyone,
|
||||
update: authenticated,
|
||||
|
||||
},
|
||||
admin: {
|
||||
useAsTitle: 'title',
|
||||
@@ -116,6 +110,7 @@ export const Papers: CollectionConfig = {
|
||||
|
||||
],
|
||||
validate: (authors) => {
|
||||
// @ts-ignore
|
||||
const leaders = authors.filter(author => author.position === 'leader')
|
||||
if (leaders.length > 1) {
|
||||
return 'Only one author can be the project leader.'
|
||||
@@ -123,6 +118,5 @@ export const Papers: CollectionConfig = {
|
||||
return true
|
||||
},
|
||||
},
|
||||
...slugField(),
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import type { CollectionAfterReadHook } from 'payload'
|
||||
import { User } from 'src/payload-types'
|
||||
|
||||
// The `user` collection has access control locked so that users are not publicly accessible
|
||||
// This means that we need to populate the authors manually here to protect user privacy
|
||||
// GraphQL will not return mutated user data that differs from the underlying schema
|
||||
// So we use an alternative `populatedAuthors` field to populate the user data, hidden from the admin UI
|
||||
export const populateAuthors: CollectionAfterReadHook = async ({ doc, req, req: { payload } }) => {
|
||||
if (doc?.authors && doc?.authors?.length > 0) {
|
||||
const authorDocs: User[] = []
|
||||
|
||||
for (const author of doc.authors) {
|
||||
try {
|
||||
const authorDoc = await payload.findByID({
|
||||
id: typeof author === 'object' ? author?.id : author,
|
||||
collection: 'users',
|
||||
depth: 0,
|
||||
})
|
||||
|
||||
if (authorDoc) {
|
||||
authorDocs.push(authorDoc)
|
||||
}
|
||||
|
||||
if (authorDocs.length > 0) {
|
||||
doc.populatedAuthors = authorDocs.map((authorDoc) => ({
|
||||
id: authorDoc.id,
|
||||
name: authorDoc.name,
|
||||
}))
|
||||
}
|
||||
} catch {
|
||||
// swallow error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return doc
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import type { CollectionAfterChangeHook, CollectionAfterDeleteHook } from 'payload'
|
||||
|
||||
import { revalidatePath, revalidateTag } from 'next/cache'
|
||||
|
||||
import type { Post } from '../../../payload-types'
|
||||
|
||||
export const revalidatePost: CollectionAfterChangeHook<Post> = ({
|
||||
doc,
|
||||
previousDoc,
|
||||
req: { payload, context },
|
||||
}) => {
|
||||
if (!context.disableRevalidate) {
|
||||
if (doc._status === 'published') {
|
||||
const path = `/posts/${doc.slug}`
|
||||
|
||||
payload.logger.info(`Revalidating post at path: ${path}`)
|
||||
|
||||
revalidatePath(path)
|
||||
revalidateTag('posts-sitemap')
|
||||
}
|
||||
|
||||
// If the post was previously published, we need to revalidate the old path
|
||||
if (previousDoc._status === 'published' && doc._status !== 'published') {
|
||||
const oldPath = `/posts/${previousDoc.slug}`
|
||||
|
||||
payload.logger.info(`Revalidating old post at path: ${oldPath}`)
|
||||
|
||||
revalidatePath(oldPath)
|
||||
revalidateTag('posts-sitemap')
|
||||
}
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
export const revalidateDelete: CollectionAfterDeleteHook<Post> = ({ doc, req: { context } }) => {
|
||||
if (!context.disableRevalidate) {
|
||||
const path = `/posts/${doc?.slug}`
|
||||
|
||||
revalidatePath(path)
|
||||
revalidateTag('posts-sitemap')
|
||||
}
|
||||
|
||||
return doc
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import {
|
||||
BlocksFeature,
|
||||
FixedToolbarFeature,
|
||||
HeadingFeature,
|
||||
HorizontalRuleFeature,
|
||||
InlineToolbarFeature,
|
||||
lexicalEditor,
|
||||
} from '@payloadcms/richtext-lexical'
|
||||
|
||||
import { authenticated } from '../../access/authenticated'
|
||||
import { authenticatedOrPublished } from '../../access/authenticatedOrPublished'
|
||||
import { Banner } from '../../blocks/Banner/config'
|
||||
import { Code } from '../../blocks/Code/config'
|
||||
import { MediaBlock } from '../../blocks/MediaBlock/config'
|
||||
import { generatePreviewPath } from '../../utilities/generatePreviewPath'
|
||||
import { populateAuthors } from './hooks/populateAuthors'
|
||||
import { revalidateDelete, revalidatePost } from './hooks/revalidatePost'
|
||||
|
||||
import {
|
||||
MetaDescriptionField,
|
||||
MetaImageField,
|
||||
MetaTitleField,
|
||||
OverviewField,
|
||||
PreviewField,
|
||||
} from '@payloadcms/plugin-seo/fields'
|
||||
import { slugField } from '@/fields/slug'
|
||||
|
||||
export const Posts: CollectionConfig<'posts'> = {
|
||||
slug: 'posts',
|
||||
access: {
|
||||
create: authenticated,
|
||||
delete: authenticated,
|
||||
read: authenticatedOrPublished,
|
||||
update: authenticated,
|
||||
},
|
||||
// This config controls what's populated by default when a post is referenced
|
||||
// https://payloadcms.com/docs/queries/select#defaultpopulate-collection-config-property
|
||||
// Type safe if the collection slug generic is passed to `CollectionConfig` - `CollectionConfig<'posts'>
|
||||
defaultPopulate: {
|
||||
title: true,
|
||||
slug: true,
|
||||
categories: true,
|
||||
meta: {
|
||||
image: true,
|
||||
description: true,
|
||||
},
|
||||
},
|
||||
admin: {
|
||||
defaultColumns: ['title', 'slug', 'updatedAt'],
|
||||
livePreview: {
|
||||
url: ({ data, req }) => {
|
||||
const path = generatePreviewPath({
|
||||
slug: typeof data?.slug === 'string' ? data.slug : '',
|
||||
collection: 'posts',
|
||||
req,
|
||||
})
|
||||
|
||||
return path
|
||||
},
|
||||
},
|
||||
preview: (data, { req }) =>
|
||||
generatePreviewPath({
|
||||
slug: typeof data?.slug === 'string' ? data.slug : '',
|
||||
collection: 'posts',
|
||||
req,
|
||||
}),
|
||||
useAsTitle: 'title',
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
type: 'tabs',
|
||||
tabs: [
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'heroImage',
|
||||
type: 'upload',
|
||||
relationTo: 'media',
|
||||
},
|
||||
{
|
||||
name: 'content',
|
||||
type: 'richText',
|
||||
editor: lexicalEditor({
|
||||
features: ({ rootFeatures }) => {
|
||||
return [
|
||||
...rootFeatures,
|
||||
HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }),
|
||||
BlocksFeature({ blocks: [Banner, Code, MediaBlock] }),
|
||||
FixedToolbarFeature(),
|
||||
InlineToolbarFeature(),
|
||||
HorizontalRuleFeature(),
|
||||
]
|
||||
},
|
||||
}),
|
||||
label: false,
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
label: 'Content',
|
||||
},
|
||||
{
|
||||
fields: [
|
||||
{
|
||||
name: 'relatedPosts',
|
||||
type: 'relationship',
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
},
|
||||
filterOptions: ({ id }) => {
|
||||
return {
|
||||
id: {
|
||||
not_in: [id],
|
||||
},
|
||||
}
|
||||
},
|
||||
hasMany: true,
|
||||
relationTo: 'posts',
|
||||
},
|
||||
{
|
||||
name: 'categories',
|
||||
type: 'relationship',
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
},
|
||||
hasMany: true,
|
||||
relationTo: 'categories',
|
||||
},
|
||||
],
|
||||
label: 'Meta',
|
||||
},
|
||||
{
|
||||
name: 'meta',
|
||||
label: 'SEO',
|
||||
fields: [
|
||||
OverviewField({
|
||||
titlePath: 'meta.title',
|
||||
descriptionPath: 'meta.description',
|
||||
imagePath: 'meta.image',
|
||||
}),
|
||||
MetaTitleField({
|
||||
hasGenerateFn: true,
|
||||
}),
|
||||
MetaImageField({
|
||||
relationTo: 'media',
|
||||
}),
|
||||
|
||||
MetaDescriptionField({}),
|
||||
PreviewField({
|
||||
// if the `generateUrl` function is configured
|
||||
hasGenerateFn: true,
|
||||
|
||||
// field paths to match the target field for data
|
||||
titlePath: 'meta.title',
|
||||
descriptionPath: 'meta.description',
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'publishedAt',
|
||||
type: 'date',
|
||||
admin: {
|
||||
date: {
|
||||
pickerAppearance: 'dayAndTime',
|
||||
},
|
||||
position: 'sidebar',
|
||||
},
|
||||
hooks: {
|
||||
beforeChange: [
|
||||
({ siblingData, value }) => {
|
||||
if (siblingData._status === 'published' && !value) {
|
||||
return new Date()
|
||||
}
|
||||
return value
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'authors',
|
||||
type: 'relationship',
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
},
|
||||
hasMany: true,
|
||||
relationTo: 'users',
|
||||
},
|
||||
// This field is only used to populate the user data via the `populateAuthors` hook
|
||||
// This is because the `user` collection has access control locked to protect user privacy
|
||||
// GraphQL will also not return mutated user data that differs from the underlying schema
|
||||
{
|
||||
name: 'populatedAuthors',
|
||||
type: 'array',
|
||||
access: {
|
||||
update: () => false,
|
||||
},
|
||||
admin: {
|
||||
disabled: true,
|
||||
readOnly: true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
...slugField(),
|
||||
],
|
||||
hooks: {
|
||||
afterChange: [revalidatePost],
|
||||
afterRead: [populateAuthors],
|
||||
afterDelete: [revalidateDelete],
|
||||
},
|
||||
versions: {
|
||||
drafts: {
|
||||
autosave: {
|
||||
interval: 100, // We set this interval for optimal live preview
|
||||
},
|
||||
schedulePublish: true,
|
||||
},
|
||||
maxPerDoc: 50,
|
||||
},
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { anyone } from '../access/anyone'
|
||||
import { authenticated } from '../access/authenticated'
|
||||
|
||||
export const Technologies: CollectionConfig = {
|
||||
slug: 'technologies',
|
||||
@@ -13,10 +11,7 @@ export const Technologies: CollectionConfig = {
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
access: {
|
||||
create: authenticated,
|
||||
delete: authenticated,
|
||||
read: anyone,
|
||||
update: authenticated,
|
||||
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
|
||||
12
src/collections/Users.ts
Normal file
12
src/collections/Users.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
export const Users: CollectionConfig = {
|
||||
slug: 'users',
|
||||
admin: {
|
||||
useAsTitle: 'email',
|
||||
},
|
||||
fields: [
|
||||
// Email added by default
|
||||
// Add more fields as needed
|
||||
],
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
// users.ts
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
const Users: CollectionConfig = {
|
||||
slug: "users",
|
||||
fields: [],
|
||||
};
|
||||
Reference in New Issue
Block a user