wwwfiberdirekt/src/collections/Pages/index.ts

236 lines
8.2 KiB
TypeScript

import type { CollectionConfig } from 'payload'
import { authenticated } from '../../access/authenticated'
import { authenticatedOrPublished } from '../../access/authenticatedOrPublished'
import { populatePublishedAt } from '../../hooks/populatePublishedAt'
import { generatePreviewPath } from '../../utilities/generatePreviewPath'
import { revalidateDelete, revalidatePage } from './hooks/revalidatePage'
import { FDHeroBlock } from '../../blocks/FDHeroBlock/config'
import { FDCtaSideImageBlock } from '../../blocks/FDCtaSideImageBlock/config'
import { FDFeatureAnnouncementBlock } from '../../blocks/FDFeatureAnnouncementBlock/config'
import { FDServicesGridBlock } from '../../blocks/FDServicesGridBlock/config'
import { FDContactBlock } from '../../blocks/FDContactBlock/config'
import { FDFaqBlock } from '../../blocks/FDFaqBlock/config'
import { FDCardGridBlock } from '../../blocks/FDCardGridBlock/config'
import { FDPricingCardBlock } from '../../blocks/FDPricingCardBlock/config'
import { FDSpacerBlock } from '../../blocks/FDSpacerBlock/config'
import { FDIconBarBlock } from '../../blocks/FDIconBarBlock/config'
import { FDUspChecklistBlock } from '../../blocks/FDUspChecklistBlock/config'
import { FDWideCardBlock } from '../../blocks/FDWideCardBlock/config'
import { FDTechPropertiesBlock } from '../../blocks/FDTechPropertiesBlock/config'
import { FDUspTableBlock } from '../../blocks/FDUspTableBlock/config'
import { FDHeaderTextImageBlock } from '../../blocks/FDHeaderTextImageBlock/config'
import { FDContactFormBlock } from '../../blocks/FDContactFormBlock/config'
import { FDTagsBlock } from '../../blocks/FDTagsBlock/config'
import { FDTextBlock } from '../../blocks/FDTextBlock/config'
import { FDLocationsGridBlock } from '../../blocks/FDLocationsGridBlock/config'
import { FDAlternateHeroBlock } from '../../blocks/FDAlternateHeroBlock/config'
import { FDStatisticsBlock } from '../../blocks/FDStatisticsBlock/config'
import { FDPartnersLogosBlock } from '../../blocks/FDPartnersLogosBlock/config'
import { FDNewsletterBlock } from '../../blocks/FDNewsletterBlock/config'
import { FDServiceChooserBlock } from '../../blocks/FDServiceChooserBlock/config'
import { FDDataTableBlock } from '../../blocks/FDDataTableBlock/config'
import { FDVpsCalculatorBlock } from '../../blocks/FDVpsCalculatorBlock/config'
import { FDCodeEmbedBlock } from '../../blocks/FDCodeEmbedBlock/config'
import { FDVideoBlock } from '../../blocks/FDVideoBlock/config'
import { FDCtaBannerBlock } from '../../blocks/FDCtaBannerBlock/config'
import { FDTestimonialBlock } from '../../blocks/FDTestimonialBlock/config'
import { FDTeamBlock } from '../../blocks/FDTeamBlock/config'
import { FDServiceCalculatorBlock } from '../../blocks/FDServiceCalculatorBlock/config'
import { FDLinkCardsBlock } from '../../blocks/FDLinkCardsBlock/config'
import { FDSpecCardsBlock } from '../../blocks/FDSpecCardsBlock/config'
import { FDQuizBlock } from '../../blocks/FDQuizBlock/config'
import {
MetaDescriptionField,
MetaImageField,
MetaTitleField,
OverviewField,
PreviewField,
} from '@payloadcms/plugin-seo/fields'
// ── Slug generator — handles Swedish characters ────────────────────────────────
const generateSlugFromTitle = (value: string): string =>
value
.toLowerCase()
.trim()
.replace(/[åä]/g, 'a')
.replace(/ö/g, 'o')
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '')
export const Pages: CollectionConfig<'pages'> = {
slug: 'pages',
access: {
create: authenticated,
delete: authenticated,
read: authenticatedOrPublished,
update: authenticated,
},
defaultPopulate: {
title: true,
slug: true,
},
admin: {
defaultColumns: ['title', 'slug', 'updatedAt'],
livePreview: {
url: ({ data, req }) =>
generatePreviewPath({
slug: data?.slug,
collection: 'pages',
req,
}),
},
preview: (data, { req }) =>
generatePreviewPath({
slug: data?.slug as string,
collection: 'pages',
req,
}),
useAsTitle: 'title',
},
fields: [
{
name: 'title',
type: 'text',
required: true,
},
{
type: 'tabs',
tabs: [
{
fields: [
{
name: 'layout',
type: 'blocks',
blocks: [
FDHeroBlock,
FDCtaSideImageBlock,
FDFeatureAnnouncementBlock,
FDServicesGridBlock,
FDContactBlock,
FDFaqBlock,
FDCardGridBlock,
FDPricingCardBlock,
FDSpacerBlock,
FDIconBarBlock,
FDUspChecklistBlock,
FDWideCardBlock,
FDTechPropertiesBlock,
FDUspTableBlock,
FDHeaderTextImageBlock,
FDContactFormBlock,
FDLocationsGridBlock,
FDAlternateHeroBlock,
FDStatisticsBlock,
FDPartnersLogosBlock,
FDNewsletterBlock,
FDServiceChooserBlock,
FDDataTableBlock,
FDVpsCalculatorBlock,
FDServiceCalculatorBlock,
FDTagsBlock,
FDTextBlock,
FDCodeEmbedBlock,
FDVideoBlock,
FDCtaBannerBlock,
FDTestimonialBlock,
FDTeamBlock,
FDLinkCardsBlock,
FDSpecCardsBlock,
FDQuizBlock,
],
required: true,
admin: {
initCollapsed: true,
},
},
],
label: 'Innehåll',
},
{
name: 'meta',
label: 'SEO',
fields: [
OverviewField({
titlePath: 'meta.title',
descriptionPath: 'meta.description',
imagePath: 'meta.image',
}),
MetaTitleField({
hasGenerateFn: true,
}),
MetaImageField({
relationTo: 'media',
}),
MetaDescriptionField({}),
PreviewField({
hasGenerateFn: true,
titlePath: 'meta.title',
descriptionPath: 'meta.description',
}),
],
},
],
},
{
name: 'publishedAt',
type: 'date',
admin: {
position: 'sidebar',
},
},
// ── Slug ─────────────────────────────────────────────────────────────────
{
name: 'slug',
type: 'text',
required: true,
index: true,
admin: {
position: 'sidebar',
description:
'Sidans URL-slug, t.ex. "om-oss" → fiberdirekt.se/om-oss. Kan alltid redigeras manuellt. Bocka i "Generera slug" nedan för att skriva om automatiskt från titeln.',
},
hooks: {
beforeChange: [
({ data, siblingData, value }) => {
// Only auto-generate if the checkbox is explicitly checked
if (siblingData?.generateSlug) {
return generateSlugFromTitle(data?.title || siblingData?.title || '')
}
// Otherwise keep whatever value the editor typed (or the existing value)
return value
},
],
},
},
// ── Auto-generate toggle ──────────────────────────────────────────────────
{
name: 'generateSlug',
type: 'checkbox',
label: 'Generera slug automatiskt från titeln',
defaultValue: true,
admin: {
position: 'sidebar',
description:
'När ikryssad skrivs slugen om från titeln vid varje sparning. Avbocka för att låsa slugen och redigera den manuellt.',
},
},
],
hooks: {
afterChange: [revalidatePage],
beforeChange: [populatePublishedAt],
afterDelete: [revalidateDelete],
},
versions: {
drafts: {
autosave: {
interval: 100,
},
schedulePublish: true,
},
maxPerDoc: 50,
},
}