Shumiland/payload.config.ts
Vadym Samoilenko ef629dbdbe
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
feat(pages): add dinosaur park page + redesign birthday, group visits, thank-you
New pages:
- /lokatsii/dynozavry — DinosaurPage (static ISR): DinoHero, DinoWheel (interactive
  8-species arc selector, auto-rotate 4s), DinoGallery, DinoActivities, DinoWhyVisit,
  DinoTickets (ezy API dyno+combo categories)
- /kvytky/dyakuiemo — thank-you page with ticket-shaped card design

Redesigned pages:
- /dni-narodzhennia — new hero, "Що входить" 6-card section, WhyVisit accordion,
  pricing grid from BirthdayPackages CMS, form preserved
- /grupovi-vidviduvannia — new hero overlay, description band, amenity 2x2 grid,
  350 грн ticket card, bottom CTA section, form preserved

New CMS:
- DinosaurPage global (slug: dinosaur-page) with 7 array sub-tables
- migration 0006_dinosaur_page.sql — idempotent, creates all tables + dynozavry location
- seed/route.ts — seeds DinosaurPage global with 8 dino species defaults
- payload.config.ts — registers DinosaurPage in globals, seoPlugin, livePreview

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 13:28:52 +01:00

217 lines
6.4 KiB
TypeScript

import { buildConfig } from 'payload'
import { postgresAdapter } from '@payloadcms/db-postgres'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
import { seoPlugin } from '@payloadcms/plugin-seo'
import { redirectsPlugin } from '@payloadcms/plugin-redirects'
import { formBuilderPlugin } from '@payloadcms/plugin-form-builder'
import { resendAdapter } from '@payloadcms/email-resend'
import sharp from 'sharp'
import path from 'path'
import { fileURLToPath } from 'url'
import { Users } from './src/collections/Users'
import { Media } from './src/collections/Media'
import { Pages } from './src/collections/Pages'
import { BlogPosts } from './src/collections/BlogPosts'
import { Categories } from './src/collections/Categories'
import { Tags } from './src/collections/Tags'
import { Tariffs } from './src/collections/Tariffs'
import { Leads } from './src/collections/Leads'
import { Orders } from './src/collections/Orders'
import { Locations } from './src/collections/Locations'
import { Reviews } from './src/collections/Reviews'
import { BirthdayPackages } from './src/collections/BirthdayPackages'
import { HomePage } from './src/globals/HomePage'
import { CheckoutPage } from './src/globals/CheckoutPage'
import { ThankYouPage } from './src/globals/ThankYouPage'
import { Header } from './src/globals/Header'
import { Footer } from './src/globals/Footer'
import { SiteSettings } from './src/globals/SiteSettings'
import { DyvoLisPage } from './src/globals/DyvoLisPage'
import { GroupVisitsPage } from './src/globals/GroupVisitsPage'
import { BirthdayPage } from './src/globals/BirthdayPage'
import { TicketsPage } from './src/globals/TicketsPage'
import { LocationsPage } from './src/globals/LocationsPage'
import { BlogIndexPage } from './src/globals/BlogIndexPage'
import { DinosaurPage } from './src/globals/DinosaurPage'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
const siteURL = process.env['NEXT_PUBLIC_SITE_URL'] ?? 'http://localhost:3000'
export default buildConfig({
secret: process.env['PAYLOAD_SECRET']!,
serverURL: siteURL,
email: resendAdapter({
defaultFromAddress: process.env['RESEND_FROM'] ?? 'noreply@shumiland.com.ua',
defaultFromName: 'Шуміленд',
apiKey: process.env['RESEND_API_KEY'] ?? '',
}),
db: postgresAdapter({
pool: {
connectionString: process.env['DATABASE_URL']!,
},
migrationDir: path.resolve(dirname, 'migrations'),
}),
editor: lexicalEditor(),
sharp,
collections: [
Users,
Media,
Pages,
BlogPosts,
Categories,
Tags,
Tariffs,
Leads,
Orders,
Locations,
Reviews,
BirthdayPackages,
],
globals: [
HomePage,
CheckoutPage,
ThankYouPage,
Header,
Footer,
SiteSettings,
DyvoLisPage,
GroupVisitsPage,
BirthdayPage,
TicketsPage,
LocationsPage,
BlogIndexPage,
DinosaurPage,
],
plugins: [
redirectsPlugin({
collections: ['pages'],
redirectTypes: ['301', '302'],
overrides: {
admin: { group: 'Контент сайту' },
},
}),
seoPlugin({
collections: ['pages', 'blog-posts', 'locations'],
globals: [
'home-page',
'dyvolis-page',
'group-visits-page',
'birthday-page',
'tickets-page',
'checkout-page',
'thank-you-page',
'locations-page',
'blog-index-page',
'dinosaur-page',
],
uploadsCollection: 'media',
tabbedUI: true,
generateURL: ({ doc, collectionSlug, globalSlug }) => {
const base = 'https://shumiland.com.ua'
const d = doc as { slug?: string }
if (collectionSlug === 'blog-posts') return `${base}/blog/${d.slug ?? ''}`
if (collectionSlug === 'locations') return `${base}/lokatsii/${d.slug ?? ''}`
if (collectionSlug === 'pages') return `${base}/${d.slug ?? ''}`
const globalURLs: Record<string, string> = {
'home-page': base,
'dyvolis-page': `${base}/lokatsii/dyvolis`,
'group-visits-page': `${base}/grupovi-vidviduvannia`,
'birthday-page': `${base}/dni-narodzhennia`,
'tickets-page': `${base}/kvytky`,
'checkout-page': `${base}/kvytky/checkout`,
'thank-you-page': `${base}/kvytky/dyakuiemo`,
'locations-page': `${base}/lokatsii`,
'blog-index-page': `${base}/blog`,
'dinosaur-page': `${base}/lokatsii/dynozavry`,
}
return globalURLs[globalSlug ?? ''] ?? base
},
generateTitle: ({ doc }) => {
const d = doc as { title?: string; name?: string; heroTitle?: string }
const title = d.title ?? d.name ?? d.heroTitle ?? ''
return title ? `${title} — Шуміленд` : 'Шуміленд'
},
generateDescription: ({ doc }) => {
const d = doc as { excerpt?: string; shortDesc?: string; heroSubtitle?: string }
return d.excerpt ?? d.shortDesc ?? d.heroSubtitle ?? ''
},
}),
formBuilderPlugin({
fields: {
text: true,
textarea: true,
select: true,
radio: false,
email: true,
number: true,
message: true,
date: true,
checkbox: true,
state: false,
country: false,
payment: false,
},
defaultToEmail: process.env['MANAGER_EMAILS']?.split(',')[0] ?? '',
redirectRelationships: ['pages'],
formOverrides: {
admin: { group: 'Форми' },
access: { read: () => true },
},
formSubmissionOverrides: {
admin: { group: 'Форми' },
},
}),
],
admin: {
user: 'users',
meta: {
titleSuffix: '— Шуміленд CMS',
},
timezones: {
supportedTimezones: [{ label: 'Київ (UTC+3)', value: 'Europe/Kyiv' }],
defaultTimezone: 'Europe/Kyiv',
},
dateFormat: 'dd.MM.yyyy HH:mm',
livePreview: {
url: siteURL,
collections: ['pages'],
globals: [
'home-page',
'checkout-page',
'thank-you-page',
'header',
'footer',
'dyvolis-page',
'group-visits-page',
'birthday-page',
'tickets-page',
'locations-page',
'blog-index-page',
'dinosaur-page',
],
},
},
i18n: {
fallbackLanguage: 'en',
},
cors: [siteURL],
typescript: {
outputFile: path.resolve(dirname, 'src/payload-types.ts'),
},
telemetry: false,
})