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, }, }