- 11 Page Builder blocks: HeroBlock, TextBlock, FeaturesBlock, LocationCardBlock, PricingBlock, GalleryBlock, FormBlock (with label relation for lead tracking), CTABlock, CountdownBlock, BlogPreviewBlock, MapBlock - Collections: Labels, Pages, LandingPages, Blog, Events, Leads (UTM + googleClientId + label relation), Orders, Tickets - Globals: SiteSettings (GTM/GA4/Binotel/Umami), TicketsConfig, Navigation - Added "type": "module" to package.json for Payload CLI ESM compatibility - payload-types.ts generated (1874 lines) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
161 lines
4.1 KiB
TypeScript
161 lines
4.1 KiB
TypeScript
import type { CollectionConfig } from 'payload'
|
||
import { isAdmin, isEditor, isAdminOrPublished } from '../access'
|
||
|
||
export const Blog: CollectionConfig = {
|
||
slug: 'blog',
|
||
labels: {
|
||
singular: 'Пост блогу',
|
||
plural: 'Пости блогу',
|
||
},
|
||
admin: {
|
||
group: 'Контент',
|
||
useAsTitle: 'title',
|
||
defaultColumns: ['title', 'category', 'publishedAt', '_status'],
|
||
preview: (doc) => {
|
||
if (doc?.slug) {
|
||
return `${process.env.NEXT_PUBLIC_SITE_URL}/blog/${doc.slug}`
|
||
}
|
||
return null
|
||
},
|
||
},
|
||
access: {
|
||
read: isAdminOrPublished,
|
||
create: isEditor,
|
||
update: isEditor,
|
||
delete: isAdmin,
|
||
},
|
||
versions: {
|
||
drafts: {
|
||
autosave: {
|
||
interval: 375,
|
||
},
|
||
},
|
||
},
|
||
fields: [
|
||
{
|
||
name: 'title',
|
||
type: 'text',
|
||
label: 'Заголовок',
|
||
required: true,
|
||
admin: {
|
||
placeholder: 'Як ми готуємось до літнього сезону',
|
||
},
|
||
},
|
||
{
|
||
name: 'slug',
|
||
type: 'text',
|
||
label: 'URL (slug)',
|
||
required: true,
|
||
unique: true,
|
||
index: true,
|
||
admin: {
|
||
placeholder: 'litniy-sezon-2026',
|
||
description: 'Автоматично генерується з заголовку. Доступний за: /blog/{slug}',
|
||
},
|
||
},
|
||
{
|
||
name: 'excerpt',
|
||
type: 'textarea',
|
||
label: 'Короткий опис (анонс)',
|
||
admin: {
|
||
rows: 3,
|
||
placeholder: 'Розповідаємо про нові атракціони та заходи цього сезону',
|
||
description: 'Відображається в картці на списку блогу та в META description',
|
||
},
|
||
},
|
||
{
|
||
name: 'coverImage',
|
||
type: 'upload',
|
||
relationTo: 'media',
|
||
label: 'Обкладинка',
|
||
admin: {
|
||
description: 'Рекомендований розмір: 1200×630 px',
|
||
},
|
||
},
|
||
{
|
||
name: 'category',
|
||
type: 'select',
|
||
label: 'Категорія',
|
||
options: [
|
||
{ label: 'Новини', value: 'news' },
|
||
{ label: 'Заходи', value: 'events' },
|
||
{ label: 'Корисне', value: 'tips' },
|
||
{ label: 'За лаштунками', value: 'behind-scenes' },
|
||
],
|
||
admin: {
|
||
placeholder: 'Оберіть категорію',
|
||
},
|
||
},
|
||
{
|
||
name: 'tags',
|
||
type: 'array',
|
||
label: 'Теги',
|
||
maxRows: 10,
|
||
fields: [
|
||
{
|
||
name: 'tag',
|
||
type: 'text',
|
||
label: 'Тег',
|
||
required: true,
|
||
admin: {
|
||
placeholder: 'динопарк',
|
||
},
|
||
},
|
||
],
|
||
},
|
||
{
|
||
name: 'publishedAt',
|
||
type: 'date',
|
||
label: 'Дата публікації',
|
||
admin: {
|
||
date: {
|
||
pickerAppearance: 'dayOnly',
|
||
displayFormat: 'd MMM yyyy',
|
||
},
|
||
description: 'Відображається на сторінці. Якщо не вказано — використовується дата створення.',
|
||
},
|
||
},
|
||
{
|
||
name: 'body',
|
||
type: 'richText',
|
||
label: 'Контент',
|
||
required: true,
|
||
admin: {
|
||
description: 'Повний текст статті',
|
||
},
|
||
},
|
||
{
|
||
name: 'seo',
|
||
type: 'group',
|
||
label: 'SEO',
|
||
fields: [
|
||
{
|
||
name: 'metaTitle',
|
||
type: 'text',
|
||
label: 'Meta Title',
|
||
admin: {
|
||
description: 'Якщо порожнє — використовується заголовок поста',
|
||
},
|
||
},
|
||
{
|
||
name: 'metaDescription',
|
||
type: 'textarea',
|
||
label: 'Meta Description',
|
||
admin: {
|
||
rows: 3,
|
||
description: 'Якщо порожнє — використовується анонс поста',
|
||
},
|
||
},
|
||
{
|
||
name: 'ogImage',
|
||
type: 'upload',
|
||
relationTo: 'media',
|
||
label: 'OG Image',
|
||
admin: {
|
||
description: 'Якщо порожнє — використовується обкладинка',
|
||
},
|
||
},
|
||
],
|
||
},
|
||
],
|
||
}
|